[Mesa-dev] [PATCH 5/5] mesa: Replace the hash table in string_to_uint_map with the new one.

Eric Anholt eric at anholt.net
Thu Oct 25 09:13:05 PDT 2012


This mapping is generally used for mapping the strings identifying
uniforms/attributes to integer locations in the GL API.  While one would hope
that applications just call these once per thing per shader at startup, new
app developers often end up calling this at runtime.  Having an implementation
that's faster at lookup (because there are often more than 16 uniforms) should
help those applications.
---
 src/glsl/Makefile.am                    |    2 +
 src/glsl/SConscript                     |    4 +-
 src/glsl/glcpp/Makefile.am              |    2 +
 src/mesa/Android.mk                     |    2 +
 src/mesa/main/hash_table.h              |    1 +
 src/mesa/program/string_to_uint_map.cpp |    2 +-
 src/mesa/program/string_to_uint_map.h   |   73 +++++++++++++------------------
 7 files changed, 41 insertions(+), 45 deletions(-)

diff --git a/src/glsl/Makefile.am b/src/glsl/Makefile.am
index d3eb742..3febf16 100644
--- a/src/glsl/Makefile.am
+++ b/src/glsl/Makefile.am
@@ -53,6 +53,7 @@ libglslcommon_la_LIBADD = glcpp/libglcpp.la
 # common sources for builtin_compiler and glsl_compiler
 GLSL2_SOURCES = \
 	$(top_srcdir)/src/mesa/program/chaining_hash_table.c \
+	$(top_srcdir)/src/mesa/program/hash_table.c \
 	$(top_srcdir)/src/mesa/program/symbol_table.c \
 	$(GLSL_COMPILER_CXX_FILES)
 
@@ -69,6 +70,7 @@ glsl_compiler_LDADD = libglsl.la
 
 glsl_test_SOURCES = \
 	$(top_srcdir)/src/mesa/program/chaining_hash_table.c \
+	$(top_srcdir)/src/mesa/program/hash_table.c \
 	$(top_srcdir)/src/mesa/program/symbol_table.c \
 	$(GLSL_SRCDIR)/standalone_scaffolding.cpp \
 	test.cpp \
diff --git a/src/glsl/SConscript b/src/glsl/SConscript
index b687788..43a3e06 100644
--- a/src/glsl/SConscript
+++ b/src/glsl/SConscript
@@ -58,12 +58,14 @@ if env['crosscompile'] and not env['embedded']:
 else:
     # Copy these files to avoid generation object files into src/mesa/program
     env.Prepend(CPPPATH = ['#src/mesa/program'])
-    env.Command('hash_table.c', '#src/mesa/program/chaining_hash_table.c', Copy('$TARGET', '$SOURCE'))
+    env.Command('hash_table.c', '#src/mesa/program/hash_table.c', Copy('$TARGET', '$SOURCE'))
+    env.Command('chaining_hash_table.c', '#src/mesa/program/chaining_hash_table.c', Copy('$TARGET', '$SOURCE'))
     env.Command('symbol_table.c', '#src/mesa/program/symbol_table.c', Copy('$TARGET', '$SOURCE'))
 
     compiler_objs = env.StaticObject(source_lists['GLSL_COMPILER_CXX_FILES'])
 
     mesa_objs = env.StaticObject([
+        'hash_table.c',
         'chaining_hash_table.c',
         'symbol_table.c',
     ])
diff --git a/src/glsl/glcpp/Makefile.am b/src/glsl/glcpp/Makefile.am
index 3709302..651b0d3 100644
--- a/src/glsl/glcpp/Makefile.am
+++ b/src/glsl/glcpp/Makefile.am
@@ -26,6 +26,7 @@ AM_CFLAGS = \
 	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/src/mapi \
 	-I$(top_srcdir)/src/mesa/ \
+	-I$(top_srcdir)/src/glsl/ \
 	$(LIBRARY_INCLUDES) \
 	$(DEFINES) \
 	$(LIBRARY_DEFINES) \
@@ -45,6 +46,7 @@ libglcpp_la_SOURCES = \
 glcpp_SOURCES = \
 	../ralloc.c \
 	$(top_srcdir)/src/mesa/program/chaining_hash_table.c \
+	$(top_srcdir)/src/mesa/program/hash_table.c \
 	glcpp.c
 
 glcpp_LDADD = libglcpp.la
diff --git a/src/mesa/Android.mk b/src/mesa/Android.mk
index 1cc317a..6b660b5 100644
--- a/src/mesa/Android.mk
+++ b/src/mesa/Android.mk
@@ -127,6 +127,7 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
 	program/chaining_hash_table.c \
+	program/hash_table.c \
 	program/symbol_table.c
 
 LOCAL_MODULE := libmesa_glsl_utils
@@ -142,6 +143,7 @@ include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES := \
 	program/chaining_hash_table.c \
+	program/hash_table.c \
 	program/symbol_table.c
 
 LOCAL_MODULE := libmesa_glsl_utils
diff --git a/src/mesa/main/hash_table.h b/src/mesa/main/hash_table.h
index 78e3aea..f866ecd 100644
--- a/src/mesa/main/hash_table.h
+++ b/src/mesa/main/hash_table.h
@@ -25,6 +25,7 @@
  *
  */
 
+#include <sys/types.h>
 #include <inttypes.h>
 #include <stdbool.h>
 
diff --git a/src/mesa/program/string_to_uint_map.cpp b/src/mesa/program/string_to_uint_map.cpp
index b6a08c2..f893450 100644
--- a/src/mesa/program/string_to_uint_map.cpp
+++ b/src/mesa/program/string_to_uint_map.cpp
@@ -26,7 +26,7 @@
 ` *
  * \author Ian Romanick <ian.d.romanick at intel.com>
  */
-#include "hash_table.h"
+#include "main/hash_table.h"
 #include "string_to_uint_map.h"
 
 extern "C" struct string_to_uint_map *
diff --git a/src/mesa/program/string_to_uint_map.h b/src/mesa/program/string_to_uint_map.h
index 8921a6e..49ecd50 100644
--- a/src/mesa/program/string_to_uint_map.h
+++ b/src/mesa/program/string_to_uint_map.h
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include "hash_table.h"
+#include "main/hash_table.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -40,25 +40,26 @@ string_to_uint_map_dtor(struct string_to_uint_map *);
 #endif
 
 #ifdef __cplusplus
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+
 /**
  * Map from a string (name) to an unsigned integer value
- *
- * \note
- * Because of the way this class interacts with the \c hash_table
- * implementation, values of \c UINT_MAX cannot be stored in the map.
  */
 struct string_to_uint_map {
 public:
    string_to_uint_map()
    {
-      this->ht = hash_table_ctor(0, hash_table_string_hash,
-				 hash_table_string_compare);
+      this->ht = _mesa_hash_table_create(NULL,
+                                         _mesa_key_string_equal);
    }
 
    ~string_to_uint_map()
    {
-      hash_table_call_foreach(this->ht, delete_key, NULL);
-      hash_table_dtor(this->ht);
+      clear();
+      _mesa_hash_table_destroy(this->ht, NULL);
    }
 
    /**
@@ -66,8 +67,11 @@ public:
     */
    void clear()
    {
-      hash_table_call_foreach(this->ht, delete_key, NULL);
-      hash_table_clear(this->ht);
+      struct hash_entry *entry;
+      hash_table_foreach(this->ht, entry) {
+         free((void *)entry->key);
+         _mesa_hash_table_remove(this->ht, entry);
+      }
    }
 
    /**
@@ -82,47 +86,30 @@ public:
     */
    bool get(unsigned &value, const char *key)
    {
-      const intptr_t v =
-	 (intptr_t) hash_table_find(this->ht, (const void *) key);
+      struct hash_entry *entry;
+      entry = _mesa_hash_table_search(this->ht, _mesa_hash_string(key), key);
+      if (!entry)
+         return false;
 
-      if (v == 0)
-	 return false;
-
-      value = (unsigned)(v - 1);
+      value = (uintptr_t)entry->data;
       return true;
    }
 
    void put(unsigned value, const char *key)
    {
-      /* The low-level hash table structure returns NULL if key is not in the
-       * hash table.  However, users of this map might want to store zero as a
-       * valid value in the table.  Bias the value by +1 so that a
-       * user-specified zero is stored as 1.  This enables ::get to tell the
-       * difference between a user-specified zero (returned as 1 by
-       * hash_table_find) and the key not in the table (returned as 0 by
-       * hash_table_find).
-       *
-       * The net effect is that we can't store UINT_MAX in the table.  This is
-       * because UINT_MAX+1 = 0.
-       */
-      assert(value != UINT_MAX);
-      char *dup_key = strdup(key);
-      bool result = hash_table_replace(this->ht,
-				       (void *) (intptr_t) (value + 1),
-				       dup_key);
-      if (result)
-	 free(dup_key);
+      uint32_t hash = _mesa_hash_string(key);
+      struct hash_entry *entry;
+
+      entry = _mesa_hash_table_search(this->ht, hash, key);
+      if (entry) {
+         entry->data = (void *)(uintptr_t)value;
+      } else {
+         key = strdup(key);
+         _mesa_hash_table_insert(this->ht, hash, key, (void *)(uintptr_t)value);
+      }
    }
 
 private:
-   static void delete_key(const void *key, void *data, void *closure)
-   {
-      (void) data;
-      (void) closure;
-
-      free((char *)key);
-   }
-
    struct hash_table *ht;
 };
 #endif /* __cplusplus */
-- 
1.7.10.4



More information about the mesa-dev mailing list