{"id":13671675,"url":"https://github.com/Reeywhaar/nut","last_synced_at":"2025-04-27T18:31:34.389Z","repository":{"id":34158970,"uuid":"170784836","full_name":"Reeywhaar/nut","owner":"Reeywhaar","description":"Port of Bolt DB in Rust","archived":false,"fork":false,"pushed_at":"2024-01-28T11:30:47.000Z","size":184,"stargazers_count":45,"open_issues_count":1,"forks_count":8,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-08T21:45:42.839Z","etag":null,"topics":["database","embed","key-value-store","rust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/Reeywhaar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.txt","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}},"created_at":"2019-02-15T01:45:42.000Z","updated_at":"2025-03-28T15:42:12.000Z","dependencies_parsed_at":"2024-01-24T23:31:24.637Z","dependency_job_id":"e5c4a3d0-959c-4c57-b4f2-d1d94c160200","html_url":"https://github.com/Reeywhaar/nut","commit_stats":{"total_commits":23,"total_committers":2,"mean_commits":11.5,"dds":0.04347826086956519,"last_synced_commit":"ff1988bc9c68525e02d3d1729d714ba9f72401f9"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reeywhaar%2Fnut","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reeywhaar%2Fnut/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reeywhaar%2Fnut/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Reeywhaar%2Fnut/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Reeywhaar","download_url":"https://codeload.github.com/Reeywhaar/nut/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251187237,"owners_count":21549606,"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":["database","embed","key-value-store","rust"],"created_at":"2024-08-02T09:01:16.094Z","updated_at":"2025-04-27T18:31:33.761Z","avatar_url":"https://github.com/Reeywhaar.png","language":"Rust","readme":"# Nut\n\n#### Port of [Bolt DB](https://github.com/boltdb/bolt) in Rust\n\n- **Compatible with Bolt's database format** and provides similar api.\n\n  _Since Nut supports same format as Bolt there are known issues:_\n\n  - Bolt uses Memmap to operate, there is no LRU or other cache, so if database doesn't fit in memory, then it's end of game, Nut will inevitably crash.\n  - Data structures are written directly onto disk. No serialization takes place, so Nut doesn't understand db file from computer with different Endianness, for example.\n\n- **Transaction based**. In case of error transaction will be rolled back.\n- **Multiple readers, single writer.**\n  Nut works just like Bolt: you can have one writer and multiple readers at a time, just be sure they run on different threads. Making writer and reader transaction in same thread will cause deadlock. Writer can write freely if memory map is have enough free pages, in other case it will be waiting for reading transactions to close.\n\n# Usage\n\nPackage available at crates.io: https://crates.io/crates/nut\n\nDocumentation available at https://docs.rs/nut/0.1.2/nut/\n\nUsual way is to `cargo build --release` in console. Docs available via `cargo doc --no-deps --open`. Api is very similar to Bolt if you are familiar with it.\n\n# Examples\n\n### Create db and put something\n\n```rust\nuse nut::DBBuilder;\n\nlet mut db = DBBuilder::new(\"test.db\").build().unwrap();\nlet mut tx = db.begin_rw_tx().unwrap();\n{\n\tlet mut flowers = tx.create_bucket(b\"flowers\").unwrap();\n\t// returns mutable reference to bucket,\n\t\t// which prevents of reborrowing tx\n\n\tflowers.put(\n\t\tb\"iris\",\n\t\tb\"song by American alternative rock band Goo Goo Dolls\".to_vec()\n\t).unwrap();\n\tflowers.put(\n\t\tb\"binary data\",\n\t\tvec![127, 127, 127, 127]\n\t).unwrap();\n\n\t{\n\t\t// you can create subbuckets as well\n\t\tlet mut annuals = flowers\n\t\t\t.create_bucket_if_not_exists(b\"annuals\").unwrap();\n\n\t\t// api is basically same as for transaction\n\t\tannuals.put(\n\t\t\tb\"corn\",\n\t\t\tb\"American nu metal band from Bakersfield\".to_vec()\n\t\t).unwrap();\n\t\t// releasing subbucket\n\t}\n\n\t// releasing bucket to be able use tx again\n}\n// due to RAII tx will be automatically closed if no error occured,\n// or rolled back if there was some.\n// Additionally you can commit or rollback manually\ntx.rollback().unwrap();\n```\n\n**Note:** All buckets obtained from transaction should be dropped before calling either `rollback` or `commit`.\n\n### Getting data back\n\n```rust\nuse nut::DBBuilder;\n\nlet mut db = DBBuilder::new(\"test.db\").build().unwrap();\n\n// creating read only transaction\n// read only ransaction will be automatically rolled back\nlet mut tx = db.begin_tx().unwrap();\n\n// getting bucket\nlet flowers = tx.bucket(b\"flowers\").unwrap();\nlet data = flowers.get(b\"iris\").unwrap();\nassert_eq!(\n\tdata,\n\t\u0026b\"song by American alternative rock band Goo Goo Dolls\"[..]\n);\n```\n\n### Getting available buckets\n\n```rust\nuse nut::DBBuilder;\n\nlet mut db = DBBuilder::new(\"test.db\").build().unwrap();\nlet mut tx = db.begin_tx().unwrap();\n\n{\n\t// .buckets() available to conveniently retrieve all buckets keys\n\tlet bucket_names = tx.buckets(); // returns Vec\u003cVec\u003cu8\u003e\u003e\n\n\t// bucket key is any binary data, not only string\n\tassert_eq!(bucket_names, vec![\"flowers\".as_bytes().to_vec()]);\n}\n\n{\n\t// additionally there is .cursor() method\n\t// that returns Cursor struct,\n\t// which is able to iterate through bucket contents\n\tlet cursor = tx.cursor();\n\n\tassert_eq!(\n\t\t\u0026cursor.first().unwrap().value.unwrap(),\n\t\t\u0026\"flowers\".as_bytes()\n\t);\n}\n```\n\n# Nut Bin\n\nCrate also provides `nut` binary which is helpful to inspect database file in various ways. It can be found after `cargo build --release` in `./target/release/nut`.\n\nExcerpt from man:\n\n```bash\nUSAGE:\n    nut [SUBCOMMAND]\n\nFLAGS:\n    -h, --help       Prints help information\n    -V, --version    Prints version information\n\nSUBCOMMANDS:\n    check    Runs an exhaustive check to verify that all pages are accessible or are marked as freed.\n    dump     Dumps hex of the page\n    help     Prints this message or the help of the given subcommand(s)\n    info     Prints database info\n    pages    Prints a table of pages with their type (Meta, Leaf, Branch, Freelist)\n    tree     Prints buckets tree\n```\n\n# Disclaimer\n\nI'm not planning to actively mantain this project since it just a hobby project to check out Rust, and there are better alternatives in terms of performance.\n\n---\n\nMIT License\n","funding_links":[],"categories":["Rust"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FReeywhaar%2Fnut","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FReeywhaar%2Fnut","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FReeywhaar%2Fnut/lists"}