{"id":33179247,"url":"https://github.com/ggrandes/kvstore","last_synced_at":"2026-01-14T03:42:33.739Z","repository":{"id":4697688,"uuid":"5844844","full_name":"ggrandes/kvstore","owner":"ggrandes","description":"KVStore is a simple Key-Value Store based on B+Tree (disk \u0026 memory) for Java","archived":false,"fork":false,"pushed_at":"2024-09-15T09:51:08.000Z","size":271,"stargazers_count":99,"open_issues_count":2,"forks_count":25,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-13T03:01:44.513Z","etag":null,"topics":["btree","disk","index","java","persistent","tree"],"latest_commit_sha":null,"homepage":"http://technobcn.wordpress.com/2012/08/19/construyendo-un-arbol-b-btree/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ggrandes.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}},"created_at":"2012-09-17T17:53:12.000Z","updated_at":"2025-02-07T16:39:10.000Z","dependencies_parsed_at":"2022-08-25T23:32:10.810Z","dependency_job_id":null,"html_url":"https://github.com/ggrandes/kvstore","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/ggrandes/kvstore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fkvstore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fkvstore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fkvstore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fkvstore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ggrandes","download_url":"https://codeload.github.com/ggrandes/kvstore/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ggrandes%2Fkvstore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408858,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["btree","disk","index","java","persistent","tree"],"created_at":"2025-11-16T03:00:36.827Z","updated_at":"2026-01-14T03:42:33.731Z","avatar_url":"https://github.com/ggrandes.png","language":"Java","readme":"# KVStore\n\nKVStore is a Key-Value Store based on B+Tree for Memory \u0026 Disk (for on disk, keys and values must be fixed length) for Java. Project is Open source (Apache License, Version 2.0) \n\nAPI is similar to [TreeMap](http://docs.oracle.com/javase/6/docs/api/java/util/TreeMap.html).\n\n### Current Stable Version is [1.0.2](https://search.maven.org/#search|ga|1|g%3Aorg.javastack%20a%3Akvstore)\n\n---\n\n## DOC\n\n#### Usage Example\n\n```java\nimport java.util.Iterator;\nimport org.javastack.kvstore.KVStoreFactory;\nimport org.javastack.kvstore.Options;\nimport org.javastack.kvstore.holders.IntHolder;\nimport org.javastack.kvstore.structures.btree.BplusTree.TreeEntry;\nimport org.javastack.kvstore.structures.btree.BplusTreeFile;\n\npublic class Example {\n\tprivate static final String btreeFile = \"/tmp/test\";\n\n\t//\n\tpublic static void main(final String[] args) throws Exception {\n\t\tfinal int[] keys = new int[] { 5, 7, -11, 111, 0 };\n\t\t//\n\t\tKVStoreFactory\u003cIntHolder, IntHolder\u003e factory = new KVStoreFactory\u003cIntHolder, IntHolder\u003e(\n\t\t\t\tIntHolder.class, IntHolder.class);\n\t\tOptions opts = factory.createTreeOptionsDefault()\n\t\t\t\t.set(KVStoreFactory.FILENAME, btreeFile);\n\t\tBplusTreeFile\u003cIntHolder, IntHolder\u003e tree = factory.createTreeFile(opts);\n\t\t//\n\t\t// Open \u0026 Recovery tree if needed\n\t\ttry {\n\t\t\tif (tree.open())\n\t\t\t\tSystem.out.println(\"open tree ok\");\n\t\t} catch (InvalidDataException e) {\n\t\t\tSystem.out.println(\"open tree error, recovery needed\");\n\t\t\tif (tree.recovery(false) \u0026\u0026 tree.open()) {\n\t\t\t\tSystem.out.println(\"recovery ok, tree opened\");\n\t\t\t} else {\n\t\t\t\tthrow new Exception(\"Fatal Error Opening Tree\");\n\t\t\t}\n\t\t}\n\t\t// clear all previous content if any\n\t\ttree.clear();\n\t\t// ============== PUT\n\t\tfor (int i = 0; i \u003c keys.length; i++) {\n\t\t\tfinal IntHolder key = IntHolder.valueOf(keys[i]);\n\t\t\tfinal IntHolder value = IntHolder.valueOf(i);\n\t\t\ttree.put(key, value);\n\t\t}\n\t\ttree.sync();\n\t\t// ============== GET\n\t\tSystem.out.println(\"tree.get(7)=\" + tree.get(IntHolder.valueOf(7)));\n\t\t// ============== REMOVE\n\t\ttree.remove(IntHolder.valueOf(7));\n\t\t// ============== ITERATOR\n\t\tfor (Iterator\u003cTreeEntry\u003cIntHolder, IntHolder\u003e\u003e i = tree.iterator(); i\n\t\t\t\t.hasNext();) {\n\t\t\tTreeEntry\u003cIntHolder, IntHolder\u003e e = i.next();\n\t\t\tSystem.out.println(\"Key=\" + e.getKey() + \" Value=\" + e.getValue());\n\t\t}\n\t\t// ============== FIRST / LAST\n\t\tSystem.out.println(\"tree.firstKey()=\" + tree.firstKey());\n\t\tSystem.out.println(\"tree.lastKey()=\" + tree.lastKey());\n\t\t//\n\t\ttree.sync();\n\t\ttree.close();\n\t}\n}\n```\n\n##### The Result:\n\n\ttree.get(7)=1\n\tKey=-11 Value=2\n\tKey=0 Value=4\n\tKey=5 Value=0\n\tKey=111 Value=3\n\ttree.firstKey()=-11\n\ttree.lastKey()=111\n\n\n* More examples in [Test package](https://github.com/ggrandes/kvstore/tree/master/src/main/java/org/javastack/kvstore/test)\n\n---\n\n## MAVEN\n\nAdd the KVStore dependency to your pom.xml:\n\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.javastack\u003c/groupId\u003e\n        \u003cartifactId\u003ekvstore\u003c/artifactId\u003e\n        \u003cversion\u003e1.0.2\u003c/version\u003e\n    \u003c/dependency\u003e\n\n---\n\n## TODOs\n\n* A lot of Doc\n* Describe disk formats\n* HashMap on disk\n* Separate size of read cache and write cache\n\n## DONEs\n\n* BlockStore (Fixed length chunks)\n    * Support for mmaped files\n* StreamStore (Variable length chunks)\n* B+Tree for Index\n    * Buffer reuse\n    * Memory mode\n    * Persistence on disk (BlockStore)\n        * Cache of nodes\n        * Reuse free blocks on disk\n        * Redo log\n        * Recovery system\n        * Allow open without populate read cache\n        * Allow open readOnly mode\n        * File locking (multi-process)\n* HashMaps for natives (memory) \n* Holders for data and NIO serialization\n    * Fixed length\n        * Boolean\n        * Byte\n        * Short\n        * Integer\n        * Long\n        * Null\n    * Variable length\n        * Strings\n* Create Factory\n* Options object for factory\n* Use Log4J\n* Maven repository\n\n\n## MISC\n\n---\n\n## Benchmarks\n\n###### Values are not accurate, but orientative. Higher better. All test Running on Laptop { Windows Vista (32bits), Core 2 Duo 1.4Ghz (U9400), 4GB Ram, Magnetic Disk (WDC-WD5000BEVT-22ZAT0) }.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eTest-1\u003c/th\u003e\n    \u003cth\u003eWrites/s\u003c/th\u003e\n    \u003cth\u003eReads/s\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eBlockStore (RAF)\u003c/th\u003e\n    \u003ctd\u003e46k\u003c/td\u003e\n    \u003ctd\u003e58k\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eBlockStore (MMAP)\u003c/th\u003e\n    \u003ctd\u003e67k\u003c/td\u003e\n    \u003ctd\u003e182k\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eStreamStore\u003c/th\u003e\n    \u003ctd\u003e101k\u003c/td\u003e\n    \u003ctd\u003e55k\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n###### Test-1 (org.javastack.kvstore.test.BenchMarkDiskStore): Registry { count=1e6, datalen=256bytes } BlockStore { blockSize=512 (2reg/block), fileSize=250MB } StreamStore { outBufferSize=0x10000, align=true, fileSize=256MB } \n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003eTest-2\u003c/th\u003e\n    \u003cth\u003ePut/s\u003c/th\u003e\n    \u003cth\u003eGet/s\u003c/th\u003e\n    \u003cth\u003eRemove/s\u003c/th\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eBplusTreeMemory\u003c/th\u003e\n    \u003ctd\u003e457k\u003c/td\u003e\n    \u003ctd\u003e1041k\u003c/td\u003e\n    \u003ctd\u003e324k\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eIntHashMap\u003c/th\u003e\n    \u003ctd\u003e1154k\u003c/td\u003e\n    \u003ctd\u003e31250k\u003c/td\u003e\n    \u003ctd\u003e16000k\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003cth\u003eIntLinkedHashMap\u003c/th\u003e\n    \u003ctd\u003e1114k\u003c/td\u003e\n    \u003ctd\u003e31250k\u003c/td\u003e\n    \u003ctd\u003e11696k\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n###### Test-2 (org.javastack.kvstore.test.BenchMarkMemoryStructures): Registry { count=2e6, datalen=256bytes } BplusTreeMemory { key=Integer, b-order=511 } IntHashMap { initialSize=(2e6 * 2) } \n\n---\nInspired in [Book: Open Data Structures in Java](http://opendatastructures.org/ods-java/14_2_B_Trees.html), [Perl DB_File](http://search.cpan.org/~pmqs/DB_File-1.827/DB_File.pm), [JDBM3](https://github.com/jankotek/JDBM3) and [H2-Database](http://www.h2database.com/), this code is Java-minimalistic version.\n","funding_links":[],"categories":["数据库"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fggrandes%2Fkvstore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fggrandes%2Fkvstore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fggrandes%2Fkvstore/lists"}