00001
00002
00003
00004
00005
00006
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
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 IOINLINE PointerHashRecord *PointerHash_record1_(PointerHash *self, void *k)
00033 {
00034
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
00043 intptr_t kk = (intptr_t)k;
00044
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
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