3 osrfHash* osrfNewHash() {
5 OSRF_MALLOC(hash, sizeof(osrfHash));
6 hash->hash = osrfNewList();
9 hash->keys = osrfNewStringArray(64);
14 /* algorithm proposed by Donald E. Knuth
15 * in The Art Of Computer Programming Volume 3 (more or less..)*/
16 static unsigned int osrfHashMakeKey(char* str) {
18 unsigned int len = strlen(str);
21 for(i = 0; i < len; str++, i++)
22 h = ((h << 5) ^ (h >> 27)) ^ (*str);
23 return (h & (OSRF_HASH_LIST_SIZE-1));
28 #define OSRF_HASH_MAKE_KEY(str,num) \
30 unsigned int len = strlen(str); \
31 unsigned int h = len;\
33 for(i = 0; i < len; str++, i++)\
34 h = ((h << 5) ^ (h >> 27)) ^ (*str);\
35 *num = (h & (OSRF_HASH_LIST_SIZE-1));\
40 #define OSRF_HASH_MAKE_KEY(str,num) \
41 unsigned int ___len = strlen(str);\
42 unsigned int ___h = ___len;\
43 unsigned int ___i = 0;\
44 for(___i = 0; ___i < ___len; str++, ___i++)\
45 ___h = ((___h << 5) ^ (___h >> 27)) ^ (*str);\
46 num = (___h & (OSRF_HASH_LIST_SIZE-1));\
50 #define OSRF_HASH_MAKE_KEY(str,num,len) \
53 for(__i = 0; __i < len; __i++, str++)\
54 num = ((num << 5) ^ (num >> 27)) ^ (*str);\
55 num = (num & (OSRF_HASH_LIST_SIZE-1));\
59 #define OSRF_HASH_MAKE_KEY(str,num, len) \
60 num = osrfHashMakeKey(str);\
61 fprintf(stderr, "made num: %d\n", num);
66 /* returns the index of the item and points l to the sublist the item
67 * lives in if the item and points n to the hashnode the item
68 * lives in if the item is found. Otherwise -1 is returned */
69 static unsigned int osrfHashFindItem( osrfHash* hash, char* key, osrfList** l, osrfHashNode** n ) {
70 if(!(hash && key)) return -1;
73 int i = osrfHashMakeKey(key);
77 OSRF_HASH_MAKE_KEY(key, &i);
80 osrfList* list = OSRF_LIST_GET_INDEX( hash->hash, i );
81 if( !list ) { return -1; }
84 osrfHashNode* node = NULL;
85 for( k = 0; k < list->size; k++ ) {
86 node = OSRF_LIST_GET_INDEX(list, k);
87 if( node && node->key && !strcmp(node->key, key) )
99 osrfHashNode* osrfNewHashNode(char* key, void* item) {
100 if(!(key && item)) return NULL;
102 OSRF_MALLOC(n, sizeof(osrfHashNode));
103 n->key = strdup(key);
108 void* osrfHashNodeFree(osrfHash* hash, osrfHashNode* node) {
109 if(!(node && hash)) return NULL;
112 hash->freeItem( node->key, node->item );
113 else item = node->item;
119 void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... ) {
120 if(!(hash && item && key )) return NULL;
122 VA_LIST_TO_STRING(key);
123 void* olditem = osrfHashRemove( hash, VA_BUF );
125 int bucketkey = osrfHashMakeKey(VA_BUF);
128 unsigned int bucketkey;
129 OSRF_HASH_MAKE_KEY(VA_BUF, &bucketkey);
133 if( !(bucket = OSRF_LIST_GET_INDEX(hash->hash, bucketkey)) ) {
134 bucket = osrfNewList();
135 osrfListSet( hash->hash, bucket, bucketkey );
138 osrfHashNode* node = osrfNewHashNode(VA_BUF, item);
139 osrfListPushFirst( bucket, node );
141 if(!osrfStringArrayContains(hash->keys, VA_BUF))
142 osrfStringArrayAdd( hash->keys, VA_BUF );
148 void* osrfHashRemove( osrfHash* hash, const char* key, ... ) {
149 if(!(hash && key )) return NULL;
151 VA_LIST_TO_STRING(key);
153 osrfList* list = NULL;
155 int index = osrfHashFindItem( hash, (char*) VA_BUF, &list, &node );
156 if( index == -1 ) return NULL;
158 osrfListRemove( list, index );
161 void* item = osrfHashNodeFree(hash, node);
162 osrfStringArrayRemove(hash->keys, VA_BUF);
167 void* osrfHashGet( osrfHash* hash, const char* key, ... ) {
168 if(!(hash && key )) return NULL;
169 VA_LIST_TO_STRING(key);
171 osrfHashNode* node = NULL;
172 int index = osrfHashFindItem( hash, (char*) VA_BUF, NULL, &node );
173 if( index == -1 ) return NULL;
178 osrfStringArray* osrfHashKeysInc( osrfHash* hash ) {
179 if(!hash) return NULL;
183 osrfStringArray* osrfHashKeys( osrfHash* hash ) {
184 if(!hash) return NULL;
189 osrfStringArray* strings = osrfNewStringArray(8);
191 for( i = 0; i != hash->hash->size; i++ ) {
192 list = OSRF_LIST_GET_INDEX( hash->hash, i );
194 for( k = 0; k != list->size; k++ ) {
195 node = OSRF_LIST_GET_INDEX( list, k );
196 if( node ) osrfStringArrayAdd( strings, node->key );
205 unsigned long osrfHashGetCount( osrfHash* hash ) {
210 void osrfHashFree( osrfHash* hash ) {
217 for( i = 0; i != hash->hash->size; i++ ) {
218 if( ( list = OSRF_LIST_GET_INDEX( hash->hash, i )) ) {
219 for( j = 0; j != list->size; j++ ) {
220 if( (node = OSRF_LIST_GET_INDEX( list, j )) ) {
221 OSRF_HASH_NODE_FREE(hash, node);
228 osrfListFree(hash->hash);
229 osrfStringArrayFree(hash->keys);
235 osrfHashIterator* osrfNewHashIterator( osrfHash* hash ) {
236 if(!hash) return NULL;
237 //osrfHashIterator* itr = safe_malloc(sizeof(osrfHashIterator));
238 osrfHashIterator* itr;
239 OSRF_MALLOC(itr, sizeof(osrfHashIterator));
242 itr->keys = osrfHashKeysInc(hash);
246 void* osrfHashIteratorNext( osrfHashIterator* itr ) {
247 if(!(itr && itr->hash)) return NULL;
248 if( itr->currentIdx >= itr->keys->size ) return NULL;
250 itr->current = strdup(
251 osrfStringArrayGetString(itr->keys, itr->currentIdx++));
252 char* val = osrfHashGet( itr->hash, itr->current );
256 void osrfHashIteratorFree( osrfHashIterator* itr ) {
259 //osrfStringArrayFree(itr->keys);
263 void osrfHashIteratorReset( osrfHashIterator* itr ) {
266 //osrfStringArrayFree(itr->keys);
267 itr->keys = osrfHashKeysInc(itr->hash);