////////////////////////////////////////////////////////////////////////////// // Project: Redpants Kernel // // Date: 5-12-2000 // // Module: hashtable.c // // Purpose: This portion of the shell contains the code which implements // // hashtables to allow the console to keep track of commands. // // // // Created 2000, by Ben L. Titzer // ////////////////////////////////////////////////////////////////////////////// #include <kernel/hash.h> #include <wchar.h> #include <stdlib.h> #define DEFAULT_SIZE 31 //hashtable_t preinit; //hashelem_t pretable[DEFAULT_SIZE]; hashtable_t *hashCreate(dword size) { word cntr; hashtable_t *h; // allocate the hashtable structure h = (hashtable_t *)malloc(sizeof(hashtable_t)); if ( h == NULL ) return NULL; // if allocation failed, return NULL // try to allocate the table h->table = (hashelem_t *)malloc(sizeof(hashelem_t)*size); if ( h->table == NULL ) // if we failed { free(h); // free the hashtable structure return NULL; // return NULL } h->size = size; // store the size of the table h->used = 0; // none are used yet for ( cntr = 0; cntr < size; cntr++ ) // clear all data in hashtable { h->table[cntr].str = NULL; h->table[cntr].data = NULL; } return h; } dword hashInsert(hashtable_t *h, hashelem_t *e) { dword hval; dword probe; hashelem_t *f; if ( e->str == NULL ) return 0; // don't insert empty strings if ( (f = hashFind(h, e->str)) != NULL ) // if duplicate { f->data = e->data; // update data return 1; } hval = hash(e->str) % h->size; if ( h->table[hval].str != NULL ) // if spot is already taken { for ( probe = 2; probe < 10; probe++ ) // do quadratic probing { hval = (hval+probe*probe)%h->size; if ( h->table[hval].str == NULL ) break; } if ( probe == 10 ) return 0; // couldn't find a spot after } h->table[hval] = *e; h->used++; return 1; } dword hash(const wchar_t* s) { dword hash = 0; wchar_t c; while ( (c = *s++) ) // loop through string hash = c + (hash << 6) + (hash << 16) - hash; // update hash value return hash; } hashelem_t *hashFind(hashtable_t *h, const wchar_t* s) { dword probe = 2; dword hval; if ( s == NULL ) return NULL; hval = hash(s) % h->size; while ( (h->table[hval].str == NULL) || (wcsicmp(s, h->table[hval].str) != 0) ) { if ( probe == 9 ) return NULL; // we didnt find it hval = (hval+probe*probe)%h->size; // quadratic probe probe++; } return h->table + hval; } void hashList(hashtable_t *h, void (*callback)(hashelem_t *e)) { dword cntr; for ( cntr = 0; cntr < h->size; cntr++ ) { if ( h->table[cntr].str != NULL ) callback(h->table + cntr); } }