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