{"id":16889683,"url":"https://github.com/benoitc/cbt","last_synced_at":"2025-04-11T13:08:02.295Z","repository":{"id":25237202,"uuid":"28661793","full_name":"benoitc/cbt","owner":"benoitc","description":"multi-layer MVCC log append-only database library based on the Apache CouchDB btree.","archived":false,"fork":false,"pushed_at":"2018-07-23T20:37:06.000Z","size":143,"stargazers_count":14,"open_issues_count":0,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-09T10:07:20.575Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Erlang","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/benoitc.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":"2014-12-31T09:09:54.000Z","updated_at":"2021-12-07T15:50:07.000Z","dependencies_parsed_at":"2022-08-19T15:10:18.879Z","dependency_job_id":null,"html_url":"https://github.com/benoitc/cbt","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitc%2Fcbt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitc%2Fcbt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitc%2Fcbt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benoitc%2Fcbt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benoitc","download_url":"https://codeload.github.com/benoitc/cbt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248404598,"owners_count":21097780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-10-13T16:58:21.047Z","updated_at":"2025-04-11T13:08:02.275Z","avatar_url":"https://github.com/benoitc.png","language":"Erlang","readme":"#cbt\n\nmulti-layer MVCC log append-only database library based on the Apache CouchDB btree.\n\n## Changes compared to couchdb\n\n- Pluggable Storage backends\n- use CRC32 to check data integrity instead of MD5\n- rewrote the file init part to make it more robust\n- removed the need of an external config. Provides correct default and use\n  erlang environment.\n- documentation and specs\n- some syntax improvements.\n\n## build\n\n### 1. install rebar\nTo build cbt you need to install rebar in your `PATH`. Rebar is\navailable on Github:\n\nhttps://github.com/rebar/rebar\n\nFollow the\n[README](https://github.com/rebar/rebar/blob/master/README.md) to\ninstall it.\n\n### 2. build\n\nFetch the source code:\n\n    $ git clone https://bitbucket.org/refugeio/cbt.git\n\nBuild the source, run the `make` command. It will fetch any needed\ndependencies.\n\n    $ cd /\u003cPATH_TO\u003e/cbt\n    $ make\n\n\u003e **Note:** To use snappy or lz4 compression methods you need to install the\n\u003e following dependencies:\n\u003e - `snappy`:  https://github.com/fdmanana/snappy-erlang-nif\n\u003e - ` lz4`: https://github.com/krestenkrab/erlang-lz4\n\u003e\n\u003e And launch your application installed in the library path.\n\n### 3. test CBT\n\nRun the following command line:\n\n    $ make test\n\n\n### 3. Build the doc\n\n    $ make doc\n\nand open the `index.html` file in the doc folder. Or read it\n[online](http://cbt.cowdb.org).\n\n## Example of usage with the file backend\n\nExample of usage:\n\nStore a {Key Value} pair in a btree:\n\n    1\u003e {ok, Fd} = cbt_file:open(\"test.db\", [create_if_missing]).\n    {ok,\u003c0.35.0\u003e}\n    2\u003e {ok, Btree} = cbt_btree:open(nil, Fd).\n    {ok,{btree,\u003c0.35.0\u003e,nil,undefined,undefined,undefined,nil,\n               snappy,1279}}\n    3\u003e\n    3\u003e {ok, Btree2} = cbt_btree:add(Btree, [{a, 1}]).\n    {ok,{btree,\u003c0.35.0\u003e,\n               {0,[],32},\n               undefined,undefined,undefined,nil,snappy,1279}}\n    4\u003e Root = cbt_btree:get_state(Btree2).\n    {0,[],32}\n    5\u003e Header = {1, Root}.\n    {1,{0,[],32}}\n    6\u003e cbt_file:write_header(Fd, Header).\n    ok\n\nWhat we did here is to open a file, create a btree inside and add a key\nvalue. Until we write the header, the database value is not changed.\n\nNow open the database in a new process and read the btree using the last\nheader:\n\n    7\u003e {ok, Fd1} = cbt_file:open(\"test.db\").\n    {ok,\u003c0.44.0\u003e}\n    8\u003e\n    8\u003e {ok, Header1} = cbt_file:read_header(Fd1).\n    {ok,{1,{0,[],32}}}\n    9\u003e Header1 == Header\n    9\u003e .\n    true\n    10\u003e {_, ReaderRoot} = Header1.\n    {1,{0,[],32}}\n    11\u003e {ok, SnapshotBtree} = cbt_btree:open(ReaderRoot, Fd1).\n    {ok,{btree,\u003c0.44.0\u003e,\n               {0,[],32},\n               undefined,undefined,undefined,nil,snappy,1279}}\n    12\u003e cbt_btree:lookup(SnapshotBtree, [a]).\n    [{ok,{a,1}}]\n\nYou can check that the database value is not change until we store the\nheader:\n\n    13\u003e {ok, Btree4} = cbt_btree:add(Btree2, [{a, 1}, {b, 2}]).\n    {ok,{btree,\u003c0.35.0\u003e,\n               {4160,[],39},\n               undefined,undefined,undefined,nil,snappy,1279}}\n    14\u003e cbt_btree:lookup(Btree4, [a, b]).\n    [{ok,{a,1}},{ok,{b,2}}]\n    15\u003e Root2 = cbt_btree:get_state(Btree4).\n    {4160,[],39}\n    16\u003e Header2 = {1, Root2}.\n    {1,{4160,[],39}}\n    17\u003e cbt_file:write_header(Fd, Header2).\n    ok\n    18\u003e cbt_btree:lookup(SnapshotBtree, [a, b]).\n    [{ok,{a,1}},not_found]\n\n\n## ETS backend\n\nFind here a simple usage of the ETS backend of cbt allowing you to store one\ndatabase in an ETS.\n\n    1\u003e cbt_ets:new(test).\n    test\n    2\u003e {ok, Bt} = cbt_ets:open_btree(test, test).\n    {ok,{btree,test,cbt_ets,nil,identity,identity,\n               #Fun\u003ccbt_btree.1.30772535\u003e,nil,none,1279,2558}}\n    3\u003e {ok, Bt2} = cbt_btree:add(Bt, [{a, 1}]).\n    {ok,{btree,test,cbt_ets,\n               {1,[],28},\n               identity,identity,#Fun\u003ccbt_btree.1.30772535\u003e,nil,none,1279,\n               2558}}\n    4\u003e  cbt_ets:update_btree(test, test, Bt2).\n    true\n    5\u003e {ok, SnapshotBtree} = cbt_ets:open_btree(test, test).\n    {ok,{btree,test,cbt_ets,\n               {1,[],28},\n               identity,identity,#Fun\u003ccbt_btree.1.30772535\u003e,nil,none,1279,\n               2558}}\n    6\u003e cbt_btree:lookup(SnapshotBtree, [a]).\n    [{ok,{a,1}}]\n    7\u003e {ok, Bt3} = cbt_btree:add(Bt2, [{b, 2}]).\n    {ok,{btree,test,cbt_ets,\n               {2,[],36},\n               identity,identity,#Fun\u003ccbt_btree.1.30772535\u003e,nil,none,1279,\n               2558}}\n    8\u003e cbt_ets:update_btree(test, test, Bt3).\n    true\n    9\u003e cbt_btree:lookup(SnapshotBtree, [a, b]).\n    [{ok,{a,1}},not_found]\n    10\u003e {ok, SnapshotBtree2} = cbt_ets:open_btree(test, test).\n    {ok,{btree,test,cbt_ets,\n               {2,[],36},\n               identity,identity,#Fun\u003ccbt_btree.1.30772535\u003e,nil,none,1279,\n               2558}}\n    11\u003e cbt_btree:lookup(SnapshotBtree2, [a, b]).\n    [{ok,{a,1}},{ok,{b,2}}]i\n\n## Custom storage backend\n\nCBT provides you 2 different backends by default:\n\n- `cbt_file`: Backend to store data in a file\n- `cbt_ets`: Backend to store data in ETS.\n\nBut can use a custom backends to store the btree data if you need it. For\nexample if you want to store the btree in a custom file backend when you want\nto change the data types or when you want to store the BTREE over a Key/Value\nstore.\n\nTo do it just pass the backend module to the btree and give it the Reference\n(atom or pid) that have been created when initializing the backend. Have a\nlook in the `cbt_ets' module for more informations.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenoitc%2Fcbt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenoitc%2Fcbt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenoitc%2Fcbt/lists"}