[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6603":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":25,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":35,"readmeContent":36,"aiSummary":37,"trendingCount":16,"starSnapshotCount":16,"syncStatus":38,"lastSyncTime":39,"discoverSource":40},6603,"klib","attractivechaos\u002Fklib","attractivechaos","A standalone and lightweight C library","http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F",null,"C",4677,588,187,49,0,1,3,22,5,30.31,"MIT License",false,"master",true,[27,28,29,30,31,32,33,34],"algorithm","avl-tree","b-tree","c","generic","hashtable","library","sort","2026-06-12 02:01:27","# Klib: a Generic Library in C\n\n## \u003Ca name=\"overview\">\u003C\u002Fa>Overview\n\nKlib is a standalone and lightweight C library distributed under [MIT\u002FX11\nlicense][1]. Most components are independent of external libraries, except the\nstandard C library, and independent of each other. To use a component of this\nlibrary, you only need to copy a couple of files to your source code tree\nwithout worrying about library dependencies.\n\nKlib strives for efficiency and a small memory footprint. Some components, such\nas khash.h, kbtree.h, ksort.h and kvec.h, are among the most efficient\nimplementations of similar algorithms or data structures in all programming\nlanguages, in terms of both speed and memory use.\n\nA new documentation is available [here](http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F)\nwhich includes most information in this README file.\n\n#### Common components\n\n* [khash.h][khash]: generic [hash table][2] with open addressing.\n* [kbtree.h][kbtree]: generic search tree based on [B-tree][3].\n* [kavl.h][kavl]: generic intrusive [AVL tree][wiki-avl].\n* [ksort.h][ksort]: generic sort, including [introsort][4], [merge sort][5], [heap sort][6], [comb sort][7], [Knuth shuffle][8] and the [k-small][9] algorithm.\n* [kseq.h][kseq]: generic stream buffer and a [FASTA][10]\u002F[FASTQ][11] format parser.\n* kvec.h: generic dynamic array.\n* klist.h: generic single-linked list and [memory pool][12].\n* kstring.{h,c}: basic string library.\n* kmath.{h,c}: numerical routines including [MT19937-64][13] [pseudorandom generator][14], basic [nonlinear programming][15] and a few special math functions.\n* [ketopt.h][ketopt]: portable command-line argument parser with getopt\\_long-like API.\n\n#### Components for more specific use cases\n\n* ksa.c: constructing [suffix arrays][16] for strings with multiple sentinels, based on a revised [SAIS algorithm][17].\n* knetfile.{h,c}: random access to remote files on HTTP or FTP.\n* kopen.c: smart stream opening.\n* khmm.{h,c}: basic [HMM][18] library.\n* ksw.(h,c}: Striped [Smith-Waterman algorithm][19].\n* knhx.{h,c}: [Newick tree format][20] parser.\n\n\n## \u003Ca name=\"methodology\">\u003C\u002Fa>Methodology\n\nFor the implementation of generic [containers][21], klib extensively uses C\nmacros. To use these data structures, we usually need to instantiate methods by\nexpanding a long macro. This makes the source code look unusual or even ugly\nand adds difficulty to debugging. Unfortunately, for efficient generic\nprogramming in C that lacks [template][22], using macros is the only\nsolution. Only with macros, we can write a generic container which, once\ninstantiated, compete with a type-specific container in efficiency. Some\ngeneric libraries in C, such as [Glib][23], use the `void*` type to implement\ncontainers. These implementations are usually slower and use more memory than\nklib (see [this benchmark][31]).\n\nTo effectively use klib, it is important to understand how it achieves generic\nprogramming. We will use the hash table library as an example:\n\n    #include \"khash.h\"\n    KHASH_MAP_INIT_INT(m32, char)        \u002F\u002F instantiate structs and methods\n    int main() {\n        int ret, is_missing;\n        khint_t k;\n        khash_t(m32) *h = kh_init(m32);  \u002F\u002F allocate a hash table\n        k = kh_put(m32, h, 5, &ret);     \u002F\u002F insert a key to the hash table\n        if (!ret) kh_del(m32, h, k);\n        kh_value(h, k) = 10;             \u002F\u002F set the value\n        k = kh_get(m32, h, 10);          \u002F\u002F query the hash table\n        is_missing = (k == kh_end(h));   \u002F\u002F test if the key is present\n        k = kh_get(m32, h, 5);\n        kh_del(m32, h, k);               \u002F\u002F remove a key-value pair\n        for (k = kh_begin(h); k != kh_end(h); ++k)  \u002F\u002F traverse\n            if (kh_exist(h, k))          \u002F\u002F test if a bucket contains data\n    \t\t\tkh_value(h, k) = 1;\n        kh_destroy(m32, h);              \u002F\u002F deallocate the hash table\n        return 0;\n    }\n\nIn this example, the second line instantiates a hash table with `unsigned` as\nthe key type and `char` as the value type. `m32` names such a type of hash table.\nAll types and functions associated with this name are macros, which will be\nexplained later. Macro `kh_init()` initiates a hash table and `kh_destroy()`\nfrees it. `kh_put()` inserts a key and returns the iterator (or the position)\nin the hash table. `kh_get()` and `kh_del()` get a key and delete an element,\nrespectively. Macro `kh_exist()` tests if an iterator (or a position) is filled\nwith data.\n\nAn immediate question is this piece of code does not look like a valid C\nprogram (e.g. lacking semicolon, assignment to an _apparent_ function call and\n_apparent_ undefined `m32` 'variable'). To understand why the code is correct,\nlet's go a bit further into the source code of `khash.h`, whose skeleton looks\nlike:\n\n    #define KHASH_INIT(name, SCOPE, key_t, val_t, is_map, _hashf, _hasheq) \\\n      typedef struct { \\\n        int n_buckets, size, n_occupied, upper_bound; \\\n        unsigned *flags; \\\n        key_t *keys; \\\n        val_t *vals; \\\n      } kh_##name##_t; \\\n      SCOPE inline kh_##name##_t *init_##name() { \\\n        return (kh_##name##_t*)calloc(1, sizeof(kh_##name##_t)); \\\n      } \\\n      SCOPE inline int get_##name(kh_##name##_t *h, key_t k) \\\n      ... \\\n      SCOPE inline void destroy_##name(kh_##name##_t *h) { \\\n        if (h) { \\\n          free(h->keys); free(h->flags); free(h->vals); free(h); \\\n        } \\\n      }\n    \n    #define _int_hf(key) (unsigned)(key)\n    #define _int_heq(a, b) (a == b)\n    #define khash_t(name) kh_##name##_t\n    #define kh_value(h, k) ((h)->vals[k])\n    #define kh_begin(h, k) 0\n    #define kh_end(h) ((h)->n_buckets)\n    #define kh_init(name) init_##name()\n    #define kh_get(name, h, k) get_##name(h, k)\n    #define kh_destroy(name, h) destroy_##name(h)\n    ...\n    #define KHASH_MAP_INIT_INT(name, val_t) \\\n    \tKHASH_INIT(name, static, unsigned, val_t, is_map, _int_hf, _int_heq)\n\n`KHASH_INIT()` is a huge macro defining all the structs and methods. When this\nmacro is called, all the code inside it will be inserted by the [C\npreprocess][37] to the place where it is called. If the macro is called\nmultiple times, multiple copies of the code will be inserted. To avoid naming\nconflict of hash tables with different key-value types, the library uses [token\nconcatenation][36], which is a preprocessor feature whereby we can substitute\npart of a symbol based on the parameter of the macro. In the end, the C\npreprocessor will generate the following code and feed it to the compiler\n(macro `kh_exist(h,k)` is a little complex and not expanded for simplicity):\n\n    typedef struct {\n      int n_buckets, size, n_occupied, upper_bound;\n      unsigned *flags;\n      unsigned *keys;\n      char *vals;\n    } kh_m32_t;\n    static inline kh_m32_t *init_m32() {\n      return (kh_m32_t*)calloc(1, sizeof(kh_m32_t));\n    }\n    static inline int get_m32(kh_m32_t *h, unsigned k)\n    ...\n    static inline void destroy_m32(kh_m32_t *h) {\n      if (h) {\n        free(h->keys); free(h->flags); free(h->vals); free(h);\n      }\n    }\n\n\tint main() {\n\t\tint ret, is_missing;\n\t\tkhint_t k;\n\t\tkh_m32_t *h = init_m32();\n\t\tk = put_m32(h, 5, &ret);\n\t\tif (!ret) del_m32(h, k);\n\t\th->vals[k] = 10;\n\t\tk = get_m32(h, 10);\n\t\tis_missing = (k == h->n_buckets);\n\t\tk = get_m32(h, 5);\n\t\tdel_m32(h, k);\n\t\tfor (k = 0; k != h->n_buckets; ++k)\n\t\t\tif (kh_exist(h, k)) h->vals[k] = 1;\n\t\tdestroy_m32(h);\n\t\treturn 0;\n\t}\n\nThis is the C program we know.\n\nFrom this example, we can see that macros and the C preprocessor plays a key\nrole in klib. Klib is fast partly because the compiler knows the key-value\ntype at the compile time and is able to optimize the code to the same level\nas type-specific code. A generic library written with `void*` will not get such\nperformance boost.\n\nMassively inserting code upon instantiation may remind us of C++'s slow\ncompiling speed and huge binary size when STL\u002Fboost is in use. Klib is much\nbetter in this respect due to its small code size and component independency.\nInserting several hundreds lines of code won't make compiling obviously slower.\n\n## \u003Ca name=\"resources\">\u003C\u002Fa>Resources\n\n* Library documentation, if present, is available in the header files. Examples\ncan be found in the [test\u002F][24] directory.\n* **Obsolete** documentation of the hash table library can be found at\n[SourceForge][25]. This README is partly adapted from the old documentation.\n* [Blog post][26] describing the hash table library.\n* [Blog post][27] on why using `void*` for generic programming may be inefficient.\n* [Blog post][28] on the generic stream buffer.\n* [Blog post][29] evaluating the performance of `kvec.h`.\n* [Blog post][30] arguing B-tree may be a better data structure than a binary search tree.\n* [Blog post][31] evaluating the performance of `khash.h` and `kbtree.h` among many other implementations.\n[An older version][33] of the benchmark is also available.\n* [Blog post][34] benchmarking internal sorting algorithms and implementations.\n* [Blog post][32] on the k-small algorithm.\n* [Blog post][35] on the Hooke-Jeeve's algorithm for nonlinear programming.\n\n[1]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMIT_License\n[2]: https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHash_table\n[3]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FB-tree\n[4]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FIntrosort\n[5]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMerge_sort\n[6]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHeapsort\n[7]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FComb_sort\n[8]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFisher-Yates_shuffle\n[9]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSelection_algorithm\n[10]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFASTA_format\n[11]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FFASTQ_format\n[12]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMemory_pool\n[13]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMersenne_twister\n[14]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FPseudorandom_generator\n[15]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FNonlinear_programming\n[16]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSuffix_array\n[17]: https:\u002F\u002Fsites.google.com\u002Fsite\u002Fyuta256\u002Fsais\n[18]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FHidden_Markov_model\n[19]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSmith-Waterman_algorithm\n[20]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FNewick_format\n[21]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FContainer_(abstract_data_type)\n[22]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FTemplate_(C%2B%2B)\n[23]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FGLib\n[24]: https:\u002F\u002Fgithub.com\u002Fattractivechaos\u002Fklib\u002Ftree\u002Fmaster\u002Ftest\n[25]: http:\u002F\u002Fklib.sourceforge.net\u002F\n[26]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F09\u002F02\u002Fimplementing-generic-hash-library-in-c\u002F\n[27]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F10\u002F02\u002Fusing-void-in-generic-c-programming-may-be-inefficient\u002F\n[28]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F10\u002F11\u002Fa-generic-buffered-stream-wrapper\u002F\n[29]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F09\u002F19\u002Fc-array-vs-c-vector\u002F\n[30]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F09\u002F24\u002Fb-tree-vs-binary-search-tree\u002F\n[31]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F10\u002F07\u002Fanother-look-at-my-old-benchmark\u002F\n[32]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F09\u002F13\u002Fcalculating-median\u002F\n[33]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F08\u002F28\u002Fcomparison-of-hash-table-libraries\u002F\n[34]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F08\u002F28\u002Fcomparison-of-internal-sorting-algorithms\u002F\n[35]: http:\u002F\u002Fattractivechaos.wordpress.com\u002F2008\u002F08\u002F24\u002Fderivative-free-optimization-dfo\u002F\n[36]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FC_preprocessor#Token_concatenation\n[37]: http:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FC_preprocessor\n\n[wiki-avl]: https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FAVL_tree\n\n[kbtree]: http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F#KBtree%3A%20generic%20ordered%20map:%5B%5BKBtree%3A%20generic%20ordered%20map%5D%5D\n[khash]: http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F#Khash%3A%20generic%20hash%20table:%5B%5BKhash%3A%20generic%20hash%20table%5D%5D\n[kseq]: http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F#Kseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser:%5B%5BKseq%3A%20stream%20buffer%20and%20FASTA%2FQ%20parser%5D%5D\n[ksort]: http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F#Ksort%3A%20sorting%2C%20shuffling%2C%20heap%20and%20k-small:%5B%5BKsort%3A%20sorting%2C%20shuffling%2C%20heap%20and%20k-small%5D%5D\n[kavl]: http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F#KAVL%3A%20generic%20intrusive%20AVL%20tree\n[ketopt]: http:\u002F\u002Fattractivechaos.github.io\u002Fklib\u002F#Ketopt%3A%20parsing%20command-line%20arguments\n","klib是一个独立且轻量级的C语言库，提供了一系列高效的数据结构和算法实现。其核心功能包括哈希表、B树、AVL树、排序算法等，并且每个组件都尽量减少对外部依赖，仅需标准C库支持即可运行。klib通过广泛使用C宏来实现泛型编程，尽管这使得代码看起来较为复杂，但却保证了其实现与特定类型容器相比，在效率上具有竞争力。适合于需要高性能数据处理但又受限于资源的应用场景，如嵌入式系统开发或对内存占用有严格要求的项目中。",2,"2026-06-11 03:07:51","top_language"]