{"id":18877086,"url":"https://github.com/keks51/keksdb","last_synced_at":"2026-04-27T00:31:42.400Z","repository":{"id":217327068,"uuid":"743588071","full_name":"keks51/KeksDB","owner":"keks51","description":"key value database based on bplus and lsm trees","archived":false,"fork":false,"pushed_at":"2024-02-04T13:35:19.000Z","size":3289,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-03T16:43:26.510Z","etag":null,"topics":["bplus-tree","bplustree","database","kv-database","kv-db","kv-store","lsm","lsm-tree","memtable","sstable"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/keks51.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-01-15T14:55:57.000Z","updated_at":"2024-02-05T14:38:55.000Z","dependencies_parsed_at":"2024-01-15T20:03:26.488Z","dependency_job_id":"bc96e75a-6787-4cc4-b611-ac9483384447","html_url":"https://github.com/keks51/KeksDB","commit_stats":null,"previous_names":["keks51/keksdb"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/keks51/KeksDB","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keks51%2FKeksDB","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keks51%2FKeksDB/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keks51%2FKeksDB/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keks51%2FKeksDB/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/keks51","download_url":"https://codeload.github.com/keks51/KeksDB/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/keks51%2FKeksDB/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32318417,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T23:26:28.701Z","status":"ssl_error","status_checked_at":"2026-04-26T23:26:25.802Z","response_time":129,"last_error":"SSL_read: 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":["bplus-tree","bplustree","database","kv-database","kv-db","kv-store","lsm","lsm-tree","memtable","sstable"],"created_at":"2024-11-08T06:16:49.148Z","updated_at":"2026-04-27T00:31:42.375Z","avatar_url":"https://github.com/keks51.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Example of key value database based on bplus and lsm trees\n\n- Database supports concurrent operations: put, remove, get, range select\n- Bplus tree is based on page buffer which stores data both in memory and disk.\n- Lsm tree is based on memcache and sstables.\n- Recovery is based on WAL and checkpoint snapshots\n- Http and thrift clients\n- Compared with RocksDB 8.10.0. See below\n\n# Architecture\n## database\n![db_png.png](architecture%2Fdb_png.png)\n\n## LSM\n![lsm_png.png](architecture%2Flsm_png.png)\n\n## Bplus\n![bplus_png.png](architecture%2Fbplus_png.png)\n\n## Bplus tree example\n\n[BplusSamplesTest.java](src%2Ftest%2Fjava%2Fexamples%2FBplusSamplesTest.java)\n```java\n\n@Test\npublic void ex1(@TempDir Path dir) {\n\n    try (KVStore kvStore = new KVStore(dir.toFile())) {\n        // creating db\n        String dbName = \"bplus_test_db\";\n        kvStore.createDB(dbName);\n\n        // creating table\n        String tblName = \"bplus_table_test\";\n        // bplus table properties\n        Properties properties = new Properties() {{\n            put(BPlusConfParamsEnum.BTREE_ORDER, 400);\n        }};\n        kvStore.createTable(\n                dbName,\n                tblName,\n                TableEngineType.BPLUS.toString(),\n                properties);\n\n        // adding records\n        kvStore.put(dbName, tblName, \"key1\", \"value1\".getBytes());\n        kvStore.put(dbName, tblName, \"key2\", \"value2\".getBytes());\n        kvStore.put(dbName, tblName, \"key3\", \"value3\".getBytes());\n\n        // getting values\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key1\"))); // value1\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key2\"))); // value2\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key3\"))); // value3\n        System.out.println(kvStore.get(dbName, tblName, \"key4\")); // null\n\n        // deleting several records\n        kvStore.remove(dbName, tblName, \"key1\");\n        kvStore.remove(dbName, tblName, \"key2\");\n\n        // getting records\n        System.out.println(kvStore.get(dbName, tblName, \"key1\")); // null\n        System.out.println(kvStore.get(dbName, tblName, \"key2\")); // null\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key3\"))); // value3\n        System.out.println(kvStore.get(dbName, tblName, \"key4\")); // null\n\n        // dropping table\n        kvStore.dropTable(dbName, tblName);\n\n        // dropping db\n        kvStore.dropDB(dbName);\n    }\n}\n```\n\n## Lsm tree\n\n[LsmSamplesTest.java](src%2Ftest%2Fjava%2Fexamples%2FLsmSamplesTest.java)\n\n```java\n\n@Test\npublic void ex1(@TempDir Path dir) {\n\n    try (KVStore kvStore = new KVStore(dir.toFile())) {\n        // creating db\n        String dbName = \"lsm_test_db\";\n        kvStore.createDB(dbName);\n\n        // creating table\n        String tblName = \"lsm_table_test\";\n        // lsm table properties\n        Properties properties = new Properties() {{\n            put(LsmConfParamsEnum.MEM_CACHE_SIZE, 1_000_000);\n            put(LsmConfParamsEnum.BLOOM_FILTER_FALSE_POSITIVE_RATE, 0.1);\n        }};\n        kvStore.createTable(\n                dbName,\n                tblName,\n                TableEngineType.LSM.toString(),\n                properties);\n\n        // adding records\n        kvStore.put(dbName, tblName, \"key1\", \"value1\".getBytes());\n        kvStore.put(dbName, tblName, \"key2\", \"value2\".getBytes());\n        kvStore.put(dbName, tblName, \"key3\", \"value3\".getBytes());\n\n        // getting values\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key1\"))); // value1\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key2\"))); // value2\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key3\"))); // value3\n        System.out.println(kvStore.get(dbName, tblName, \"key4\")); // null\n\n        // deleting several records\n        kvStore.remove(dbName, tblName, \"key1\");\n        kvStore.remove(dbName, tblName, \"key2\");\n\n        // getting records\n        System.out.println(kvStore.get(dbName, tblName, \"key1\")); // null\n        System.out.println(kvStore.get(dbName, tblName, \"key2\")); // null\n        System.out.println(new String(kvStore.get(dbName, tblName, \"key3\"))); // value3\n        System.out.println(kvStore.get(dbName, tblName, \"key4\")); // null\n\n        // dropping table\n        kvStore.dropTable(dbName, tblName);\n\n        // dropping db\n        kvStore.dropDB(dbName);\n    }\n}\n```\n\n# Performance benchmarks\n\nAll the benchmarks are run on MacBook Pro     \nProcessor: 2,4 GHz 8-Core Intel Core i9     \nMemory: 32 GB 2667 MHz DDR4     \nmacOS: 13.3\n\nGlobal Parameters:\n - JDK: corretto-1.8.0_362\n - -Xmx1g\n - Key size: 12 bytes\n - Value size: 500 bytes\n - all operations are done in parallel\n - all records are written in random order\n - WAL is disabled\n - No optimization process in background (Merging sstables, compacting bplus file on disk, ...)\n - Each test was run 10 times. Avg result is taken\n\n## Bplus tree\nParameters:\n - Page buffer size: 256mb\n - Page buffer clean-up %: if 80% is occupied\n - Page size: 8kb\n - Tree Order: 451\n\n[BplusPerfTest.java](src%2Ftest%2Fjava%2Fperf_test%2FBplusPerfTest.java)\n### PUT (5 million records, approx 2.5G)\n\n| threads | total sec | mean millis | ops/sec | p0.5 millis | p0.75 millis | p0.99 millis | p0.999 millis |\n|---------|-----------|-------------|---------|-------------|--------------|--------------|---------------|\n| 1       | 168.9     | 0.030       | 29612   | 0.045       | 0.086        | 0.205        | 0.278         |\n| 4       | 149.4     | 0.110       | 33457   | 0.147       | 0.311        | 0.950        | 2.752         |\n| 8       | 160.0     | 0.241       | 31241   | 0.311       | 0.655        | 2.228        | 6.815         |\n| 16      | 160.1     | 0.482       | 31228   | 0.557       | 1.441        | 4.718        | 13.631        |\n| 32      | 155.1     | 0.940       | 32233   | 1.048       | 3.145        | 8.388        | 31.457        |\n| 50      | 147.3     | 1.392       | 33939   | 1.638       | 4.980        | 12.058       | 33.554        |\n| 100     | 151.1     | 2.859       | 33090   | 3.670       | 9.961        | 33.554       | 50.331        |\n| 160     | 164.4     | 4.940       | 30422   | 6.553       | 16.252       | 50.331       | 79.691        |\n| 200     | 196.3     | 7.426       | 25471   | 10.485      | 24.117       | 71.303       | 109.051       |\n\n![put_5m.png](perf_res%2Fbplus%2Fput_5m.png)\n\n### GET (5 million records, approx 2.5G)\n\n| threads | total sec | mean millis | ops/sec | p0.5 millis | p0.75 millis | p0.99 millis | p0.999 millis |\n|---------|-----------|-------------|---------|-------------|--------------|--------------|---------------|\n| 1       | 16.0      | 0.001       | 313087  | 0.001       | 0.001        | 0.002        | 0.026         |\n| 4       | 10.3      | 0.003       | 484355  | 0.002       | 0.003        | 0.019        | 0.033         |\n| 8       | 9.4       | 0.005       | 533560  | 0.004       | 0.004        | 0.010        | 0.026         |\n| 16      | 12.0      | 0.007       | 418235  | 0.005       | 0.006        | 0.016        | 0.026         |\n| 32      | 12.8      | 0.007       | 390381  | 0.005       | 0.006        | 0.017        | 0.031         |\n| 50      | 13.1      | 0.007       | 381562  | 0.005       | 0.006        | 0.018        | 0.035         |\n| 100     | 13.0      | 0.007       | 384408  | 0.005       | 0.006        | 0.016        | 0.033         |\n| 160     | 12.7      | 0.006       | 394228  | 0.005       | 0.006        | 0.013        | 0.024         |\n| 200     | 12.8      | 0.006       | 390320  | 0.004       | 0.005        | 0.012        | 0.024         |\n\n![get_5m.png](perf_res%2Fbplus%2Fget_5m.png)\n\n## Lsm tree\n\nParameters:\n- MemTable size: 256mb\n- Sparse index size in records: 8192 records\n- All cashes are disabled\n\n[LsmPerfTest.java](src%2Ftest%2Fjava%2Fperf_test%2FLsmPerfTest.java)\n### Put (5 million records, approx 2.5G)\n\n| threads | total sec | mean millis | ops/sec | p0.5 millis | p0.75 millis | p0.99 millis | p0.999 millis |\n|---------|-----------|-------------|---------|-------------|--------------|--------------|---------------|\n| 1       | 31.3      | 0.003       | 159555  | 0.002       | 0.003        | 0.006        | 0.010         |\n| 4       | 27.9      | 0.005       | 179031  | 0.004       | 0.005        | 0.009        | 0.026         |\n| 8       | 25.0      | 0.006       | 199696  | 0.005       | 0.006        | 0.011        | 0.033         |\n| 16      | 26.0      | 0.011       | 192581  | 0.006       | 0.007        | 0.013        | 0.197         |\n| 32      | 27.0      | 0.020       | 185384  | 0.006       | 0.008        | 0.020        | 0.246         |\n| 50      | 28.7      | 0.027       | 174520  | 0.006       | 0.008        | 0.014        | 0.246         |\n| 100     | 27.7      | 0.049       | 180642  | 0.006       | 0.007        | 0.014        | 0.328         |\n| 160     | 25.9      | 0.045       | 193221  | 0.005       | 0.007        | 0.012        | 0.345         |\n| 200     | 26.6      | 0.077       | 188097  | 0.006       | 0.007        | 0.021        | 0.371         |\n\n![put_5m.png](perf_res%2Flsm%2Fput_5m.png)\n\n### Get (1 million records, approx 500mb)\n\n| threads | total sec | mean millis | ops/sec | p0.5 millis | p0.75 millis | p0.99 millis | p0.999 millis |\n|---------|-----------|-------------|---------|-------------|--------------|--------------|---------------|\n| 1       | 234.6     | 0.231       | 4261    | 0.237       | 0.344        | 0.524        | 0.786         |\n| 4       | 91.8      | 0.357       | 10889   | 0.376       | 0.557        | 0.819        | 1.179         |\n| 8       | 71.8      | 0.550       | 13932   | 0.557       | 0.819        | 1.572        | 6.553         |\n| 16      | 72.6      | 1.109       | 13778   | 1.048       | 1.572        | 3.407        | 13.106        |\n| 32      | 73.2      | 2.239       | 13668   | 1.113       | 1.637        | 46.136       | 125.828       |\n| 50      | 70.7      | 3.372       | 14145   | 1.113       | 1.572        | 96.468       | 201.326       |\n| 100     | 69.6      | 6.595       | 14360   | 1.113       | 1.637        | 218.103      | 419.429       |\n| 160     | 69.0      | 10.406      | 14484   | 1.048       | 1.572        | 352.321      | 603.979       |\n| 200     | 72.3      | 13.647      | 13825   | 1.113       | 1.572        | 452.984      | 738.196       |\n\n![get_1m.png](perf_res%2Flsm%2Fget_1m.png)\n\n## RocksDB (Lsm tree)\n\nParameters:\n- MemTable size: 256mb\n- Sparse index size in records: 8192 records\n- All cashes are disabled\n- version: 8.10.0\n\n### Put (5 million records, approx 2.5G)\n[write_test.sh](perf_res%2Frocksdb%2Fwrite_test.sh)\n\n| threads | total sec | mean millis | ops/sec | p0.5 millis | p0.75 millis | p0.99 millis | p0.999 millis |\n|---------|-----------|-------------|---------|-------------|--------------|--------------|---------------|\n| 1       | 11.3      | 0.002       | 441666  | 0.002       | 0.002        | 0.005        | 0.021         |\n| 4       | 6.7       | 0.005       | 744083  | 0.004       | 0.005        | 0.020        | 0.046         |\n| 8       | 4.5       | 0.007       | 1120613 | 0.006       | 0.008        | 0.029        | 0.092         |\n| 16      | 8.4       | 0.027       | 592084  | 0.009       | 0.014        | 0.179        | 0.505         |\n| 32      | 6.7       | 0.042       | 746748  | 0.010       | 0.068        | 0.166        | 1.915         |\n| 50      | 30.0      | 0.297       | 166481  | 0.287       | 0.355        | 0.799        | 4.216         |\n| 100     | 44.1      | 0.880       | 113488  | 0.828       | 1.054        | 1.702        | 4.065         |\n| 160     | 60.1      | 1.923       | 83160   | 1.837       | 2.346        | 3.140        | 8.487         |\n| 200     | 72.4      | 2.893       | 69092   | 2.729       | 3.469        | 4.398        | 11.258        |\n\n![put_5m.png](perf_res%2Frocksdb%2Fput_5m.png)\n\n### Get (1 million records, approx 500mb)\n[read_test.sh](perf_res%2Frocksdb%2Fread_test.sh)\n\n| threads | total sec | mean millis | ops/sec | p0.5 millis | p0.75 millis | p0.99 millis | p0.999 millis | p0.9999 millis |\n|---------|-----------|-------------|---------|-------------|--------------|--------------|---------------|----------------|\n| 1       | 978.6     | 0.979       | 1021    | 0.982       | 1.160        | 3.279        | 4.348         | 6.425          |\n| 4       | 538.6     | 2.153       | 1856    | 1.885       | 2.467        | 7.860        | 9.834         | 18.555         |\n| 8       | 526.2     | 4.207       | 1900    | 3.910       | 4.608        | 12.487       | 20.436        | 34.563         |\n| 16      | 553.2     | 8.843       | 1807    | 8.003       | 9.696        | 30.507       | 62.561        | 105.109        |\n| 32      | 563.0     | 17.985      | 1776    | 13.135      | 23.148       | 72.873       | 109.830       | 170.000        |\n| 50      | 448.6     | 22.372      | 2228    | 12.581      | 29.524       | 124.573      | 168.988       | 244.832        |\n| 100     | 372.6     | 37.034      | 2683    | 9.892       | 39.344       | 313.190      | 453.023       | 558.513        |\n| 160     | 282.2     | 44.554      | 3543    | 5.875       | 13.964       | 561.457      | 828.740       | 858.606        |\n| 200     | 244.6     | 47.957      | 4087    | 4.905       | 13.880       | 636.681      | 850.862       | 1146.667       |\n\n![get_1m.png](perf_res%2Frocksdb%2Fget_1m.png)\n\n\n## Bplus tree vs Lsm tree vs RocksDB\n\n### PUT (5 million records, approx 2.5G)\n\n![put_op_sec_5m.png](perf_res%2Fput_op_sec_5m.png)\n\n![put_sec_5m.png](perf_res%2Fput_sec_5m.png)\n\n### GET (1 million records, approx 500mb)\n\n![get_op_sec_1m.png](perf_res%2Fget_op_sec_1m.png)\n\n![get_sec_1m.png](perf_res%2Fget_sec_1m.png)\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeks51%2Fkeksdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkeks51%2Fkeksdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkeks51%2Fkeksdb/lists"}