{"id":24314946,"url":"https://github.com/karrick/gobptree","last_synced_at":"2025-10-13T13:40:09.764Z","repository":{"id":137107696,"uuid":"135783145","full_name":"karrick/gobptree","owner":"karrick","description":"Provides several non-blocking B+Tree data structures","archived":false,"fork":false,"pushed_at":"2022-06-01T03:29:13.000Z","size":115,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-10T12:48:59.636Z","etag":null,"topics":["concurrency","concurrent-data-structure","golang","golang-library","tree-structure"],"latest_commit_sha":null,"homepage":null,"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/karrick.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-02T03:13:13.000Z","updated_at":"2022-12-29T15:57:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"eb740a3a-c416-400a-90ba-01900dda8617","html_url":"https://github.com/karrick/gobptree","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/karrick/gobptree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karrick%2Fgobptree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karrick%2Fgobptree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karrick%2Fgobptree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karrick%2Fgobptree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karrick","download_url":"https://codeload.github.com/karrick/gobptree/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karrick%2Fgobptree/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015353,"owners_count":26085684,"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","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"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":["concurrency","concurrent-data-structure","golang","golang-library","tree-structure"],"created_at":"2025-01-17T10:16:16.022Z","updated_at":"2025-10-13T13:40:09.713Z","avatar_url":"https://github.com/karrick.png","language":"Go","readme":"# gobptree\n\nProvides several _nearly_ non-blocking B+Tree data\nstructures. Deletions fail the not-blocking test because they must\nlock the tree from the root node down to the leaf node where a\nkey-value pair is stored until the deletion completes. Insertions and\nSearch functions are non-blocking.\n\n  * Int32Tree\n  * Int64Tree\n  * Uint32Tree\n  * Uint64Tree\n  * StringTree\n  * ComparableTree\n\nComparableTree is designed to use any data structure type as a datum\nkey that implements the Comparable interface. Namely, any data\nstructure that has methods for both `Less(interface{}) bool`, and\n`ZeroValue() Comparable`. Examples of this flexible B+Tree\nimplementation are provided in the `godoc` documentation as well as\nthe test files for the ComparableTree type.\n\nOther tree types are provided as optimized versions of their\nrespective data types.\n\n---\n\nEvery B+Tree data structure in this library provides the following\nmethods, each of which is described below.\n\n  * Delete(key)\n  * Insert(key, value)\n  * Search(key)\n  * Update(key, callback)\n  * NewScanner(key)\n\nInsertions in all of the B+Tree data structures from this library are\nhighly parallelizable, because the nodes will be pre-emptively split\nwhile traversing down from the root to the leaf if necessary rather\nthan having split nodes bubble back up from the bottom. This is not\nonly faster, but allows the tree to release the lock on the parent\nnode before visiting the child nodes, allowing other operations to\ncontinue in parallel that would otherwise block on the node lock.\n\nLike `Insert`, B+Tree `Search` only holds the lock on each node until\nthe appropriate child node is discovered, so they will not impede\ninsertions or other search operations.\n\nIn contrast to `Insert` and `Search`, however, invoking `Delete` from\nthe tree, require the lock to be held on each node in the tree until\nthe algorithm bubbles back up during the final stage of\nrecursion. This is because the tree will not know whether or not nodes\nmust borrow from their siblings or merge with their sibling until\nafter the child node has completed its deletion operation.\n\nThe `Update` method will search for the specified key and invoke the\nspecified callback function with the key-value pair associated with\nthat key, and then finally update the stored value for the key with\nthe value provided by a callback's return value. If the specified key\nwas not found, `Update` still invokes the callback function and stores\nits return value in the tree as a new key-value pair.\n\nAdditionally this library provides a `NewScanner` function that\nreturns a cursor that allows enumeration of all nodes equal to or\ngreater than the specified key. The cursor data structure returned by\neach of the B+Tree structures' `NewScanner` method each provide the\nfollowing interface. The cursor is designed to be used somewhat\nsimilarly to `bufio.Scanner`, and an example is provided.\n\n  * Close: releases the resources held by the cursor early\n  * Pair: returns the key-value pair referenced by the cursor\n  * Scan: returns true when additional key-value pairs remain\n\nFor example, if a tree has keys for all int64 values from 0 through\n1000, calling `NewScanner(10)` will return a scanner that lazily\niterates through all key-value pairs from 10 through 100. However, if\nthe tree held all odd values from 1 to 100, `NewScanner(10)` would\nreturn a cursor that lazily enumerated all key-value pairs from 11\nto 99. Note that if one go-routine is walking through values from the\ntree while another go-routine adds a new value, the new value will be\nincluded in the enumeration provided the insertion completes before\nthe enumeration arrives at the specified leaf node where the key is\nfound.\n\n## Overview [![GoDoc](https://godoc.org/github.com/karrick/gobptree?status.svg)](https://godoc.org/github.com/karrick/gobptree)\n\n```Go\npackage main\n\nimport (\n    \"fmt\"\n    \"math/rand\"\n    \"os\"\n    \"time\"\n\n    \"github.com/karrick/gobptree\"\n)\n\nfunc main() {\n    const oneMillion = 1000000\n    const order = 64\n\n    // Create a randomized list of int values from [0 to N).\n    rand.Seed(time.Now().Unix())\n    randomizedValues := rand.Perm(oneMillion)\n\n    // Create a B+Tree of the specified order, using int64 values as keys.\n    t, err := gobptree.NewInt64Tree(order)\n    if err != nil {\n        fmt.Fprintf(os.Stderr, \"ERROR: %s\\n\", err)\n        os.Exit(1)\n    }\n\n    // Sort the randomized list of keys by inserting each of them into the\n    // tree. For this example, we do not care about the value associated with\n    // each key.\n    for _, v := range randomizedValues {\n        t.Insert(int64(v), struct{}{})\n    }\n\n    // Scan through the tree, collecting all keys starting with the specified\n    // key, or the next key in the tree.\n    var sortedValues []int64\n    c := t.NewScanner(0)\n    for c.Scan() {\n        // Get the key-value pair for this datum, but only collect the key.\n        k, _ := c.Pair()\n        sortedValues = append(sortedValues, k)\n    }\n\n    // Ensure enumerated order of the keys are in fact sorted, in other words, a\n    // slice of int64 values from [0 to N).\n    for i := int64(0); i \u003c oneMillion; i++ {\n        // Demonstrate searching for key, but disregard the returned value.\n        _, ok := t.Search(i)\n        if !ok {\n            fmt.Fprintf(os.Stderr, \"GOT: %v; WANT: %v\", ok, true)\n            os.Exit(1)\n        }\n        // Ensure sortedValues[i] matches i.\n        if got, want := i, sortedValues[i]; got != want {\n            fmt.Fprintf(os.Stderr, \"GOT: %v; WANT: %v\", got, want)\n        }\n    }\n\n    // Demonstrate removing all keys from the tree in randomized order.\n    for _, v := range randomizedValues {\n        t.Delete(int64(v))\n    }\n}\n```\n\n## Install\n\n```\ngo get github.com/karrick/gobptree\n```\n\n## License\n\nMIT.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarrick%2Fgobptree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarrick%2Fgobptree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarrick%2Fgobptree/lists"}