diff --git a/compile.ini b/compile.ini new file mode 100644 index 0000000..b0e26db --- /dev/null +++ b/compile.ini @@ -0,0 +1,8 @@ +include = colla/ +files = colla/*.c + +[windows] +link = ws2_32.lib + +[linux] +link = pthread \ No newline at end of file diff --git a/colla/coropool.c b/deprecated/coropool.c similarity index 95% rename from colla/coropool.c rename to deprecated/coropool.c index 209962f..9d169e4 100644 --- a/colla/coropool.c +++ b/deprecated/coropool.c @@ -1,322 +1,322 @@ -#include "coropool.h" - -#if 0 -#include -#include - -#include "jobpool.h" - -enum { - NUM_JOBS = 50 -}; - -struct _pool_internal_t; - -typedef union job_t { - struct { - mco_coro *co; - struct _pool_internal_t *pool; - }; - struct { - union job_t *next_free; - void *__padding; - }; -} job_t; - -static inline bool _isJobValid(job_t *job) { - return job->pool != NULL; -} - -typedef struct jobchunk_t { - job_t jobs[NUM_JOBS]; - job_t *first_free; - struct jobchunk_t *next; -} jobchunk_t; - -void _chunkInit(jobchunk_t *chunk) { - if (!chunk) return; - chunk->first_free = chunk->jobs; - for (int i = 0; i < (NUM_JOBS - 1); ++i) { - chunk->jobs[i].next_free = chunk->jobs + i + 1; - } -} - -jobchunk_t *_chunkNew(jobchunk_t *prev) { - jobchunk_t *chunk = calloc(1, sizeof(jobchunk_t)); - _chunkInit(chunk); - prev->next = chunk; - return chunk; -} - -job_t *_chunkGetFirstFree(jobchunk_t *chunk) { - job_t *first_free = chunk->first_free; - if (first_free) { - chunk->first_free = first_free->next_free; - } - return first_free; -} - -void _chunkSetFree(jobchunk_t *chunk, job_t *job) { - job->pool = NULL; - job->next_free = chunk->first_free; - chunk->first_free = job; -} - -typedef struct _pool_internal_t { - jobpool_t pool; - jobchunk_t head_chunk; - cmutex_t chunk_mtx; -} _pool_internal_t; - -static int _worker(void *arg); - -coropool_t copoInit(uint32 num) { - _pool_internal_t *pool = calloc(1, sizeof(_pool_internal_t)); - pool->pool = poolInit(num); - _chunkInit(&pool->head_chunk); - pool->chunk_mtx = mtxInit(); - return pool; -} - -void copoFree(coropool_t copo) { - _pool_internal_t *pool = copo; - - poolWait(pool->pool); - poolFree(pool->pool); - - jobchunk_t *chunk = &pool->head_chunk; - while (chunk) { - jobchunk_t *next = chunk->next; - free(chunk); - chunk = next; - } - - mtxFree(pool->chunk_mtx); - free(pool); -} - -bool copoAdd(coropool_t copo, copo_func_f fn) { - mco_desc desc = mco_desc_init(fn, 0); - return copoAddDesc(copo, &desc); -} - -bool copoAddDesc(coropool_t copo, mco_desc *desc) { - mco_coro *co; - mco_create(&co, desc); - return copoAddCo(copo, co); -} - -static bool _copoAddJob(job_t *job) { - //return poolAdd(job->pool->pool, _worker, job); - return true; -} - -static bool _copoRemoveJob(job_t *job) { - _pool_internal_t *pool = job->pool; - // find chunk - jobchunk_t *chunk = &pool->head_chunk; - while (chunk) { - if (chunk->jobs < job && (chunk->jobs + NUM_JOBS) > job) { - break; - } - chunk = chunk->next; - } - if (!chunk) return false; - mtxLock(pool->chunk_mtx); - _chunkSetFree(chunk, job); - mtxUnlock(pool->chunk_mtx); -} - -bool copoAddCo(coropool_t copo, mco_coro *co) { - _pool_internal_t *pool = copo; - - job_t *new_job = NULL; - jobchunk_t *chunk = &pool->head_chunk; - - mtxLock(pool->chunk_mtx); - while (!new_job) { - new_job = _chunkGetFirstFree(chunk); - if (!new_job) { - if (!chunk->next) { - info("adding new chunk"); - chunk->next = _chunkNew(chunk); - } - chunk = chunk->next; - } - } - mtxUnlock(pool->chunk_mtx); - - new_job->co = co; - new_job->pool = pool; - - //return poolAdd(pool->pool, _worker, new_job); - return _copoAddJob(new_job); -} - -void copoWait(coropool_t copo) { - _pool_internal_t *pool = copo; - poolWait(pool->pool); -} - -static int _worker(void *arg) { - job_t *job = arg; - mco_result res = mco_resume(job->co); - if (res != MCO_DEAD) { - _copoAddJob(job); - } - else { - _copoRemoveJob(job); - } - return 0; -} -#endif - -#include - -typedef struct { - vec(mco_coro *) jobs; - uint32 head; - cmutex_t work_mutex; - condvar_t work_cond; - condvar_t working_cond; - int32 working_count; - int32 thread_count; - bool stop; -} _copo_internal_t; - -static mco_coro *_getJob(_copo_internal_t *copo); -static int _copoWorker(void *arg); - -coropool_t copoInit(uint32 num) { - if (!num) num = 2; - - _copo_internal_t *copo = malloc(sizeof(_copo_internal_t)); - *copo = (_copo_internal_t){ - .work_mutex = mtxInit(), - .work_cond = condInit(), - .working_cond = condInit(), - .thread_count = (int32)num - }; - - for (usize i = 0; i < num; ++i) { - thrDetach(thrCreate(_copoWorker, copo)); - } - - return copo; -} - -void copoFree(coropool_t copo_in) { - _copo_internal_t *copo = copo_in; - if (!copo) return; - - mtxLock(copo->work_mutex); - copo->stop = true; - condWakeAll(copo->work_cond); - mtxUnlock(copo->work_mutex); - - copoWait(copo); - - vecFree(copo->jobs); - mtxFree(copo->work_mutex); - condFree(copo->work_cond); - condFree(copo->working_cond); - - free(copo); -} - -bool copoAdd(coropool_t copo, copo_func_f fn) { - mco_desc desc = mco_desc_init(fn, 0); - return copoAddDesc(copo, &desc); -} - -bool copoAddDesc(coropool_t copo, mco_desc *desc) { - mco_coro *co; - mco_create(&co, desc); - return copoAddCo(copo, co); -} - -bool copoAddCo(coropool_t copo_in, mco_coro *co) { - _copo_internal_t *copo = copo_in; - if (!copo) return false; - - mtxLock(copo->work_mutex); - - if (copo->head > vecLen(copo->jobs)) { - vecClear(copo->jobs); - copo->head = 0; - } - - vecAppend(copo->jobs, co); - - condWake(copo->work_cond); - mtxUnlock(copo->work_mutex); - - return true; -} - -void copoWait(coropool_t copo_in) { - _copo_internal_t *copo = copo_in; - if (!copo) return; - - mtxLock(copo->work_mutex); - // while its either - // - working and there's still some threads doing some work - // - not working and there's still some threads exiting - while ((!copo->stop && copo->working_count > 0) || - (copo->stop && copo->thread_count > 0) - ) { - condWait(copo->working_cond, copo->work_mutex); - } - mtxUnlock(copo->work_mutex); -} - -// == PRIVATE FUNCTIONS =================================== - -static mco_coro *_getJob(_copo_internal_t *copo) { - if (copo->head >= vecLen(copo->jobs)) { - copo->head = 0; - } - return copo->jobs[copo->head++]; -} - -static int _copoWorker(void *arg) { - _copo_internal_t *copo = arg; - - while (true) { - mtxLock(copo->work_mutex); - // wait for a new job - while (copo->head >= vecLen(copo->jobs) && !copo->stop) { - condWait(copo->work_cond, copo->work_mutex); - } - - if (copo->stop) { - break; - } - - mco_coro *job = _getJob(copo); - copo->working_count++; - mtxUnlock(copo->work_mutex); - - if (job && mco_status(job) != MCO_DEAD) { - mco_resume(job); - if (mco_status(job) != MCO_DEAD) { - copoAddCo(copo, job); - } - } - - mtxLock(copo->work_mutex); - copo->working_count--; - if (!copo->stop && - copo->working_count == 0 && - copo->head == vecLen(copo->jobs) - ) { - condWake(copo->working_cond); - } - mtxUnlock(copo->work_mutex); - } - - copo->thread_count--; - condWake(copo->working_cond); - mtxUnlock(copo->work_mutex); - return 0; +#include "coropool.h" + +#if 0 +#include +#include + +#include "jobpool.h" + +enum { + NUM_JOBS = 50 +}; + +struct _pool_internal_t; + +typedef union job_t { + struct { + mco_coro *co; + struct _pool_internal_t *pool; + }; + struct { + union job_t *next_free; + void *__padding; + }; +} job_t; + +static inline bool _isJobValid(job_t *job) { + return job->pool != NULL; +} + +typedef struct jobchunk_t { + job_t jobs[NUM_JOBS]; + job_t *first_free; + struct jobchunk_t *next; +} jobchunk_t; + +void _chunkInit(jobchunk_t *chunk) { + if (!chunk) return; + chunk->first_free = chunk->jobs; + for (int i = 0; i < (NUM_JOBS - 1); ++i) { + chunk->jobs[i].next_free = chunk->jobs + i + 1; + } +} + +jobchunk_t *_chunkNew(jobchunk_t *prev) { + jobchunk_t *chunk = calloc(1, sizeof(jobchunk_t)); + _chunkInit(chunk); + prev->next = chunk; + return chunk; +} + +job_t *_chunkGetFirstFree(jobchunk_t *chunk) { + job_t *first_free = chunk->first_free; + if (first_free) { + chunk->first_free = first_free->next_free; + } + return first_free; +} + +void _chunkSetFree(jobchunk_t *chunk, job_t *job) { + job->pool = NULL; + job->next_free = chunk->first_free; + chunk->first_free = job; +} + +typedef struct _pool_internal_t { + jobpool_t pool; + jobchunk_t head_chunk; + cmutex_t chunk_mtx; +} _pool_internal_t; + +static int _worker(void *arg); + +coropool_t copoInit(uint32 num) { + _pool_internal_t *pool = calloc(1, sizeof(_pool_internal_t)); + pool->pool = poolInit(num); + _chunkInit(&pool->head_chunk); + pool->chunk_mtx = mtxInit(); + return pool; +} + +void copoFree(coropool_t copo) { + _pool_internal_t *pool = copo; + + poolWait(pool->pool); + poolFree(pool->pool); + + jobchunk_t *chunk = &pool->head_chunk; + while (chunk) { + jobchunk_t *next = chunk->next; + free(chunk); + chunk = next; + } + + mtxFree(pool->chunk_mtx); + free(pool); +} + +bool copoAdd(coropool_t copo, copo_func_f fn) { + mco_desc desc = mco_desc_init(fn, 0); + return copoAddDesc(copo, &desc); +} + +bool copoAddDesc(coropool_t copo, mco_desc *desc) { + mco_coro *co; + mco_create(&co, desc); + return copoAddCo(copo, co); +} + +static bool _copoAddJob(job_t *job) { + //return poolAdd(job->pool->pool, _worker, job); + return true; +} + +static bool _copoRemoveJob(job_t *job) { + _pool_internal_t *pool = job->pool; + // find chunk + jobchunk_t *chunk = &pool->head_chunk; + while (chunk) { + if (chunk->jobs < job && (chunk->jobs + NUM_JOBS) > job) { + break; + } + chunk = chunk->next; + } + if (!chunk) return false; + mtxLock(pool->chunk_mtx); + _chunkSetFree(chunk, job); + mtxUnlock(pool->chunk_mtx); +} + +bool copoAddCo(coropool_t copo, mco_coro *co) { + _pool_internal_t *pool = copo; + + job_t *new_job = NULL; + jobchunk_t *chunk = &pool->head_chunk; + + mtxLock(pool->chunk_mtx); + while (!new_job) { + new_job = _chunkGetFirstFree(chunk); + if (!new_job) { + if (!chunk->next) { + info("adding new chunk"); + chunk->next = _chunkNew(chunk); + } + chunk = chunk->next; + } + } + mtxUnlock(pool->chunk_mtx); + + new_job->co = co; + new_job->pool = pool; + + //return poolAdd(pool->pool, _worker, new_job); + return _copoAddJob(new_job); +} + +void copoWait(coropool_t copo) { + _pool_internal_t *pool = copo; + poolWait(pool->pool); +} + +static int _worker(void *arg) { + job_t *job = arg; + mco_result res = mco_resume(job->co); + if (res != MCO_DEAD) { + _copoAddJob(job); + } + else { + _copoRemoveJob(job); + } + return 0; +} +#endif + +#include + +typedef struct { + vec(mco_coro *) jobs; + uint32 head; + cmutex_t work_mutex; + condvar_t work_cond; + condvar_t working_cond; + int32 working_count; + int32 thread_count; + bool stop; +} _copo_internal_t; + +static mco_coro *_getJob(_copo_internal_t *copo); +static int _copoWorker(void *arg); + +coropool_t copoInit(uint32 num) { + if (!num) num = 2; + + _copo_internal_t *copo = malloc(sizeof(_copo_internal_t)); + *copo = (_copo_internal_t){ + .work_mutex = mtxInit(), + .work_cond = condInit(), + .working_cond = condInit(), + .thread_count = (int32)num + }; + + for (usize i = 0; i < num; ++i) { + thrDetach(thrCreate(_copoWorker, copo)); + } + + return copo; +} + +void copoFree(coropool_t copo_in) { + _copo_internal_t *copo = copo_in; + if (!copo) return; + + mtxLock(copo->work_mutex); + copo->stop = true; + condWakeAll(copo->work_cond); + mtxUnlock(copo->work_mutex); + + copoWait(copo); + + vecFree(copo->jobs); + mtxFree(copo->work_mutex); + condFree(copo->work_cond); + condFree(copo->working_cond); + + free(copo); +} + +bool copoAdd(coropool_t copo, copo_func_f fn) { + mco_desc desc = mco_desc_init(fn, 0); + return copoAddDesc(copo, &desc); +} + +bool copoAddDesc(coropool_t copo, mco_desc *desc) { + mco_coro *co; + mco_create(&co, desc); + return copoAddCo(copo, co); +} + +bool copoAddCo(coropool_t copo_in, mco_coro *co) { + _copo_internal_t *copo = copo_in; + if (!copo) return false; + + mtxLock(copo->work_mutex); + + if (copo->head > vecLen(copo->jobs)) { + vecClear(copo->jobs); + copo->head = 0; + } + + vecAppend(copo->jobs, co); + + condWake(copo->work_cond); + mtxUnlock(copo->work_mutex); + + return true; +} + +void copoWait(coropool_t copo_in) { + _copo_internal_t *copo = copo_in; + if (!copo) return; + + mtxLock(copo->work_mutex); + // while its either + // - working and there's still some threads doing some work + // - not working and there's still some threads exiting + while ((!copo->stop && copo->working_count > 0) || + (copo->stop && copo->thread_count > 0) + ) { + condWait(copo->working_cond, copo->work_mutex); + } + mtxUnlock(copo->work_mutex); +} + +// == PRIVATE FUNCTIONS =================================== + +static mco_coro *_getJob(_copo_internal_t *copo) { + if (copo->head >= vecLen(copo->jobs)) { + copo->head = 0; + } + return copo->jobs[copo->head++]; +} + +static int _copoWorker(void *arg) { + _copo_internal_t *copo = arg; + + while (true) { + mtxLock(copo->work_mutex); + // wait for a new job + while (copo->head >= vecLen(copo->jobs) && !copo->stop) { + condWait(copo->work_cond, copo->work_mutex); + } + + if (copo->stop) { + break; + } + + mco_coro *job = _getJob(copo); + copo->working_count++; + mtxUnlock(copo->work_mutex); + + if (job && mco_status(job) != MCO_DEAD) { + mco_resume(job); + if (mco_status(job) != MCO_DEAD) { + copoAddCo(copo, job); + } + } + + mtxLock(copo->work_mutex); + copo->working_count--; + if (!copo->stop && + copo->working_count == 0 && + copo->head == vecLen(copo->jobs) + ) { + condWake(copo->working_cond); + } + mtxUnlock(copo->work_mutex); + } + + copo->thread_count--; + condWake(copo->working_cond); + mtxUnlock(copo->work_mutex); + return 0; } \ No newline at end of file diff --git a/colla/coropool.h b/deprecated/coropool.h similarity index 95% rename from colla/coropool.h rename to deprecated/coropool.h index 14cf370..2bbdfc5 100644 --- a/colla/coropool.h +++ b/deprecated/coropool.h @@ -1,17 +1,17 @@ -#pragma once - -#include -#include - -#include "minicoro.h" - -typedef void *coropool_t; -typedef void (*copo_func_f)(mco_coro *co); - -coropool_t copoInit(uint32 num); -void copoFree(coropool_t copo); - -bool copoAdd(coropool_t copo, copo_func_f fn); -bool copoAddDesc(coropool_t copo, mco_desc *desc); -bool copoAddCo(coropool_t copo, mco_coro *co); -void copoWait(coropool_t copo); +#pragma once + +#include +#include + +#include "minicoro.h" + +typedef void *coropool_t; +typedef void (*copo_func_f)(mco_coro *co); + +coropool_t copoInit(uint32 num); +void copoFree(coropool_t copo); + +bool copoAdd(coropool_t copo, copo_func_f fn); +bool copoAddDesc(coropool_t copo, mco_desc *desc); +bool copoAddCo(coropool_t copo, mco_coro *co); +void copoWait(coropool_t copo); diff --git a/colla/hashmap.c b/deprecated/hashmap.c similarity index 95% rename from colla/hashmap.c rename to deprecated/hashmap.c index bf47e1b..0bfff05 100644 --- a/colla/hashmap.c +++ b/deprecated/hashmap.c @@ -1,130 +1,130 @@ -#include "hashmap.h" - -#include - -static uint64 hash_seed = 0; - -hashmap_t hmInit(usize initial_cap) { - hashmap_t map = {0}; - if (!initial_cap) initial_cap = 512; - vecReserve(map.nodes, initial_cap); - memset(map.nodes, 0, sizeof(hashnode_t) * initial_cap); - return map; -} - -void hmFree(hashmap_t map) { - vecFree(map.nodes); -} - -void hmSet(hashmap_t *map, uint64 hash, uint64 index) { - uint32 hm_index = hash % vecCap(map->nodes); - - while (map->nodes[hm_index].hash) { - hashnode_t *node = &map->nodes[hm_index]; - if (node->hash == hash) { - node->index = index; - return; - } - hm_index = (hm_index + 1) % vecCap(map->nodes); - } - - map->nodes[hm_index].hash = hash; - map->nodes[hm_index].index = index; - _veclen(map->nodes)++; - - float load_factor = (float)vecLen(map->nodes) / (float)vecCap(map->nodes); - if (load_factor > 0.75f) { - uint32 old_cap = vecCap(map->nodes); - vecReserve(map->nodes, old_cap); - for (usize i = old_cap; i < vecCap(map->nodes); ++i) { - map->nodes[i].hash = 0; - map->nodes[i].index = 0; - } - } -} - -uint64 hmGet(hashmap_t map, uint64 hash) { - uint32 hm_index = hash % vecCap(map.nodes); - - do { - hashnode_t *node = &map.nodes[hm_index]; - if (node->hash == hash) { - return node->index; - } - hm_index = (hm_index + 1) % vecCap(map.nodes); - } while (map.nodes[hm_index].hash); - - return 0; -} - -void hmDelete(hashmap_t *map, uint64 hash) { - uint32 hm_index = hash % vecCap(map->nodes); - - do { - hashnode_t *node = &map->nodes[hm_index]; - if (node->hash == hash) { - node->hash = 0; - node->index = 0; - break; - } - hm_index = (hm_index + 1) % vecCap(map->nodes); - } while (map->nodes[hm_index].hash); - - if(vecLen(map->nodes)) _veclen(map->nodes)--; -} - -void hashSetSeed(uint64 new_seed) { - hash_seed = new_seed; -} - -uint64 hash(const void *ptr, usize len) { - const uint64 m = 0xC6A4A7935BD1E995LLU; - const int r = 47; - - uint64 h = hash_seed ^ (len * m); - - const uint64 *data = (const uint64 *)ptr; - const uint64 *end = (len >> 3) + data; - - while (data != end) { - uint64 k = *data++; - - k *= m; - k ^= k >> r; - k *= m; - - h ^= k; - h *= m; - } - - const unsigned char * data2 = (const unsigned char *)data; - - switch(len & 7) { - case 7: h ^= (uint64_t)(data2[6]) << 48; - case 6: h ^= (uint64_t)(data2[5]) << 40; - case 5: h ^= (uint64_t)(data2[4]) << 32; - case 4: h ^= (uint64_t)(data2[3]) << 24; - case 3: h ^= (uint64_t)(data2[2]) << 16; - case 2: h ^= (uint64_t)(data2[1]) << 8; - case 1: h ^= (uint64_t)(data2[0]); - h *= m; - }; - - h ^= h >> r; - h *= m; - h ^= h >> r; - - return h; -} - -uint64 hashStr(str_t str) { - return hash(str.buf, str.len); -} - -uint64 hashView(strview_t view) { - return hash(view.buf, view.len); -} - -uint64 hashCStr(const char *cstr) { - return hash(cstr, strlen(cstr)); -} +#include "hashmap.h" + +#include + +static uint64 hash_seed = 0; + +hashmap_t hmInit(usize initial_cap) { + hashmap_t map = {0}; + if (!initial_cap) initial_cap = 512; + vecReserve(map.nodes, initial_cap); + memset(map.nodes, 0, sizeof(hashnode_t) * initial_cap); + return map; +} + +void hmFree(hashmap_t map) { + vecFree(map.nodes); +} + +void hmSet(hashmap_t *map, uint64 hash, uint64 index) { + uint32 hm_index = hash % vecCap(map->nodes); + + while (map->nodes[hm_index].hash) { + hashnode_t *node = &map->nodes[hm_index]; + if (node->hash == hash) { + node->index = index; + return; + } + hm_index = (hm_index + 1) % vecCap(map->nodes); + } + + map->nodes[hm_index].hash = hash; + map->nodes[hm_index].index = index; + _veclen(map->nodes)++; + + float load_factor = (float)vecLen(map->nodes) / (float)vecCap(map->nodes); + if (load_factor > 0.75f) { + uint32 old_cap = vecCap(map->nodes); + vecReserve(map->nodes, old_cap); + for (usize i = old_cap; i < vecCap(map->nodes); ++i) { + map->nodes[i].hash = 0; + map->nodes[i].index = 0; + } + } +} + +uint64 hmGet(hashmap_t map, uint64 hash) { + uint32 hm_index = hash % vecCap(map.nodes); + + do { + hashnode_t *node = &map.nodes[hm_index]; + if (node->hash == hash) { + return node->index; + } + hm_index = (hm_index + 1) % vecCap(map.nodes); + } while (map.nodes[hm_index].hash); + + return 0; +} + +void hmDelete(hashmap_t *map, uint64 hash) { + uint32 hm_index = hash % vecCap(map->nodes); + + do { + hashnode_t *node = &map->nodes[hm_index]; + if (node->hash == hash) { + node->hash = 0; + node->index = 0; + break; + } + hm_index = (hm_index + 1) % vecCap(map->nodes); + } while (map->nodes[hm_index].hash); + + if(vecLen(map->nodes)) _veclen(map->nodes)--; +} + +void hashSetSeed(uint64 new_seed) { + hash_seed = new_seed; +} + +uint64 hash(const void *ptr, usize len) { + const uint64 m = 0xC6A4A7935BD1E995LLU; + const int r = 47; + + uint64 h = hash_seed ^ (len * m); + + const uint64 *data = (const uint64 *)ptr; + const uint64 *end = (len >> 3) + data; + + while (data != end) { + uint64 k = *data++; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + } + + const unsigned char * data2 = (const unsigned char *)data; + + switch(len & 7) { + case 7: h ^= (uint64_t)(data2[6]) << 48; + case 6: h ^= (uint64_t)(data2[5]) << 40; + case 5: h ^= (uint64_t)(data2[4]) << 32; + case 4: h ^= (uint64_t)(data2[3]) << 24; + case 3: h ^= (uint64_t)(data2[2]) << 16; + case 2: h ^= (uint64_t)(data2[1]) << 8; + case 1: h ^= (uint64_t)(data2[0]); + h *= m; + }; + + h ^= h >> r; + h *= m; + h ^= h >> r; + + return h; +} + +uint64 hashStr(str_t str) { + return hash(str.buf, str.len); +} + +uint64 hashView(strview_t view) { + return hash(view.buf, view.len); +} + +uint64 hashCStr(const char *cstr) { + return hash(cstr, strlen(cstr)); +} diff --git a/colla/hashmap.h b/deprecated/hashmap.h similarity index 96% rename from colla/hashmap.h rename to deprecated/hashmap.h index 1efdd37..1808970 100644 --- a/colla/hashmap.h +++ b/deprecated/hashmap.h @@ -1,49 +1,49 @@ -#pragma once - -#include "collatypes.h" -#include "vec.h" -#include "str.h" - -/* -Example usage: -hashSetSeed(time(NULL)); -vec(const char *) strings = NULL; -hashmap_t map = hmInit(32); - -// mapGet returns 0 in case it doesn't find anything, this way we don't need -// to check its return value -vecAppend(strings, "nil"); - -hmSet(&map, hashCStr("english"), vecAppend(strings, "hello")); -hmSet(&map, hashCStr("french"), vecAppend(strings, "bonjour")); -hmSet(&map, hashCStr("italian"), vecAppend(strings, "ciao")); - -printf("english: %s\n", strings[hmGet(map, hashCStr("english"))]); -printf("french: %s\n", strings[hmGet(map, hashCStr("french"))]); -printf("italian: %s\n", strings[hmGet(map, hashCStr("italian"))]); - -mapFree(map); -vecFree(strings); -*/ - -typedef struct { - uint64 hash; - uint64 index; -} hashnode_t; - -typedef struct { - vec(hashnode_t) nodes; -} hashmap_t; - -hashmap_t hmInit(usize initial_cap); -void hmFree(hashmap_t map); - -void hmSet(hashmap_t *map, uint64 hash, uint64 index); -uint64 hmGet(hashmap_t map, uint64 hash); -void hmDelete(hashmap_t *map, uint64 hash); - -void hashSetSeed(uint64 new_seed); -uint64 hash(const void *data, usize len); -uint64 hashStr(str_t str); -uint64 hashView(strview_t view); -uint64 hashCStr(const char *cstr); +#pragma once + +#include "collatypes.h" +#include "vec.h" +#include "str.h" + +/* +Example usage: +hashSetSeed(time(NULL)); +vec(const char *) strings = NULL; +hashmap_t map = hmInit(32); + +// mapGet returns 0 in case it doesn't find anything, this way we don't need +// to check its return value +vecAppend(strings, "nil"); + +hmSet(&map, hashCStr("english"), vecAppend(strings, "hello")); +hmSet(&map, hashCStr("french"), vecAppend(strings, "bonjour")); +hmSet(&map, hashCStr("italian"), vecAppend(strings, "ciao")); + +printf("english: %s\n", strings[hmGet(map, hashCStr("english"))]); +printf("french: %s\n", strings[hmGet(map, hashCStr("french"))]); +printf("italian: %s\n", strings[hmGet(map, hashCStr("italian"))]); + +mapFree(map); +vecFree(strings); +*/ + +typedef struct { + uint64 hash; + uint64 index; +} hashnode_t; + +typedef struct { + vec(hashnode_t) nodes; +} hashmap_t; + +hashmap_t hmInit(usize initial_cap); +void hmFree(hashmap_t map); + +void hmSet(hashmap_t *map, uint64 hash, uint64 index); +uint64 hmGet(hashmap_t map, uint64 hash); +void hmDelete(hashmap_t *map, uint64 hash); + +void hashSetSeed(uint64 new_seed); +uint64 hash(const void *data, usize len); +uint64 hashStr(str_t str); +uint64 hashView(strview_t view); +uint64 hashCStr(const char *cstr);