{"id":21082733,"url":"https://github.com/renproject/kv","last_synced_at":"2025-05-16T09:32:02.763Z","repository":{"id":52240693,"uuid":"185332842","full_name":"renproject/kv","owner":"renproject","description":"A flexible and extensible library for key-value storage","archived":false,"fork":false,"pushed_at":"2020-01-07T03:51:08.000Z","size":281,"stargazers_count":17,"open_issues_count":0,"forks_count":4,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-14T02:52:02.546Z","etag":null,"topics":["badgerdb","cache","database","go","key","leveldb","store","value"],"latest_commit_sha":null,"homepage":"","language":"Go","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/renproject.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":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2019-05-07T06:14:42.000Z","updated_at":"2024-04-03T19:54:42.000Z","dependencies_parsed_at":"2022-08-26T05:40:27.410Z","dependency_job_id":null,"html_url":"https://github.com/renproject/kv","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renproject%2Fkv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renproject%2Fkv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renproject%2Fkv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renproject%2Fkv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renproject","download_url":"https://codeload.github.com/renproject/kv/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254504919,"owners_count":22082116,"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":["badgerdb","cache","database","go","key","leveldb","store","value"],"created_at":"2024-11-19T20:15:10.732Z","updated_at":"2025-05-16T09:32:02.386Z","avatar_url":"https://github.com/renproject.png","language":"Go","readme":"# `📦 kv`\n\n[![GoDoc](https://godoc.org/github.com/renproject/kv?status.svg)](https://godoc.org/github.com/renproject/kv)\n![](https://github.com/renproject/kv/workflows/go/badge.svg)\n![Go Report](https://goreportcard.com/badge/github.com/renproject/kv)\n[![Coverage Status](https://coveralls.io/repos/github/renproject/kv/badge.svg?branch=master)](https://coveralls.io/github/renproject/kv?branch=master)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)\n\nA flexible and extensible library for key-value storage.\n\n- [x] Multiple encoding/decoding formats\n- [x] Persistent database drivers\n- [x] In-memory database drivers\n- [x] Time-to-live caching\n- [x] Safe for concurrent use\n- [x] Production ready\n\nInstallation\n------------\n\n```sh\ngo get github.com/renproject/kv\n```\n\nRequirements\n------------\n\nRequires `go1.11` or newer.\n\nUsage\n-----\n\n### Codec\n\nA `Codec` encodes `interface{}` values into bytes, decode bytes into the `interface{}` values. Generally, when a specific type is not supported, a `Codec` will panic. Out of the box, KV supports:\n\n- `JSONCodec` which encodes/decodes using the standard library [JSON](https://golang.org/pkg/encoding/json) marshaler, and\n- `GobCodec` which encodes/decodes using the standard library [Gob]https://golang.org/pkg/encoding/gob marshaler (you must explicitly register types outside of KV).\n\nAn example of using the `JSONCodec`:\n\n```go\ndb := kv.NewLevelDB(\".db\", kv.JSONCodec)\n```\n\n### DB\n\nA `DB` is a key/value database. The key is a `string` and the value is an `interface{}` that can be encoded/decoded by the chosen `Codec` (different `DBs` can use different `Codecs`). A `DB` is safe for concurrent if, and only if, the underlying driver is safe for concurrent use (the LevelDB driver and BadgerDB driver are safe for concurrent use).\n\nAn example of initialising a `DB`:\n\n```go\n// Initialising an in-memory database \ndb := kv.NewMemDB(kv.JSONCodec)\n\n// Initialising a LevelDB database\ndb = kv.NewLevelDB(\".ldb\", kv.JSONCodec)\n\n// Initialising a BadgerDB database \ndb = kv.NewBadgerDB(\".bdb\", kv.JSONCodec)\n```\n\nAlthough reading/writing is usually done through a `Table`, you can read/write using the `DB` directly (you must be careful that keys will not conflict with `Table` name hashes):\n\n```go\n// Write\nif err := db.Insert(\"key\", \"value\"); err != nil {\n    log.Fatalf(\"error inserting: %v\", err)\n}\n\n// Read\nvar value string\nif err := db.Get(\"key\", \u0026value); err != nil {\n    log.Fatalf(\"error getting: %v\", err)\n}\n\n// Delete\nif err := db.Delete(\"key\"); err != nil {\n    log.Fatalf(\"error deleting: %v\", err)\n}\n\n// Number of key/value pairs with the given prefix\nsize, err := db.Size(\"\")\nif err != nil {\n    log.Fatalf(\"error sizing: %v\", err)\n}\nlog.Printf(\"%v key/value pairs found\", size)\n\n// Get an iterator over all key/value pairs with the given prefix\niter := db.Iterator(\"\")\n```\n\n\n### Table\n\nA `Table` is an abstraction over a `DB` partitions key/value pairs into non-overlapping groups. This allows you to iterate over small groups of key/value pairs that are logically related. You must ensure that `Table` names are unique.\n\nAn example of basic use:\n\n```go\ntype Foo struct{\n    A string\n    B int\n    C []byte\n}\n\n// Init\ntable := kv.NewTable(db, \"myAwesomeTable\")\n\n// Write\nfoo := Foo{\"foo\", 420, []byte{1,2,3}}\nif err := table.Insert(\"key\", foo); err != nil {\n    log.Fatalf(\"error inserting into table: %v\", err)\n}\n\n// Read\nbar := Foo{}\nif err := table.Get(\"key\", \u0026bar); err != nil {\n    log.Fatalf(\"error getting from table: %v\", err)\n}\n```\n\nThe most useful feature of `Tables` is iteration:\n\n```go\n// Get the number of key/value pairs in the table\nsize, err := table.Size()\nif err != nil {\n    log.Fatalf(\"error sizing table: %v\", err)\n}\nlog.Printf(\"%v key/value pairs found\", size)\n\n// Iterate over all key/value pairs in the table\nfor iter := table.Iterator(); iter.Next(); {\n    key, err := iter.Key()\n    if err != nil {\n        continue\n    }\n    value := Foo{}\n    if err = iter.Value(\u0026value); err != nil {\n        continue\n    }\n}\n```\n\nBenchmarks\n----------\n\n| Database | Number of iterations run | Time (ns/op) | Memory (bytes/op) |\n|----------|:------------------------:|-------------:|------------------:|\n| LevelDB  |           2000           |     10784337 |   4397224         |\n| BadgerDB |            100           |    200012411 | 200012411         |\n\nContributors\n------------\n\nBuilt with ❤ by Ren.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenproject%2Fkv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenproject%2Fkv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenproject%2Fkv/lists"}