usermode/library/common/cuckoo_hash/PointerHash.c

00001 //metadoc PointerHash copyright Steve Dekorte 2002
00002 //metadoc PointerHash license BSD revised
00003 //metadoc PointerHash notes Suggestion to use cuckoo hash and original implementation by Marc Fauconneau 
00004 
00005 #define POINTERHASH_C
00006 #include "PointerHash.h"
00007 #undef POINTERHASH_C
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <assert.h>
00012 
00013 IOINLINE PointerHash *PointerHash_new(void)
00014 {
00015         PointerHash *self = (PointerHash *)io_calloc(1, sizeof(PointerHash));
00016         PointerHash_setSize_(self, 8);
00017         return self;
00018 }
00019 
00020 IOINLINE void PointerHash_copy_(PointerHash *self, const PointerHash *other)
00021 {
00022         io_free(self->records);
00023         memcpy(self, other, sizeof(PointerHash));
00024         self->records = malloc(self->size * sizeof(PointerHashRecord));
00025         memcpy(self->records, other->records, self->size * sizeof(PointerHashRecord));
00026 }
00027 
00028 IOINLINE PointerHash *PointerHash_clone(PointerHash *self)
00029 {
00030         PointerHash *other = PointerHash_new();
00031         PointerHash_copy_(other, self);
00032         return other;
00033 }
00034 
00035 IOINLINE void PointerHash_setSize_(PointerHash *self, size_t size)
00036 {
00037         self->records = realloc(self->records, size * sizeof(PointerHashRecord));
00038         
00039         if(size > self->size)
00040         {               
00041                 memset(self->records + self->size * sizeof(PointerHashRecord), 
00042                         0x0, (size - self->size) * sizeof(PointerHashRecord));
00043         }
00044         
00045         self->size = size;
00046         
00047         PointerHash_updateMask(self);
00048 }
00049 
00050 IOINLINE void PointerHash_updateMask(PointerHash *self)
00051 {
00052         self->mask = (intptr_t)(self->size - 1);
00053 }
00054 
00055 IOINLINE void PointerHash_show(PointerHash *self)
00056 {
00057         size_t i;
00058         
00059         printf("PointerHash records:\n");
00060         for(i = 0; i < self->size; i++)
00061         {
00062                 PointerHashRecord *r = PointerHashRecords_recordAt_(self->records, i);
00063                 printf("  %i: %p %p\n", (int)i, r->k, r->v);
00064         }
00065 }
00066 
00067 IOINLINE void PointerHash_free(PointerHash *self)
00068 {
00069         io_free(self->records);
00070         io_free(self);
00071 }
00072 
00073 IOINLINE void PointerHash_insert_(PointerHash *self, PointerHashRecord *x)
00074 {       
00075         int n;
00076         
00077         for (n = 0; n < POINTERHASH_MAXLOOP; n ++)
00078         { 
00079                 PointerHashRecord *r;
00080                 
00081                 r = PointerHash_record1_(self, x->k);
00082                 PointerHashRecord_swapWith_(x, r);
00083                 if(x->k == 0x0) { self->keyCount ++; return; }
00084                  
00085                 r = PointerHash_record2_(self, x->k);
00086                 PointerHashRecord_swapWith_(x, r);
00087                 if(x->k == 0x0) { self->keyCount ++; return; }
00088         }
00089         
00090         PointerHash_grow(self); 
00091         PointerHash_at_put_(self, x->k, x->v);
00092 }
00093 
00094 IOINLINE void PointerHash_insertRecords(PointerHash *self, unsigned char *oldRecords, size_t oldSize)
00095 {
00096         size_t i;
00097         
00098         for (i = 0; i < oldSize; i ++)
00099         {
00100                 PointerHashRecord *r = PointerHashRecords_recordAt_(oldRecords, i);
00101                 
00102                 if (r->k)
00103                 {
00104                         PointerHash_at_put_(self, r->k, r->v);
00105                 }
00106         }
00107 }
00108 
00109 IOINLINE void PointerHash_resizeTo_(PointerHash *self, size_t newSize)
00110 {
00111         unsigned char *oldRecords = self->records;
00112         size_t oldSize = self->size;
00113         self->size = newSize;
00114         self->records = io_calloc(1, sizeof(PointerHashRecord) * self->size);
00115         self->keyCount = 0;
00116         PointerHash_updateMask(self);
00117         PointerHash_insertRecords(self, oldRecords, oldSize);
00118         io_free(oldRecords);
00119 }
00120 
00121 IOINLINE void PointerHash_grow(PointerHash *self)
00122 {
00123         PointerHash_resizeTo_(self, self->size * 2);
00124 }
00125 
00126 void PointerHash_shrink(PointerHash *self)
00127 {
00128         PointerHash_resizeTo_(self, self->size / 2);
00129 }
00130 
00131 IOINLINE void PointerHash_removeKey_(PointerHash *self, void *k)
00132 {
00133         PointerHashRecord *r;
00134         
00135         r = PointerHash_record1_(self, k);      
00136         if(r->k == k)
00137         {
00138                 r->k = 0x0;
00139                 r->v = 0x0;
00140                 self->keyCount --;
00141                 PointerHash_shrinkIfNeeded(self);
00142                 return;
00143         }
00144         
00145         r = PointerHash_record2_(self, k);
00146         if(r->k == k)
00147         {
00148                 r->k = 0x0;
00149                 r->v = 0x0;
00150                 self->keyCount --;
00151                 PointerHash_shrinkIfNeeded(self);
00152                 return;
00153         }
00154 }
00155 
00156 IOINLINE size_t PointerHash_size(PointerHash *self) // actually the keyCount
00157 {
00158         return self->keyCount;
00159 }
00160 
00161 // ----------------------------
00162 
00163 IOINLINE size_t PointerHash_memorySize(PointerHash *self)
00164 {
00165         return sizeof(PointerHash) + self->size * sizeof(PointerHashRecord);
00166 }
00167 
00168 IOINLINE void PointerHash_compact(PointerHash *self)
00169 {
00170 }

Generated on Sat Apr 23 11:43:35 2011 for Mnemosyne by  doxygen 1.4.7