Skip to content

Commit

Permalink
added hash
Browse files Browse the repository at this point in the history
  • Loading branch information
goccy committed Jul 23, 2012
1 parent 5ae7c5b commit 5ac39f8
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 26 deletions.
21 changes: 21 additions & 0 deletions auto_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,31 @@ typedef bool int
#define XS_ERROR_TEXT "# [cannot trace] XS MODULE"
#define TRACE_ERROR_TEXT "# [cannot trace] TOO LARGE SIZE"

#define MAX_HASH_SIZE 512

typedef struct _FastSerializer {
char *(*serialize)(struct _FastSerializer *fs, SV *v);
} FastSerializer;

typedef struct _HashList {
const char *key;
const void *value;
struct _HashList *next;
} HashList;

typedef struct _HashMap {
HashList **hash_table;
size_t table_size;
void (*setValue)(struct _HashMap *map, const char *key, const char *value);
const void *(*getValue)(struct _HashMap *map, const char *key);
} HashMap;

typedef struct _String {
unsigned long hash;
char *s;
size_t len;
} String;

typedef struct _VirtualCallStack {
/* save object information */
SV *v; /* current object */
Expand Down
69 changes: 69 additions & 0 deletions hash.c
Original file line number Diff line number Diff line change
@@ -1 +1,70 @@
#include "auto_test.h"

static HashList *new_HashList(const char *key, void *value)
{
HashList *hl = (HashList *)safe_malloc(sizeof(HashList));
hl->key = key;
hl->value = value;
return hl;
}

/**
* An implementation of the djb2 hash function by Dan Bernstein.
*/
static unsigned long HashMap_makeHash(const char *_key, unsigned int len)
{
char *key = (char *)_key;
unsigned long hash = 5381;
while (len--) {
/* hash * 33 + c */
hash = ((hash << 5) + hash) + *key++;
}
return hash;
}

static bool HashMap_existsKey(HashMap *map, const char *key)
{
unsigned long hash = HashMap_makeHash(key, strlen(key)) % map->table_size;
HashList *hl = map->hash_table[hash];
while (hl) {
if (match(hl->key, key)) {
return true;
}
hl = hl->next;
}
return false;
}

static void HashMap_setValue(HashMap *map, const char *key, const char *value)
{
unsigned long hash = HashMap_makeHash(key, strlen(key)) % map->table_size;
HashList *hl = new_HashList(key, (void *)value);
HashList *slot = map->hash_table[hash];
while (slot) {
slot = slot->next;
}
slot = hl;
}

static const void *HashMap_getValue(HashMap *map, const char *key)
{
unsigned long hash = HashMap_makeHash(key, strlen(key)) % map->table_size;
HashList *hl = map->hash_table[hash];
while (hl) {
if (match(hl->key, key)) {
return hl->value;
}
hl = hl->next;
}
return NULL;
}

static HashMap *new_HashMap(size_t slot_size)
{
HashMap *map = (HashMap *)safe_malloc(sizeof(HashMap));
map->hash_table = (HashList **)safe_malloc(sizeof(HashList) * slot_size);
map->table_size = slot_size;
map->setValue = HashMap_setValue;
map->getValue = HashMap_getValue;
return map;
}
71 changes: 45 additions & 26 deletions serializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,33 +45,52 @@ static char buf[32] = {0};
} while (0)
#endif

#define RECURSIVE_CALL_byArray(_a, _i, _size) do { \
if (callstack_idx > MAX_CALLSTACK_SIZE) { \
DO_EXCEPTION(); \
} \
callstack_idx++; \
callstack++; \
callstack->ret_addr = &&L_ARRAY_AFTER; \
callstack->a = _a; \
callstack->i = _i; \
callstack->size = _size; \
goto *jmp_table[L_TOP]; \
L_ARRAY_AFTER:; \
_a = callstack->a; \
_i = callstack->i; \
_size = callstack->size; \
callstack--; \
callstack_idx--; \
} while (0)

#define CALL(array, _vv, _next, _sv, _i, _j, _size, _max_size, TO, FROM) do { \
if (callstack_idx > MAX_CALLSTACK_SIZE) { \
DO_EXCEPTION(); \
} \
callstack_idx++; \
callstack++; \
callstack->ret_addr = &&L_##FROM##AFTER; \
callstack->a = array; \
callstack->hash_v = _vv; \
callstack->next = _next; \
callstack->i = _i; \
callstack->j = _j; \
callstack->size = _size; \
callstack->max_size = _max_size; \
callstack->v = _sv; \
goto *jmp_table[TO]; \
L_##FROM##AFTER: \
_sv = callstack->v; \
array = callstack->a; \
_vv = callstack->hash_v; \
_next = callstack->next; \
_i = callstack->i; \
_j = callstack->j; \
_size = callstack->size; \
_max_size = callstack->max_size; \
callstack--; \
callstack_idx--; \
if (callstack_idx > MAX_CALLSTACK_SIZE) { \
DO_EXCEPTION(); \
} \
callstack_idx++; \
callstack++; \
callstack->ret_addr = &&L_##FROM##AFTER; \
callstack->a = array; \
callstack->hash_v = _vv; \
callstack->next = _next; \
callstack->i = _i; \
callstack->j = _j; \
callstack->size = _size; \
callstack->max_size = _max_size; \
callstack->v = _sv; \
goto *jmp_table[TO]; \
L_##FROM##AFTER: \
_sv = callstack->v; \
array = callstack->a; \
_vv = callstack->hash_v; \
_next = callstack->next; \
_i = callstack->i; \
_j = callstack->j; \
_size = callstack->size; \
_max_size = callstack->max_size; \
callstack--; \
callstack_idx--; \
} while (0)

#define FastSerializer_serializeIntObject(v) do { \
Expand Down

0 comments on commit 5ac39f8

Please sign in to comment.