From cf84b9fa46e53c37af2dcb8532e56ab1e7b72e50 Mon Sep 17 00:00:00 2001 From: Ringo Watanabe Date: Sat, 1 Dec 2018 23:17:10 +0000 Subject: [PATCH] start hashtable --- build/.gitkeep | 0 include/hashtable.h | 15 ++++++++++++ include/internal/crc.h | 11 +++++++++ obj/.gitkeep | 0 src/crc.c | 52 ++++++++++++++++++++++++++++++++++++++++++ src/hash.c | 33 +++++++++++++++++++++++++++ 6 files changed, 111 insertions(+) create mode 100644 build/.gitkeep create mode 100644 include/hashtable.h create mode 100644 include/internal/crc.h create mode 100644 obj/.gitkeep create mode 100644 src/crc.c create mode 100644 src/hash.c diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/include/hashtable.h b/include/hashtable.h new file mode 100644 index 0000000..b9f5401 --- /dev/null +++ b/include/hashtable.h @@ -0,0 +1,15 @@ +#ifndef _HASHTABLE_H + +#define H_DEFAULT_BLOCKSIZE 255 + +struct _h_kvpair_t { + unsigned int crc32; + unsigned char data[]; +}; + +typedef struct { + list_t* back; + size_t keysize; +} hashtable_t; + +#endif /* _HASHTABLE_H */ diff --git a/include/internal/crc.h b/include/internal/crc.h new file mode 100644 index 0000000..8923954 --- /dev/null +++ b/include/internal/crc.h @@ -0,0 +1,11 @@ +#ifndef _CRC_H +#define _CRC_H +#include +#include + +#define _H_CRC_TABLE_SIZE 256 +#define _H_CRC_ITERATIONS 8 + +unsigned long _h_crc32(unsigned long seed, const unsigned char* buffer,unsigned int len); + +#endif /* _CRC_H */ diff --git a/obj/.gitkeep b/obj/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/crc.c b/src/crc.c new file mode 100644 index 0000000..c5e484b --- /dev/null +++ b/src/crc.c @@ -0,0 +1,52 @@ +#include + +static const uint32_t __h_crc_poly = 0xedb88320u; + +static uint32_t __h_crc_table[_H_CRC_TABLE_SIZE]; +static _Atomic volatile int __h_crc_initialised=0; + +static _Atomic volatile int __initialising=0; + +static uint32_t* __h_crc_create_table(uint32_t* table, uint32_t poly) +{ + register int i=0; + for(;i<_H_CRC_TABLE_SIZE;i++) + { + register int j=0; + uint32_t e = (uint32_t)i; + for(;j<_H_CRC_ITERATIONS;j++) + { + if( (e&1) == 1) + e = (e>>1) ^ poly; + else e = e>>1; + } + table[i] = e; + } + return table; +} + +static uint32_t __h_crc_calc(uint32_t* table, uint32_t seed, const unsigned char* buffer, int len) +{ + uint32_t crc= seed; + register int i=0; + for(;i>8) ^ table[(buffer[i] ^ crc) & 0xff]; + } + return crc; +} + +unsigned long _h_crc32(unsigned long seed, const unsigned char* buffer,unsigned int len) +{ + while(__initialising) (void)0; + + if(!__h_crc_initialised) + { + __initialising=1; + __h_crc_create_table(__h_crc_table,__h_crc_poly); + __h_crc_initialised=1; + __initialising=0; + + } + return ~__h_crc_calc(__h_crc_table, (uint32_t) seed, buffer, (int)len); +} diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..fd7dfa2 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +#include + +#include + +int32_t _h_getid(void* key, unsigned long* sum, size_t keysize, size_t blocksize) +{ + return (int32_t)((*sum = _h_crc32(0xffffffffu, key, keysize)) % blocksize); +} + +hashtable_t* h_create(size_t keytype, size_t valuetype, size_t blocksize) +{ + hashtable_t* proto = (hashtable_t*)malloc(sizeof(hashtable_t)); + + proto->back = l_create(sizeof(struct _h_kvpair_t)+keytype+valuetype, blocksize); + proto->keysize = keytype; + + return proto; +} + +void h_add(hashtable_t* hash, void* key, void* value) +{ + unsigned long crc32; + int32_t id = _h_getid(key, &crc32, hash->keysize, hash->back->blocksize); + + //TODO: search through blocks as pages for empty id match + +}