usermode/library/common/cuckoo_hash/CHash_inline.h

00001 //metadoc CHash copyright Steve Dekorte 2009
00002 //metadoc CHash license BSD revised
00003 /*metadoc CHash description
00004         CHash - Cuckoo Hash
00005         keys and values are references (they are not copied or freed)
00006 */
00007 
00008 #ifdef CHASH_C
00009 #define IO_IN_C_FILE
00010 #endif
00011 #include "Common_inline.h"
00012 #ifdef IO_DECLARE_INLINES
00013 
00014 #define CRecords_recordAt_(records, pos) (CHashRecord *)(records + (pos * sizeof(CHashRecord)))
00015 
00016 IOINLINE CHashRecord *CHash_record1_(CHash *self, void *k)
00017 {
00018         // the ~ | 0x1 before the mask ensures an even pos
00019         size_t pos = self->hash1(k) & self->mask;
00020         //printf("pos1 %i/%i\n", pos, self->size);
00021         return CRecords_recordAt_(self->records, pos);
00022 }
00023 
00024 IOINLINE CHashRecord *CHash_record2_(CHash *self, void *k)
00025 {
00026         // the | 0x1 before the mask ensures an odd pos
00027         size_t pos = self->hash2(k) & self->mask;
00028         //printf("pos2 %i/%i\n", pos, self->size);
00029         return CRecords_recordAt_(self->records, pos);
00030 }
00031 
00032 IOINLINE void *CHash_at_(CHash *self, void *k)
00033 {
00034         CHashRecord *r;
00035         
00036          r = CHash_record1_(self, k);
00037 
00038         if(r->k && self->equals(k, r->k))
00039         {
00040                 return r->v;
00041         }
00042         
00043         r = CHash_record2_(self, k);
00044         
00045         if(r->k && self->equals(k, r->k))
00046         {
00047                 return r->v;
00048         }
00049         
00050         return 0x0;
00051 }
00052 
00053 IOINLINE size_t CHash_count(CHash *self)
00054 {
00055         return self->keyCount;
00056 }
00057 
00058 IOINLINE int CHashKey_hasKey_(CHash *self, void *key)
00059 {
00060         return CHash_at_(self, key) != NULL;
00061 }
00062 
00063 IOINLINE int CHash_at_put_(CHash *self, void *k, void *v)
00064 {
00065         CHashRecord *r;
00066         
00067         r = CHash_record1_(self, k);
00068         
00069         if(!r->k)
00070         {
00071                 r->k = k;
00072                 r->v = v;
00073                 self->keyCount ++;
00074                 return 0;
00075         }
00076         
00077         if(k == r->k || self->equals(k, r->k))
00078         {
00079                 r->v = v;
00080                 return 0;
00081         }
00082 
00083         r = CHash_record2_(self, k);
00084 
00085         if(!r->k)
00086         {
00087                 r->k = k;
00088                 r->v = v;
00089                 self->keyCount ++;
00090                 return 0;
00091         }
00092         
00093         if(k == r->k || self->equals(k, r->k))
00094         {
00095                 r->v = v;
00096                 return 0;
00097         }
00098         
00099 
00100         {
00101                 CHashRecord x;
00102                 x.k = k;
00103                 x.v = v;
00104                 return CHash_insert_(self, &x);
00105         }
00106 }
00107 
00108 IOINLINE void CHash_shrinkIfNeeded(CHash *self)
00109 {
00110         if(self->keyCount < self->size/5)
00111         {
00112                 CHash_shrink(self);
00113         }
00114 }
00115 
00116 IOINLINE void CHashRecord_swapWith_(CHashRecord *self, CHashRecord *other)
00117 {
00118         CHashRecord tmp = *self;
00119         *self = *other;
00120         *other = tmp;
00121 }
00122 
00123 IOINLINE void CHash_clean(CHash *self)
00124 {
00125         memset(self->records, 0, sizeof(CHashRecord) * self->size);
00126         self->keyCount = 0;
00127 }
00128 
00129 // --- enumeration --------------------------------------------------
00130 
00131 #define CHASH_FOREACH(self, pkey, pvalue, code) \
00132 {\
00133         CHash *_self = (self);\
00134         unsigned char *_records = _self->records;\
00135         unsigned int _i, _size = _self->size;\
00136         void *pkey;\
00137         void *pvalue;\
00138         \
00139         for (_i = 0; _i < _size; _i ++)\
00140         {\
00141                 CHashRecord *_record = CRecords_recordAt_(_records, _i);\
00142                 if (_record->k)\
00143                 {\
00144                         pkey = _record->k;\
00145                         pvalue = _record->v;\
00146                         code;\
00147                 }\
00148         }\
00149 }
00150 
00151 #undef IO_IN_C_FILE
00152 #endif

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