usermode/library/common/cuckoo_hash/PointerHash_inline.h

00001 //metadoc PointerHash copyright Steve Dekorte 2002, Marc Fauconneau 2007
00002 //metadoc PointerHash license BSD revised
00003 /*metadoc PointerHash description
00004         PointerHash - Cuckoo Hash
00005         keys and values are references (they are not copied or freed)
00006         key pointers are assumed unique
00007 */
00008 
00009 #ifdef POINTERHASH_C
00010 #define IO_IN_C_FILE
00011 #endif
00012 #include "Common_inline.h"
00013 #ifdef IO_DECLARE_INLINES
00014 
00015 #define PointerHashRecords_recordAt_(records, pos) (PointerHashRecord *)(records + (pos * sizeof(PointerHashRecord)))
00016 
00017 /*
00018 IOINLINE unsigned int PointerHash_hash(PointerHash *self, void *key)
00019 {
00020         intptr_t k = (intptr_t)PointerHashKey_value(key);
00021         return k^(k>>4);
00022 }
00023 
00024 IOINLINE unsigned int PointerHash_hash_more(PointerHash *self, unsigned int hash)
00025 {
00026         return hash ^ (hash >> self->log2tableSize);
00027 }
00028 */
00029 
00030 // -----------------------------------
00031 
00032 IOINLINE PointerHashRecord *PointerHash_record1_(PointerHash *self, void *k)
00033 {
00034         // the ~| 0x1 before the mask ensures an odd pos
00035         intptr_t kk = (intptr_t)k;
00036         size_t pos = ((kk^(kk>>4)) | 0x1) & self->mask;
00037         return PointerHashRecords_recordAt_(self->records, pos);
00038 }
00039 
00040 IOINLINE PointerHashRecord *PointerHash_record2_(PointerHash *self, void *k)
00041 {
00042         // the | 0x1 before the mask ensures an even pos
00043         intptr_t kk = (intptr_t)k;
00044         //size_t pos = (((kk^(kk/33)) << 1)) & self->mask;
00045         size_t pos = (kk << 1) & self->mask;
00046         return PointerHashRecords_recordAt_(self->records, pos);
00047 }
00048 
00049 IOINLINE void *PointerHash_at_(PointerHash *self, void *k)
00050 {
00051         PointerHashRecord *r;
00052         
00053         r = PointerHash_record1_(self, k);
00054         if(k == r->k) return r->v;
00055         
00056         r = PointerHash_record2_(self, k);      
00057         if(k == r->k) return r->v;
00058         
00059         return 0x0;
00060 }
00061 
00062 IOINLINE size_t PointerHash_count(PointerHash *self)
00063 {
00064         return self->keyCount;
00065 }
00066 
00067 IOINLINE int PointerHashKey_hasKey_(PointerHash *self, void *key)
00068 {
00069         return PointerHash_at_(self, key) != NULL;
00070 }
00071 
00072 IOINLINE void PointerHash_at_put_(PointerHash *self, void *k, void *v)
00073 {
00074         PointerHashRecord *r;
00075         
00076         r = PointerHash_record1_(self, k);
00077         
00078         if(!r->k)
00079         {
00080                 r->k = k;
00081                 r->v = v;
00082                 self->keyCount ++;
00083                 return;
00084         }
00085         
00086         if(r->k == k)
00087         {
00088                 r->v = v;
00089                 return;
00090         }
00091 
00092         r = PointerHash_record2_(self, k);
00093 
00094         if(!r->k)
00095         {
00096                 r->k = k;
00097                 r->v = v;
00098                 self->keyCount ++;
00099                 return;
00100         }
00101         
00102         if(r->k == k)
00103         {
00104                 r->v = v;
00105                 return;
00106         }
00107         
00108         {
00109         PointerHashRecord x;
00110         x.k = k;
00111         x.v = v;
00112         PointerHash_insert_(self, &x);
00113         }
00114 }
00115 
00116 IOINLINE void PointerHash_shrinkIfNeeded(PointerHash *self)
00117 {
00118         if(self->keyCount < self->size/8)
00119         {
00120                 PointerHash_shrink(self);
00121         }
00122 }
00123 
00124 IOINLINE void PointerHashRecord_swapWith_(PointerHashRecord *self, PointerHashRecord *other)
00125 {
00126         PointerHashRecord tmp = *self;
00127         *self = *other;
00128         *other = tmp;
00129 }
00130 
00131 IOINLINE void PointerHash_clean(PointerHash *self)
00132 {
00133         memset(self->records, 0, sizeof(PointerHashRecord) * self->size);
00134         self->keyCount = 0;
00135 }
00136 
00137 #include "PointerHash.c"
00138 
00139 // --- enumeration --------------------------------------------------
00140 
00141 #define POINTERHASH_FOREACH(self, pkey, pvalue, code) \
00142 {\
00143         PointerHash *_self = (self);\
00144         unsigned char *_records = _self->records;\
00145         unsigned int _i, _size = _self->size;\
00146         void *pkey;\
00147         void *pvalue;\
00148         \
00149         for (_i = 0; _i < _size; _i ++)\
00150         {\
00151                 PointerHashRecord *_record = PointerHashRecords_recordAt_(_records, _i);\
00152                 if (_record->k)\
00153                 {\
00154                         pkey = _record->k;\
00155                         pvalue = _record->v;\
00156                         code;\
00157                 }\
00158         }\
00159 }
00160 
00161 #undef IO_IN_C_FILE
00162 #endif

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