00001
00002
00003
00004
00005 #define POINTERHASH_C
00006 #include "PointerHash.h"
00007 #undef POINTERHASH_C
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <string.h>
00011 #include <assert.h>
00012
00013 IOINLINE PointerHash *PointerHash_new(void)
00014 {
00015 PointerHash *self = (PointerHash *)io_calloc(1, sizeof(PointerHash));
00016 PointerHash_setSize_(self, 8);
00017 return self;
00018 }
00019
00020 IOINLINE void PointerHash_copy_(PointerHash *self, const PointerHash *other)
00021 {
00022 io_free(self->records);
00023 memcpy(self, other, sizeof(PointerHash));
00024 self->records = malloc(self->size * sizeof(PointerHashRecord));
00025 memcpy(self->records, other->records, self->size * sizeof(PointerHashRecord));
00026 }
00027
00028 IOINLINE PointerHash *PointerHash_clone(PointerHash *self)
00029 {
00030 PointerHash *other = PointerHash_new();
00031 PointerHash_copy_(other, self);
00032 return other;
00033 }
00034
00035 IOINLINE void PointerHash_setSize_(PointerHash *self, size_t size)
00036 {
00037 self->records = realloc(self->records, size * sizeof(PointerHashRecord));
00038
00039 if(size > self->size)
00040 {
00041 memset(self->records + self->size * sizeof(PointerHashRecord),
00042 0x0, (size - self->size) * sizeof(PointerHashRecord));
00043 }
00044
00045 self->size = size;
00046
00047 PointerHash_updateMask(self);
00048 }
00049
00050 IOINLINE void PointerHash_updateMask(PointerHash *self)
00051 {
00052 self->mask = (intptr_t)(self->size - 1);
00053 }
00054
00055 IOINLINE void PointerHash_show(PointerHash *self)
00056 {
00057 size_t i;
00058
00059 printf("PointerHash records:\n");
00060 for(i = 0; i < self->size; i++)
00061 {
00062 PointerHashRecord *r = PointerHashRecords_recordAt_(self->records, i);
00063 printf(" %i: %p %p\n", (int)i, r->k, r->v);
00064 }
00065 }
00066
00067 IOINLINE void PointerHash_free(PointerHash *self)
00068 {
00069 io_free(self->records);
00070 io_free(self);
00071 }
00072
00073 IOINLINE void PointerHash_insert_(PointerHash *self, PointerHashRecord *x)
00074 {
00075 int n;
00076
00077 for (n = 0; n < POINTERHASH_MAXLOOP; n ++)
00078 {
00079 PointerHashRecord *r;
00080
00081 r = PointerHash_record1_(self, x->k);
00082 PointerHashRecord_swapWith_(x, r);
00083 if(x->k == 0x0) { self->keyCount ++; return; }
00084
00085 r = PointerHash_record2_(self, x->k);
00086 PointerHashRecord_swapWith_(x, r);
00087 if(x->k == 0x0) { self->keyCount ++; return; }
00088 }
00089
00090 PointerHash_grow(self);
00091 PointerHash_at_put_(self, x->k, x->v);
00092 }
00093
00094 IOINLINE void PointerHash_insertRecords(PointerHash *self, unsigned char *oldRecords, size_t oldSize)
00095 {
00096 size_t i;
00097
00098 for (i = 0; i < oldSize; i ++)
00099 {
00100 PointerHashRecord *r = PointerHashRecords_recordAt_(oldRecords, i);
00101
00102 if (r->k)
00103 {
00104 PointerHash_at_put_(self, r->k, r->v);
00105 }
00106 }
00107 }
00108
00109 IOINLINE void PointerHash_resizeTo_(PointerHash *self, size_t newSize)
00110 {
00111 unsigned char *oldRecords = self->records;
00112 size_t oldSize = self->size;
00113 self->size = newSize;
00114 self->records = io_calloc(1, sizeof(PointerHashRecord) * self->size);
00115 self->keyCount = 0;
00116 PointerHash_updateMask(self);
00117 PointerHash_insertRecords(self, oldRecords, oldSize);
00118 io_free(oldRecords);
00119 }
00120
00121 IOINLINE void PointerHash_grow(PointerHash *self)
00122 {
00123 PointerHash_resizeTo_(self, self->size * 2);
00124 }
00125
00126 void PointerHash_shrink(PointerHash *self)
00127 {
00128 PointerHash_resizeTo_(self, self->size / 2);
00129 }
00130
00131 IOINLINE void PointerHash_removeKey_(PointerHash *self, void *k)
00132 {
00133 PointerHashRecord *r;
00134
00135 r = PointerHash_record1_(self, k);
00136 if(r->k == k)
00137 {
00138 r->k = 0x0;
00139 r->v = 0x0;
00140 self->keyCount --;
00141 PointerHash_shrinkIfNeeded(self);
00142 return;
00143 }
00144
00145 r = PointerHash_record2_(self, k);
00146 if(r->k == k)
00147 {
00148 r->k = 0x0;
00149 r->v = 0x0;
00150 self->keyCount --;
00151 PointerHash_shrinkIfNeeded(self);
00152 return;
00153 }
00154 }
00155
00156 IOINLINE size_t PointerHash_size(PointerHash *self)
00157 {
00158 return self->keyCount;
00159 }
00160
00161
00162
00163 IOINLINE size_t PointerHash_memorySize(PointerHash *self)
00164 {
00165 return sizeof(PointerHash) + self->size * sizeof(PointerHashRecord);
00166 }
00167
00168 IOINLINE void PointerHash_compact(PointerHash *self)
00169 {
00170 }