On 10/25/2012 10:13 AM, Eric Anholt wrote:
Mesa's chaining hash table for object names is slow, and this should be much
faster.  I namespaced the functions under _mesa_*, to avoid visibility
troubles that we may have had before with hash_table_* functions.  The
hash_table.c file unfortunately lives in program/ still to avoid confusion
with automake's dependency files that would otherwise require a make distclean
across this change.
---
  configure.ac                                       |    1 +
  src/mesa/main/hash_table.h                         |  105 +++++
  src/mesa/main/tests/Makefile.am                    |    2 +
  src/mesa/main/tests/hash_table/.gitignore          |   10 +
  src/mesa/main/tests/hash_table/Makefile.am         |   42 ++
  src/mesa/main/tests/hash_table/delete_and_lookup.c |   74 ++++
  src/mesa/main/tests/hash_table/delete_management.c |   88 ++++
  src/mesa/main/tests/hash_table/destroy_callback.c  |   66 +++
  src/mesa/main/tests/hash_table/insert_and_lookup.c |   57 +++
  src/mesa/main/tests/hash_table/insert_many.c       |   72 ++++
  src/mesa/main/tests/hash_table/null_destroy.c      |   37 ++
  src/mesa/main/tests/hash_table/random_entry.c      |   88 ++++
  src/mesa/main/tests/hash_table/remove_null.c       |   45 ++
  src/mesa/main/tests/hash_table/replacement.c       |   64 +++
  src/mesa/program/hash_table.c                      |  431 ++++++++++++++++++++
  src/mesa/sources.mak                               |    1 +

[I only skimmed the test programs]


diff --git a/src/mesa/program/hash_table.c b/src/mesa/program/hash_table.c
new file mode 100644
index 0000000..ba49437
--- /dev/null
+++ b/src/mesa/program/hash_table.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright © 2009,2012 Intel Corporation
+ * Copyright © 1988-2004 Keith Packard and Bart Massey.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the names of the authors
+ * or their institutions shall not be used in advertising or
+ * otherwise to promote the sale, use or other dealings in this
+ * Software without prior written authorization from the
+ * authors.
+ *
+ * Authors:
+ *    Eric Anholt<e...@anholt.net>
+ *    Keith Packard<kei...@keithp.com>
+ */
+
+/**
+ * Implements an open-addressing, linear-reprobing hash table.
+ *
+ * For more information, see:
+ *
+ * http://cgit.freedesktop.org/~anholt/hash_table/tree/README
+ */
+
+#include<stdlib.h>
+#include<string.h>
+
+#include "main/hash_table.h"
+#include "ralloc.h"
+
+#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
+
+uint32_t deleted_key_value;
+
+/**
+ * From Knuth -- a good choice for hash/rehash values is p, p-2 where
+ * p and p-2 are both prime.  These tables are sized to have an extra 10%
+ * free to avoid exponential performance degradation as the hash table fills
+ */
+static const struct {
+   uint32_t max_entries, size, rehash;
+} hash_sizes[] = {
+   { 2,                        5,              3         },
+   { 4,                        7,              5         },
+   { 8,                        13,             11        },
+   { 16,               19,             17        },
+   { 32,               43,             41        },
+   { 64,               73,             71        },
+   { 128,              151,            149       },
+   { 256,              283,            281       },
+   { 512,              571,            569       },
+   { 1024,             1153,           1151      },
+   { 2048,             2269,           2267      },
+   { 4096,             4519,           4517      },
+   { 8192,             9013,           9011      },
+   { 16384,            18043,          18041     },
+   { 32768,            36109,          36107     },
+   { 65536,            72091,          72089     },
+   { 131072,           144409,         144407    },
+   { 262144,           288361,         288359    },
+   { 524288,           576883,         576881    },
+   { 1048576,          1153459,        1153457   },
+   { 2097152,          2307163,        2307161   },
+   { 4194304,          4613893,        4613891   },
+   { 8388608,          9227641,        9227639   },
+   { 16777216,         18455029,       18455027  },
+   { 33554432,         36911011,       36911009  },
+   { 67108864,         73819861,       73819859  },
+   { 134217728,                147639589,      147639587 },
+   { 268435456,                295279081,      295279079 },
+   { 536870912,                590559793,      590559791 },
+   { 1073741824,       1181116273,     1181116271},
+   { 2147483648ul,     2362232233ul,   2362232231ul}
+};
+
+static int
+entry_is_free(struct hash_entry *entry)

I'd const-qualify the parameter here (and several below) but it's not a huge deal.


+{
+   return entry->key == NULL;
+}
+
+static int
+entry_is_deleted(struct hash_table *ht, struct hash_entry *entry)
+{
+   return entry->key == ht->deleted_key;
+}
+
+static int
+entry_is_present(struct hash_table *ht, struct hash_entry *entry)
+{
+   return entry->key != NULL&&  entry->key != ht->deleted_key;
+}
+

[...]


+struct hash_entry *
+_mesa_hash_table_random_entry(struct hash_table *ht,
+                              bool (*predicate)(struct hash_entry *entry))

Just curious, what is this function used for?  Just testing?

[...]


diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index d51adf5..13ba16a 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -249,6 +249,7 @@ STATETRACKER_FILES = \
  PROGRAM_FILES = \
        $(SRCDIR)program/arbprogparse.c \
        $(SRCDIR)program/chaining_hash_table.c \
+       $(SRCDIR)program/hash_table.c \
        $(SRCDIR)program/program.c \
        $(SRCDIR)program/program_parse_extra.c \
        $(SRCDIR)program/prog_cache.c \

Update the SConscript file too?
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to