glxhash.c revision 3d28a2690f3752990be50a25447747e237d7bee9
14a22ae8d446855d839cc199df8eb1b057045cb88Kristian Høgsberg/* glxhash.c -- Small hash table support for integer -> integer mapping
24a22ae8d446855d839cc199df8eb1b057045cb88Kristian Høgsberg * Taken from libdrm.
34a22ae8d446855d839cc199df8eb1b057045cb88Kristian Høgsberg *
44ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Created: Sun Apr 18 09:35:45 1999 by faith@precisioninsight.com
54ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
64ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
74ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * All Rights Reserved.
84ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
94ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Permission is hereby granted, free of charge, to any person obtaining a
104ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * copy of this software and associated documentation files (the "Software"),
114ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * to deal in the Software without restriction, including without limitation
124ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
134ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * and/or sell copies of the Software, and to permit persons to whom the
144ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Software is furnished to do so, subject to the following conditions:
154ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
164ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * The above copyright notice and this permission notice (including the next
174ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * paragraph) shall be included in all copies or substantial portions of the
184ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Software.
194ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
204ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
214ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
224ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
234ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
244ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
254ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
264ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * DEALINGS IN THE SOFTWARE.
274ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
284ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
294ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
304ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * DESCRIPTION
314ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
324ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * This file contains a straightforward implementation of a fixed-sized
334ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * hash table using self-organizing linked lists [Knuth73, pp. 398-399] for
344ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * collision resolution.  There are two potentially interesting things
354ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * about this implementation:
364ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
374ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * 1) The table is power-of-two sized.  Prime sized tables are more
384ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * traditional, but do not have a significant advantage over power-of-two
394ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * sized table, especially when double hashing is not used for collision
404ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * resolution.
414ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
424ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * 2) The hash computation uses a table of random integers [Hanson97,
434ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * pp. 39-41].
444ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
454ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * FUTURE ENHANCEMENTS
464ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
474ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * With a table size of 512, the current implementation is sufficient for a
484ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * few hundred keys.  Since this is well above the expected size of the
494ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * tables for which this implementation was designed, the implementation of
504ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * dynamic hash tables was postponed until the need arises.  A common (and
514ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * naive) approach to dynamic hash table implementation simply creates a
524ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * new hash table when necessary, rehashes all the data into the new table,
534ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * and destroys the old table.  The approach in [Larson88] is superior in
544ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * two ways: 1) only a portion of the table is expanded when needed,
554ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * distributing the expansion cost over several insertions, and 2) portions
564ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * of the table can be locked, enabling a scalable thread-safe
574ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * implementation.
584ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
594ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * REFERENCES
604ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
614ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * [Hanson97] David R. Hanson.  C Interfaces and Implementations:
624ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Techniques for Creating Reusable Software.  Reading, Massachusetts:
634ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Addison-Wesley, 1997.
644ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
654ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * [Knuth73] Donald E. Knuth. The Art of Computer Programming.  Volume 3:
664ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * Sorting and Searching.  Reading, Massachusetts: Addison-Wesley, 1973.
674ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
684ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * [Larson88] Per-Ake Larson. "Dynamic Hash Tables".  CACM 31(4), April
694ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg * 1988, pp. 446-457.
704ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg *
714ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg */
724ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
734ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#include "glxhash.h"
743d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg#include <X11/Xfuncproto.h>
754ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
764ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_MAIN 0
774ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
784ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#include <stdio.h>
794ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#include <stdlib.h>
804ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
814ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_MAGIC 0xdeadbeef
824ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_DEBUG 0
834ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_SIZE  512		/* Good for about 100 entries */
844ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg				/* If you change this value, you probably
854ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg                                   have to change the HashHash hashing
864ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg                                   function! */
874ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
884ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_ALLOC malloc
894ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_FREE  free
904ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_RANDOM_DECL
914ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_RANDOM_INIT(seed)  srandom(seed)
924ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_RANDOM             random()
934ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define HASH_RANDOM_DESTROY
944ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
954ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergtypedef struct __glxHashBucket {
964ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long     key;
974ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    void              *value;
984ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    struct __glxHashBucket *next;
994ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg} __glxHashBucket, *__glxHashBucketPtr;
1004ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1014ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergtypedef struct __glxHashTable *__glxHashTablePtr;
1024ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstruct __glxHashTable {
1034ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long    magic;
1044ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long    entries;
1054ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long    hits;	/* At top of linked list */
1064ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long    partials;	/* Not at top of linked list */
1074ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long    misses;	/* Not in table */
1084ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr    buckets[HASH_SIZE];
1094ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int              p0;
1104ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr    p1;
1114ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg};
1124ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1134ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic unsigned long HashHash(unsigned long key)
1144ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
1154ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long        hash = 0;
1164ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long        tmp  = key;
1174ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    static int           init = 0;
1184ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    static unsigned long scatter[256];
1194ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int                  i;
1204ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1214ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (!init) {
1224ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	HASH_RANDOM_DECL;
1234ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	HASH_RANDOM_INIT(37);
1244ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	for (i = 0; i < 256; i++) scatter[i] = HASH_RANDOM;
1254ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	HASH_RANDOM_DESTROY;
1264ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	++init;
1274ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
1284ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1294ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    while (tmp) {
1304ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	hash = (hash << 1) + scatter[tmp & 0xff];
1314ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	tmp >>= 8;
1324ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
1334ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1344ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    hash %= HASH_SIZE;
1354ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#if HASH_DEBUG
1364ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf( "Hash(%d) = %d\n", key, hash);
1374ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#endif
1384ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return hash;
1394ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
1404ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1413d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN __glxHashTable *__glxHashCreate(void)
1424ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
1434ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr table;
1444ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int          i;
1454ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1464ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table           = HASH_ALLOC(sizeof(*table));
1474ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (!table) return NULL;
1484ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->magic    = HASH_MAGIC;
1494ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->entries  = 0;
1504ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->hits     = 0;
1514ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->partials = 0;
1524ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->misses   = 0;
1534ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1544ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < HASH_SIZE; i++) table->buckets[i] = NULL;
1554ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return table;
1564ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
1574ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1583d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN int __glxHashDestroy(__glxHashTable *t)
1594ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
1604ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr  table = (__glxHashTablePtr)t;
1614ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr bucket;
1624ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr next;
1634ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int           i;
1644ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1654ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
1664ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1674ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < HASH_SIZE; i++) {
1684ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	for (bucket = table->buckets[i]; bucket;) {
1694ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    next = bucket->next;
1704ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    HASH_FREE(bucket);
1714ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    bucket = next;
1724ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	}
1734ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
1744ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    HASH_FREE(table);
1754ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return 0;
1764ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
1774ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1784ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg/* Find the bucket and organize the list so that this bucket is at the
1794ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg   top. */
1804ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1814ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic __glxHashBucketPtr HashFind(__glxHashTablePtr table,
1824ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg			      unsigned long key, unsigned long *h)
1834ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
1844ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long hash = HashHash(key);
1854ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr prev = NULL;
1864ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr bucket;
1874ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1884ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (h) *h = hash;
1894ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
1904ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (bucket = table->buckets[hash]; bucket; bucket = bucket->next) {
1914ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	if (bucket->key == key) {
1924ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    if (prev) {
1934ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg				/* Organize */
1944ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg		prev->next           = bucket->next;
1954ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg		bucket->next         = table->buckets[hash];
1964ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg		table->buckets[hash] = bucket;
1974ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg		++table->partials;
1984ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    } else {
1994ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg		++table->hits;
2004ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    }
2014ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    return bucket;
2024ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	}
2034ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	prev = bucket;
2044ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
2054ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    ++table->misses;
2064ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return NULL;
2074ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
2084ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2093d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN int __glxHashLookup(__glxHashTable *t,
2103d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg			      unsigned long key, void **value)
2114ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
2124ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr  table = (__glxHashTablePtr)t;
2134ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr bucket;
2144ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2154ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (!table || table->magic != HASH_MAGIC) return -1; /* Bad magic */
2164ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2174ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    bucket = HashFind(table, key, NULL);
2184ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (!bucket) return 1;	/* Not found */
2194ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    *value = bucket->value;
2204ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return 0;			/* Found */
2214ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
2224ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2233d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN int __glxHashInsert(__glxHashTable *t,
2243d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg			      unsigned long key, void *value)
2254ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
2264ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr  table = (__glxHashTablePtr)t;
2274ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr bucket;
2284ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long hash;
2294ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2304ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
2314ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2324ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (HashFind(table, key, &hash)) return 1; /* Already in table */
2334ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2344ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    bucket               = HASH_ALLOC(sizeof(*bucket));
2354ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (!bucket) return -1;	/* Error */
2364ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    bucket->key          = key;
2374ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    bucket->value        = value;
2384ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    bucket->next         = table->buckets[hash];
2394ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->buckets[hash] = bucket;
2404ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#if HASH_DEBUG
2414ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("Inserted %d at %d/%p\n", key, hash, bucket);
2424ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#endif
2434ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return 0;			/* Added to table */
2444ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
2454ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2463d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN int __glxHashDelete(__glxHashTable *t, unsigned long key)
2474ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
2484ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr  table = (__glxHashTablePtr)t;
2494ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long hash;
2504ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr bucket;
2514ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2524ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
2534ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2544ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    bucket = HashFind(table, key, &hash);
2554ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2564ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (!bucket) return 1;	/* Not found */
2574ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2584ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->buckets[hash] = bucket->next;
2594ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    HASH_FREE(bucket);
2604ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return 0;
2614ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
2624ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2633d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN int __glxHashNext(__glxHashTable *t,
2643d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg			    unsigned long *key, void **value)
2654ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
2664ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr  table = (__glxHashTablePtr)t;
2674ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2684ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    while (table->p0 < HASH_SIZE) {
2694ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	if (table->p1) {
2704ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    *key       = table->p1->key;
2714ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    *value     = table->p1->value;
2724ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    table->p1  = table->p1->next;
2734ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    return 1;
2744ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	}
2754ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	table->p1 = table->buckets[table->p0];
2764ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	++table->p0;
2774ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
2784ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return 0;
2794ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
2804ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2813d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg_X_HIDDEN int __glxHashFirst(__glxHashTable *t,
2823d28a2690f3752990be50a25447747e237d7bee9Kristian Høgsberg			     unsigned long *key, void **value)
2834ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
2844ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr  table = (__glxHashTablePtr)t;
2854ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2864ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (table->magic != HASH_MAGIC) return -1; /* Bad magic */
2874ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2884ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->p0 = 0;
2894ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table->p1 = table->buckets[0];
2904ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return __glxHashNext(table, key, value);
2914ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
2924ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2934ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#if HASH_MAIN
2944ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#define DIST_LIMIT 10
2954ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic int dist[DIST_LIMIT];
2964ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
2974ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic void clear_dist(void) {
2984ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int i;
2994ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3004ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < DIST_LIMIT; i++) dist[i] = 0;
3014ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
3024ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3034ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic int count_entries(__glxHashBucketPtr bucket)
3044ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
3054ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int count = 0;
3064ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3074ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (; bucket; bucket = bucket->next) ++count;
3084ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return count;
3094ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
3104ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3114ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic void update_dist(int count)
3124ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
3134ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    if (count >= DIST_LIMIT) ++dist[DIST_LIMIT-1];
3144ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    else                     ++dist[count];
3154ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
3164ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3174ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic void compute_dist(__glxHashTablePtr table)
3184ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
3194ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int           i;
3204ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashBucketPtr bucket;
3214ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3224ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("Entries = %ld, hits = %ld, partials = %ld, misses = %ld\n",
3234ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	   table->entries, table->hits, table->partials, table->misses);
3244ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    clear_dist();
3254ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < HASH_SIZE; i++) {
3264ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	bucket = table->buckets[i];
3274ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	update_dist(count_entries(bucket));
3284ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
3294ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < DIST_LIMIT; i++) {
3304ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	if (i != DIST_LIMIT-1) printf("%5d %10d\n", i, dist[i]);
3314ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	else                   printf("other %10d\n", dist[i]);
3324ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
3334ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
3344ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3354ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergstatic void check_table(__glxHashTablePtr table,
3364ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg			unsigned long key, unsigned long value)
3374ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
3384ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    unsigned long retval  = 0;
3394ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int           retcode = __glxHashLookup(table, key, &retval);
3404ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3414ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    switch (retcode) {
3424ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    case -1:
3434ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	printf("Bad magic = 0x%08lx:"
3444ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	       " key = %lu, expected = %lu, returned = %lu\n",
3454ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	       table->magic, key, value, retval);
3464ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	break;
3474ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    case 1:
3484ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	printf("Not found: key = %lu, expected = %lu returned = %lu\n",
3494ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	       key, value, retval);
3504ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	break;
3514ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    case 0:
3524ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	if (value != retval)
3534ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	    printf("Bad value: key = %lu, expected = %lu, returned = %lu\n",
3544ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg		   key, value, retval);
3554ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	break;
3564ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    default:
3574ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	printf("Bad retcode = %d: key = %lu, expected = %lu, returned = %lu\n",
3584ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	       retcode, key, value, retval);
3594ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg	break;
3604ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    }
3614ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
3624ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3634ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsbergint main(void)
3644ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg{
3654ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashTablePtr table;
3664ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    int          i;
3674ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3684ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("\n***** 256 consecutive integers ****\n");
3694ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table = __glxHashCreate();
3704ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 256; i++) __glxHashInsert(table, i, i);
3714ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 256; i++) check_table(table, i, i);
3724ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 256; i >= 0; i--) check_table(table, i, i);
3734ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    compute_dist(table);
3744ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashDestroy(table);
3754ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3764ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("\n***** 1024 consecutive integers ****\n");
3774ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table = __glxHashCreate();
3784ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) __glxHashInsert(table, i, i);
3794ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) check_table(table, i, i);
3804ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 1024; i >= 0; i--) check_table(table, i, i);
3814ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    compute_dist(table);
3824ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashDestroy(table);
3834ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3844ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("\n***** 1024 consecutive page addresses (4k pages) ****\n");
3854ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table = __glxHashCreate();
3864ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) __glxHashInsert(table, i*4096, i);
3874ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) check_table(table, i*4096, i);
3884ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 1024; i >= 0; i--) check_table(table, i*4096, i);
3894ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    compute_dist(table);
3904ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashDestroy(table);
3914ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
3924ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("\n***** 1024 random integers ****\n");
3934ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table = __glxHashCreate();
3944ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    srandom(0xbeefbeef);
3954ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) __glxHashInsert(table, random(), i);
3964ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    srandom(0xbeefbeef);
3974ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) check_table(table, random(), i);
3984ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    srandom(0xbeefbeef);
3994ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 1024; i++) check_table(table, random(), i);
4004ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    compute_dist(table);
4014ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashDestroy(table);
4024ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
4034ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    printf("\n***** 5000 random integers ****\n");
4044ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    table = __glxHashCreate();
4054ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    srandom(0xbeefbeef);
4064ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 5000; i++) __glxHashInsert(table, random(), i);
4074ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    srandom(0xbeefbeef);
4084ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 5000; i++) check_table(table, random(), i);
4094ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    srandom(0xbeefbeef);
4104ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    for (i = 0; i < 5000; i++) check_table(table, random(), i);
4114ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    compute_dist(table);
4124ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    __glxHashDestroy(table);
4134ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg
4144ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg    return 0;
4154ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg}
4164ceefccbfa180d19e27716bf7f282d0438ac34bdKristian Høgsberg#endif
417