usermode/library/common/cuckoo_hash/PointerSetHash_inline.h

00001 //metadoc PointerSetHash copyright Steve Dekorte 2002, Marc Fauconneau 2007
00002 //metadoc PointerSetHash license BSD revised
00003 /*metadoc PointerSetHash description
00004         PointerSetHash - 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 #error
00012 #endif
00013 #include "Common_inline.h"
00014 #ifdef IO_DECLARE_INLINES
00015 
00016 #define PointerSetHashRecords_recordAt_(records, pos) (PointerSetHashRecord *)(records + (pos * sizeof(PointerSetHashRecord)))
00017 
00018 /*
00019 IOINLINE unsigned int PointerSetHash_hash(PointerSetHash *self, void *key)
00020 {
00021         intptr_t k = (intptr_t)PointerSetHashKey_value(key);
00022         return k^(k>>4);
00023 }
00024 
00025 IOINLINE unsigned int PointerSetHash_hash_more(PointerSetHash *self, unsigned int hash)
00026 {
00027         return hash ^ (hash >> self->log2tableSize);
00028 }
00029 */
00030 
00031 // -----------------------------------
00032 
00033 IOINLINE PointerSetHashRecord *PointerSetHash_record1_(PointerSetHash *self, void *k)
00034 {
00035         // the ~| 0x1 before the mask ensures an odd pos
00036         intptr_t kk = (intptr_t)k;
00037         size_t pos = ((kk^(kk>>4)) | 0x1) & self->mask;
00038         return PointerSetHashRecords_recordAt_(self->records, pos);
00039 }
00040 
00041 IOINLINE PointerSetHashRecord *PointerSetHash_record2_(PointerSetHash *self, void *k)
00042 {
00043         // the | 0x1 before the mask ensures an even pos
00044         intptr_t kk = (intptr_t)k;
00045         //size_t pos = (((kk^(kk/33)) << 1)) & self->mask;
00046         size_t pos = (kk << 1) & self->mask;
00047         return PointerSetHashRecords_recordAt_(self->records, pos);
00048 }
00049 
00050 IOINLINE void *PointerSetHash_at_(PointerSetHash *self, void *k)
00051 {
00052         PointerSetHashRecord *r;
00053         
00054         r = PointerSetHash_record1_(self, k);
00055         if(k == r->k) return 1;
00056         
00057         r = PointerSetHash_record2_(self, k);   
00058         if(k == r->k) return 1;
00059         
00060         return 0x0;
00061 }
00062 
00063 IOINLINE size_t PointerSetHash_count(PointerSetHash *self)
00064 {
00065         return self->keyCount;
00066 }
00067 
00068 IOINLINE int PointerSetHashKey_hasKey_(PointerSetHash *self, void *key)
00069 {
00070         return PointerSetHash_at_(self, key) != NULL;
00071 }
00072 
00073 IOINLINE void PointerSetHash_at_put_(PointerSetHash *self, void *k)
00074 {
00075         PointerSetHashRecord *r;
00076         
00077         r = PointerSetHash_record1_(self, k);
00078         
00079         if(!r->k)
00080         {
00081                 r->k = k;
00082                 self->keyCount ++;
00083                 return;
00084         }
00085         
00086         if(r->k == k)
00087         {
00088                 return;
00089         }
00090 
00091         r = PointerSetHash_record2_(self, k);
00092 
00093         if(!r->k)
00094         {
00095                 r->k = k;
00096                 self->keyCount ++;
00097                 return;
00098         }
00099         
00100         if(r->k == k)
00101         {
00102                 return;
00103         }
00104         
00105         {
00106         PointerSetHashRecord x;
00107         x.k = k;
00108         PointerSetHash_insert_(self, &x);
00109         }
00110 }
00111 
00112 IOINLINE void PointerSetHash_shrinkIfNeeded(PointerSetHash *self)
00113 {
00114         if(self->keyCount < self->size/8)
00115         {
00116                 PointerSetHash_shrink(self);
00117         }
00118 }
00119 
00120 IOINLINE void PointerSetHashRecord_swapWith_(PointerSetHashRecord *self, PointerSetHashRecord *other)
00121 {
00122         PointerSetHashRecord tmp = *self;
00123         *self = *other;
00124         *other = tmp;
00125 }
00126 
00127 IOINLINE void PointerSetHash_clean(PointerSetHash *self)
00128 {
00129         memset(self->records, 0, sizeof(PointerSetHashRecord) * self->size);
00130         self->keyCount = 0;
00131 }
00132 
00133 // --- enumeration --------------------------------------------------
00134 
00135 #define POINTERHASH_FOREACH(self, pkey, code) \
00136 {\
00137         PointerSetHash *_self = (self);\
00138         unsigned char *_records = _self->records;\
00139         unsigned int _i, _size = _self->size;\
00140         void *pkey;\
00141         void *pvalue;\
00142         \
00143         for (_i = 0; _i < _size; _i ++)\
00144         {\
00145                 PointerSetHashRecord *_record = PointerSetHashRecords_recordAt_(_records, _i);\
00146                 if (_record->k)\
00147                 {\
00148                         pkey = _record->k;\
00149                         code;\
00150                 }\
00151         }\
00152 }
00153 
00154 #undef IO_IN_C_FILE
00155 #endif

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