{"id":33622052,"url":"https://github.com/paulborile/clibs","last_synced_at":"2026-01-12T15:32:55.897Z","repository":{"id":74110018,"uuid":"80715437","full_name":"paulborile/clibs","owner":"paulborile","description":"Simple, fast, threadsafe C language hashtable, LRU map, Thread pool, go like channel, vector","archived":false,"fork":false,"pushed_at":"2025-10-07T15:35:03.000Z","size":12203,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-12-10T07:28:36.306Z","etag":null,"topics":["avl","channel","hashtable","lru","threadpool","vector"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/paulborile.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-02-02T10:38:53.000Z","updated_at":"2025-10-07T15:35:09.000Z","dependencies_parsed_at":"2023-09-23T02:48:50.927Z","dependency_job_id":"93b097e3-2311-4dde-9c7e-86f244d75c1f","html_url":"https://github.com/paulborile/clibs","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/paulborile/clibs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulborile%2Fclibs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulborile%2Fclibs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulborile%2Fclibs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulborile%2Fclibs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paulborile","download_url":"https://codeload.github.com/paulborile/clibs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paulborile%2Fclibs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28340950,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avl","channel","hashtable","lru","threadpool","vector"],"created_at":"2025-12-01T17:00:22.686Z","updated_at":"2026-01-12T15:32:55.885Z","avatar_url":"https://github.com/paulborile.png","language":"C++","funding_links":[],"categories":["Data Structures"],"sub_categories":[],"readme":"![CLIBS](https://github.com/paulborile/clibs/actions/workflows/c-cpp.yml/badge.svg)\n# clibs - collections in C\n\nThis repo contains standard components used to develop faster in C. All libraries try to apply the same concepts :\n- multi-instantiable : a create function allocates-returns/sets-a-preallocated handle type to be used to refer to that instance of the object\n- information hiding : user data is threated as a payload and payloads may of type STRING, VOIDP or FIXEDLEN (*_DATALEN_STRING, *_DATALEN_VOIDP or size)\n- thread safeness : when this applies the collection methods (excluding create/destroy) can be used safely by different threads \n\nAvailable components :\n\n- fh : a fast, bucketed, multi-thread optimized open hashtable\n- channel : a golang inspired channel object with multi-thread aware blocking get operations\n- vector : a simple dynamic vector\n- lru : lru cache based on fh\n\n\n## C Hashtable\n\nlibfh : fast hashtable, advanced multi threading support, key is only string and is always copied inside \n(unless FH_SETATTR_DONTCOPYKEY is set), opaque data is allocated and copied inside hash and can be string \n(datalen = FH_DATALEN_STRING), fixed lenght (datalen = sizeof data) or datalen = FH_DATALEN_VOIDP just \ncopies void pointer.\n- hashfunction is wyhash (from 0.10.0) but you can set your hash function in fh_create().\n- 1.0.0 introduces a bucketed version (inspired heavily by go map) which increases performance by 40%.\n- 1.1.0 uses rwlocks for better contention.\n- 1.2.0 rwlocks enabled by usint fh_setattr(.., FH_SETATTR_USERWLOCKS, 1)\n\nSample code :\n\n```\n#include \u003cstdio.h\u003e\n#include \u003cpthread.h\u003e\n#include \"fh.h\"\n\nint main(int argc, char **argv)\n{\n    fh_t *f = fh_create(1000, FH_DATALEN_STRING, NULL); // opaque data is string, using builtin hash function\n    // if keys are preallocated and you can avoid creating a copy of the key in hashtable\n    // for faster/less memory fh_insert\n    // fh_setattr(f, FH_SETATTR_DONTCOPYKEY, 1);\n    // if massively(many threads) reading from the hashtable more than updating it use rwlocks\n    // fh_setattr(fhash, FH_SETATTR_USERWLOCKS, 1);\n\n    int err = fh_insert(f, \"thekey\", \"value\");\n\n    char str[64];\n    err = fh_search(f, \"thekey\", str, 64); // search will copy out data\n\n    printf(\"value for the key : %s\\n\", str);\n\n    // to get only the pointer to data\n    char *value = fh_get(f, \"thekey\", \u0026err);\n\n    printf(\"value for the key : %s\\n\", value);\n\n    fh_del(f, \"thekey\");\n\n    fh_destroy(f);\n}\n\n```\nTo compile :\n\n```\ncd libfh ; make -f libfh.mk releaseclean releaselinux debugclean debuglinux\ncd test\nmake -f libfh-test.mk testclean testlinux testrun\n```\n\nPerformance : run on Intel Core i7-4710HQ CPU @ 2.50GHz\n\n```\n------------ Testing fixed size opaque data hashtable\nhash real size 65536\nAverage insert time in nanosecs : 230.40\nhash elements 30000\nhash collision 6023\nsearching ..\nAverage access time in nanosecs : 154.05\ndeleting ..\nhash elements 0\n------------ Testing string opaque data\nhash real size 65536\nAverage insert time in nanosecs : 155.98\nhash elements 30000\nhash collision 6005\nsearching ..\nAverage access time in nanosecs : 111.69\ndeleting ..\nhash elements 0\n------------ Testing void pointer opaque data\nhash real size 65536\nAverage insert time in nanosecs : 147.02\nhash elements 30000\nhash collision 6005\nsearching ..\nAverage access time in nanosecs : 81.54\ndeleting ..\nhash elements 0\n------------ end of tests\n```\n\n## C Thread pool\n\nlibthp : simple thread pool library in C. Easy to use :\n\n```\n    ...\n    // create thread pool with 10 running threads\n    thp_h *t = thp_create(NULL, 10, \u0026err);\n\n    // add some work to thread\n    thp_add(t, user_function, (void *) user_function_param);\n\n    // wait that all jobs terminate\n    thp_wait(t);\n\n    thp_destroy(t);\n\n```\n\nTo compile (you will also need libchannel) :\n\n```\nmake -f libthp.mk releaseclean releaselinux debugclean debuglinux\ncd test\nmake -f libthp-test.mk testclean testlinux testrun\n\n```\n\n## C Channel (Go inspired) - a FIFO queue with fixed size/unlimited length with blocking/non-blocking get and put\n\nConnect producer / consumer threads with a thread safe data channel\n\n```\n    ...\n    ch_h *ch = NULL;\n    pthread_t th_writer, th_reader;\n    int pthread_ret = 0, retval;\n    void *th_ret;\n\n    ch_h *ch = ch_create(NULL, CH_DATALEN_STRING);\n    \n    // set non blocking mode\n    // retval = ch_setattr(ch, CH_BLOCKING_MODE, CH_ATTR_NON_BLOCKING_GETPUT);\n\n    // set fixed size\n    // retval = ch_setattr(ch, CH_FIXED_SIZE, 1000); ch_put will block if queue is full\n\n    pthread_ret = pthread_create(\u0026th_reader, NULL, \u0026thread_reader, (void *)ch);\n\n    for (i = 0; i \u003c MSGS_SENT; i++)\n    {\n        char text[20];\n\n        sprintf(text, \"text %d\", i);\n        retval = ch_put(ch, text);\n    }\n    ch_put(ch, CH_ENDOFTRANSMISSION);\n    pthread_join(th_reader, \u0026th_ret);\n    retval = ch_destroy(ch);\n    ...\n\nstatic void *thread_reader(void *ch)\n{\n    char text[50];\n    int eot = 0;\n    while (eot != CH_GET_ENDOFTRANSMISSION)\n    {\n        eot = ch_get(ch, text);\n\n        if (eot \u003c 0 \u0026\u0026 eot != CH_GET_ENDOFTRANSMISSION)\n        {\n            // error\n        }\n    }\n    return NULL;\n}\n\n```\n\n```\nmake -f libch.mk releaseclean releaselinux debugclean debuglinux\ncd test\nmake -f libch-test.mk testclean testlinux testrun\n\n```\n\n## C LRU cache\n\nliblru : is a fast, thread safe Least Recently Used cache, basically a fixed size hashtable that discards least used items first. It is based on libfh (Fast Hash, se below) and on an internal lru list that keeps items ordered by use. Keys are always strings and payloads are void * so you will have to allocate everything outside and take care of freeing as well when/if needed.\nSample code :\n\n```\n\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#include \"lru.h\"\n\nint main(int argc, char **argv)\n{\n    char *str;\n    // create the lru\n    lru_t *l = lru_create(1000);\n\n    // check if an entry exists\n\n    if ( lru_check(l, \"this is the key\", (void *) \u0026str) != LRU_OK)\n    {\n        // not found, add it\n        lru_add(l, \"this is the key\", \"key payload\");\n    }\n\n    // destroy\n\n    lru_destroy(l);\n\n    exit(1);\n}\n\n```\n\nTo compile the liblru and test it :\n\n```\ncd liblru ; make -f liblru.mk releaseclean releaselinux debugclean debuglinux\ncd test ; make ; ./lrutest \u003clrusize\u003e\n\n```\n\nPerformance : run on Intel Core i7-4710HQ CPU @ 2.50GHz :\n\n```\n$ ./lrutest 100000\nAverage lru_check time in nanosecs : 295.28\nAverage lru_add time in nanosecs : 156.32\n\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulborile%2Fclibs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaulborile%2Fclibs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaulborile%2Fclibs/lists"}