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