Permalink
Browse files

adding Hash_murmur

  • Loading branch information...
1 parent a84c329 commit 2da98615c95b9a9dad49f43829b0ded664984d9f Steve Dekorte committed May 27, 2009
View
@@ -19,6 +19,7 @@ LINKDLL := $(CC)
LINKDLLOUTFLAG := -o
LINKDIRFLAG := -L
LINKLIBFLAG := -l
+INSTALL_PREFIX_DEFINE := $(INSTALL_PREFIX)
# may need to remove --param max-inline-insns-single=500 for older versions of gccs
WARN :=-Wstrict-prototypes
@@ -90,20 +91,22 @@ CC := cl -nologo
CCOUTFLAG :=-Fo
WARN :=
#OPTIMIZE :=-Zi -MDd -D_USE_MATH_DEFINES -DWIN32 -D_DEBUG -D_CRT_SECURE_NO_DEPRECATE
-OPTIMIZE :=-Zi -MD -D_USE_MATH_DEFINES -DWIN32 -DNDEBUG -D_CRT_SECURE_NO_DEPRECATE
+OPTIMIZE :=-O2 -EHsc -MD -D_USE_MATH_DEFINES -DWIN32 -DNDEBUG -D_CRT_SECURE_NO_DEPRECATE
AR := link -lib
AROUTFLAG :=-out:
ARFLAGS :=
LINKDLL := link
LINKDLLOUTFLAG :=-out:
LINKDIRFLAG := -libpath:
-LINKLIBFLAG := lib
+LINKLIBFLAG :=
DLL_LIB_SUFFIX := .lib
+DLL_LIB_PREFIX :=
DLL_COMMAND := -link /INCREMENTAL:NO -subsystem:WINDOWS -machine:X86 -DLL $(DEF_FILE)
DLL_SUFFIX := dll
DLL_EXTRAS := ws2_32.lib shell32.lib
FLAT_NAMESPACE :=
RANLIB := echo no ranlib
+INSTALL_PREFIX_DEFINE := $(shell cygpath -am $(INSTALL_PREFIX))
endif
### FILES #########################################################
@@ -168,11 +171,13 @@ _build/dll: _build
-include $(objects:.o=.d)
_build/objs/%.o: source/%.c
- $(CC) -MM -MT $@ -MF $(@:.o=.d) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX)\" $(CFLAGS) -c $< $(CCOUTFLAG)$@
- $(CC) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX)\" $(CFLAGS) -c $< $(CCOUTFLAG)$@
+ifeq (,$(findstring Windows,$(SYS)))
+ $(CC) -MM -MT $@ -MF $(@:.o=.d) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX_DEFINE)\" $(CFLAGS) -c $< $(CCOUTFLAG)$@
+endif
+ $(CC) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX_DEFINE)\" $(CFLAGS) -c $< $(CCOUTFLAG)$@
_build/vmall_objs/%.o: source/%.c
- $(CC) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX)\" $(CFLAGS) \
+ $(CC) -DINSTALL_PREFIX=\"$(INSTALL_PREFIX_DEFINE)\" $(CFLAGS) \
-DBUILDING_IOVMALL_DLL -c $< $(CCOUTFLAG)$@
_build/headers/%.h: source/%.h _build/headers
View
@@ -1,6 +1,6 @@
//metadoc CHash copyright Steve Dekorte 2009
//metadoc CHash license BSD revised
-//metadoc PHash notes Suggestion to use cuckoo hash and original implementation by Marc Fauconneau
+//metadoc CHash notes Suggestion to use cuckoo hash and original implementation by Marc Fauconneau
#define CHASH_C
#include "CHash.h"
@@ -86,28 +86,40 @@ void CHash_setEqualFunc_(CHash *self, CHashEqualFunc *f)
self->equals = f;
}
-void CHash_insert_(CHash *self, CHashRecord *x)
+int CHash_insert_(CHash *self, CHashRecord *x)
{
int n;
+ size_t pos;
+ //printf("insert\n");
for (n = 0; n < CHASH_MAXLOOP; n ++)
{
CHashRecord *r;
+ //pos = self->hash1(x->k) & self->mask;
+ //printf("1 x->k = %p-> %i\n", x->k, pos);
r = CHash_record1_(self, x->k);
CHashRecord_swapWith_(x, r); //x ↔ T1 [h1 (x)]
- if(x->k == 0x0) { self->keyCount ++; return; }
-
+ if(x->k == 0x0) { self->keyCount ++; return 0; }
+
+ //pos = self->hash2(x->k) & self->mask;
+ //printf("2 x->k = %p-> %i\n\n", x->k, pos);
r = CHash_record2_(self, x->k);
CHashRecord_swapWith_(x, r); //x ↔ T2 [h2 (x)]
- if(x->k == 0x0) { self->keyCount ++; return; }
+ if(x->k == 0x0) { self->keyCount ++; return 0; }
+ }
+
+ if(self->isResizing)
+ {
+ return -1;
}
CHash_grow(self);
CHash_at_put_(self, x->k, x->v);
+ return 0;
}
-void CHash_insertRecords(CHash *self, unsigned char *oldRecords, size_t oldSize)
+int CHash_insertRecords(CHash *self, unsigned char *oldRecords, size_t oldSize)
{
int i;
@@ -117,21 +129,41 @@ void CHash_insertRecords(CHash *self, unsigned char *oldRecords, size_t oldSize)
if (r->k)
{
- CHash_at_put_(self, r->k, r->v);
+ if(CHash_at_put_(self, r->k, r->v)) return 1;
}
}
+ return 0;
}
-void CHash_resizeTo_(CHash *self, size_t newSize)
+int CHash_resizeTo_(CHash *self, size_t newSize)
{
unsigned char *oldRecords = self->records;
size_t oldSize = self->size;
- self->size = newSize;
- self->records = io_calloc(1, sizeof(CHashRecord) * self->size);
- self->keyCount = 0;
- CHash_updateMask(self);
- CHash_insertRecords(self, oldRecords, oldSize);
+
+ self->isResizing = 1;
+
+ //printf("%p resizeTo %i/%i %i%%\n", (void *)self, self->keyCount, self->size, (int)(100.0*CHash_density(self)));
+
+ do
+ {
+ self->size = newSize;
+ self->records = io_calloc(1, sizeof(CHashRecord) * self->size);
+ self->keyCount = 0;
+ CHash_updateMask(self);
+ if(CHash_insertRecords(self, oldRecords, oldSize) == 0)
+ {
+ self->isResizing = 0;
+ }
+ else
+ {
+ //printf("%p grow collision %i/%i\n", (void *)self, self->keyCount, self->size);
+ newSize *= 2;
+ io_free(self->records);
+ }
+ } while(self->isResizing);
+
io_free(oldRecords);
+ return 0;
}
void CHash_grow(CHash *self)
@@ -141,7 +173,8 @@ void CHash_grow(CHash *self)
void CHash_shrink(CHash *self)
{
- CHash_resizeTo_(self, self->size / 2);
+ //printf("%p shrink %i/%i\n", (void *)self, self->keyCount, self->size);
+ //CHash_resizeTo_(self, self->size / 2);
}
void CHash_removeKey_(CHash *self, void *k)
@@ -185,3 +218,11 @@ size_t CHash_memorySize(CHash *self)
void CHash_compact(CHash *self)
{
}
+
+float CHash_density(CHash *self)
+{
+ float kc = (float)self->keyCount;
+ float size = (float)self->size;
+ return kc/size;
+}
+
View
@@ -6,13 +6,13 @@
#include "Common.h"
#include <stddef.h>
-#include <stdint.h>
+#include "PortableStdint.h"
#ifdef __cplusplus
extern "C" {
#endif
-#define CHASH_MAXLOOP 10
+#define CHASH_MAXLOOP 5
typedef int (CHashEqualFunc)(void *, void *);
typedef intptr_t (CHashHashFunc)(void *);
@@ -32,6 +32,7 @@ typedef struct
CHashHashFunc *hash2;
CHashEqualFunc *equals;
intptr_t mask;
+ int isResizing;
} CHash;
BASEKIT_API CHash *CHash_new(void);
@@ -43,7 +44,7 @@ BASEKIT_API void CHash_setHash1Func_(CHash *self, CHashHashFunc *f);
BASEKIT_API void CHash_setHash2Func_(CHash *self, CHashHashFunc *f);
BASEKIT_API void CHash_setEqualFunc_(CHash *self, CHashEqualFunc *f);
-BASEKIT_API void CHash_at_put_(CHash *self, void *k, void *v);
+BASEKIT_API int CHash_at_put_(CHash *self, void *k, void *v);
BASEKIT_API void CHash_removeKey_(CHash *self, void *k);
BASEKIT_API size_t CHash_size(CHash *self); // actually the keyCount
@@ -53,12 +54,13 @@ BASEKIT_API void CHash_compact(CHash *self);
// private methods -------------------------------
BASEKIT_API void CHash_setSize_(CHash *self, size_t size);
-BASEKIT_API void CHash_insert_(CHash *self, CHashRecord *x);
+BASEKIT_API int CHash_insert_(CHash *self, CHashRecord *x);
BASEKIT_API void CHash_grow(CHash *self);
BASEKIT_API void CHash_shrinkIfNeeded(CHash *self);
BASEKIT_API void CHash_shrink(CHash *self);
BASEKIT_API void CHash_show(CHash *self);
BASEKIT_API void CHash_updateMask(CHash *self);
+BASEKIT_API float CHash_density(CHash *self);
#include "CHash_inline.h"
View
@@ -16,32 +16,35 @@
IOINLINE CHashRecord *CHash_record1_(CHash *self, void *k)
{
// the ~ | 0x1 before the mask ensures an even pos
- size_t pos = (~(self->hash1(k) | 0x1)) & self->mask;
+ size_t pos = self->hash1(k) & self->mask;
+ //printf("pos1 %i/%i\n", pos, self->size);
return CRecords_recordAt_(self->records, pos);
}
IOINLINE CHashRecord *CHash_record2_(CHash *self, void *k)
{
// the | 0x1 before the mask ensures an odd pos
- size_t pos = (self->hash2(k) | 0x1) & self->mask;
+ size_t pos = self->hash2(k) & self->mask;
+ //printf("pos2 %i/%i\n", pos, self->size);
return CRecords_recordAt_(self->records, pos);
}
IOINLINE void *CHash_at_(CHash *self, void *k)
{
- CHashRecord *r1 = CHash_record1_(self, k);
- CHashRecord *r2;
+ CHashRecord *r;
+
+ r = CHash_record1_(self, k);
- if(r1->k && self->equals(k, r1->k))
+ if(r->k && self->equals(k, r->k))
{
- return r1->v;
+ return r->v;
}
- r2 = CHash_record2_(self, k);
+ r = CHash_record2_(self, k);
- if(r2->k && self->equals(k, r2->k))
+ if(r->k && self->equals(k, r->k))
{
- return r2->v;
+ return r->v;
}
return 0x0;
@@ -57,52 +60,54 @@ IOINLINE int CHashKey_hasKey_(CHash *self, void *key)
return CHash_at_(self, key) != NULL;
}
-IOINLINE void CHash_at_put_(CHash *self, void *k, void *v)
+IOINLINE int CHash_at_put_(CHash *self, void *k, void *v)
{
- CHashRecord *r1 = CHash_record1_(self, k);
- CHashRecord *r2;
+ CHashRecord *r;
+
+ r = CHash_record1_(self, k);
- if(!r1->k)
+ if(!r->k)
{
- r1->k = k;
- r1->v = v;
+ r->k = k;
+ r->v = v;
self->keyCount ++;
- return;
+ return 0;
}
- if(self->equals(k, r1->k))
+ if(k == r->k || self->equals(k, r->k))
{
- r1->v = v;
- return;
+ r->v = v;
+ return 0;
}
- r2 = CHash_record2_(self, k);
+ r = CHash_record2_(self, k);
- if(!r2->k)
+ if(!r->k)
{
- r2->k = k;
- r2->v = v;
+ r->k = k;
+ r->v = v;
self->keyCount ++;
- return;
+ return 0;
}
- if(self->equals(k, r2->k))
+ if(k == r->k || self->equals(k, r->k))
{
- r2->v = v;
- return;
+ r->v = v;
+ return 0;
}
+
{
- CHashRecord x;
- x.k = k;
- x.v = v;
- CHash_insert_(self, &x);
+ CHashRecord x;
+ x.k = k;
+ x.v = v;
+ return CHash_insert_(self, &x);
}
}
IOINLINE void CHash_shrinkIfNeeded(CHash *self)
{
- if(self->keyCount < self->size/4)
+ if(self->keyCount < self->size/5)
{
CHash_shrink(self);
}
Oops, something went wrong.

0 comments on commit 2da9861

Please sign in to comment.