{"id":28956664,"url":"https://github.com/nimaoth/nimsumtree","last_synced_at":"2026-02-27T05:37:29.087Z","repository":{"id":240536710,"uuid":"802898046","full_name":"Nimaoth/nimsumtree","owner":"Nimaoth","description":"Sum tree is a tree data structure similar to a B-tree, but each node stores user defined summaries of it's children","archived":false,"fork":false,"pushed_at":"2025-04-19T14:47:46.000Z","size":153,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-23T21:47:03.312Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Nim","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/Nimaoth.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,"zenodo":null}},"created_at":"2024-05-19T15:05:12.000Z","updated_at":"2025-04-19T23:48:26.000Z","dependencies_parsed_at":"2024-05-19T16:31:39.957Z","dependency_job_id":"4eb1ffb0-60c8-4848-ae56-09f9b9ac826a","html_url":"https://github.com/Nimaoth/nimsumtree","commit_stats":null,"previous_names":["nimaoth/nimsumtree"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Nimaoth/nimsumtree","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nimaoth%2Fnimsumtree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nimaoth%2Fnimsumtree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nimaoth%2Fnimsumtree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nimaoth%2Fnimsumtree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Nimaoth","download_url":"https://codeload.github.com/Nimaoth/nimsumtree/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Nimaoth%2Fnimsumtree/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265445431,"owners_count":23766475,"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":"2025-06-23T21:40:29.906Z","updated_at":"2026-02-27T05:37:24.066Z","avatar_url":"https://github.com/Nimaoth.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nimsumtree\n\nThis library provides three things:\n- A generic threadsafe [sumtree](src/nimsumtree/sumtree.nim), tree data structure similar to a B-tree, but each node stores user defined summaries of it's children.\n  Trees are immutable and it uses atomic RC so that trees can be shared across threads, but if only one reference to a node exists it will be mutated instead.\n- A [rope](src/nimsumtree/rope.nim) based on the sumtrees, for storing text and allowing efficient editing of large strings. Intended for e.g. text editors.\n- A [CRDT](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type) [text buffer](src/nimsumtree/buffer.nim), based on the rope and sumtree, for allowing collaborative editing of a text buffer.\n\nThe implementation is inspired by [Zed](https://github.com/zed-industries/zed)\n\n## Examples\n\n### Sumtree\n```nim\nimport nimsumtree/sumtree\n\ntype Count* = distinct int\ntype Max* = distinct int\n\ntype TestSummary* = object # Summary which is stored on each node\n  count*: Count\n  max*: Max\n\n# ... implement some functions for TestSummary, Count and Max to conform to some concepts\n# and associate TestSummary with the type `int`\n\n# Create a sum tree storing ints, with two children per node, and add the numbers 1, 3, and 5\n# This uses TestSummary implicitly because int.summaryType is TestSummary\nlet tree = SumTree[int].new(@[1, 3, 5])\n\necho tree # Arc(_3, #1, Internal(h: 1, (count: 3, max: 5), children: 2))\n\necho tree.pretty    # Internal(_3, #1, (count: 3, max: 5), 1):\n                    #   Leaf(_1, #1, (count: 2, max: 3), (1, 3))\n                    #   Leaf(_2, #1, (count: 1, max: 5), (5))\n\necho tree.summary   # (count: 3, max: 5)\n\n# Create a cursor to move along the tree and accumulate the Count and Max values of the summaries\n# (what a cursor accumulates can be a subset of the summary, or the summary itself)\n# var _ = tree.initCursor               # Accumulate nothing\n# var _ = tree.initCursor Count         # Accumulate only Count\n# var _ = tree.initCursor (Count, Max)  # Accumulate Count and Max\n# var _ = tree.initCursor TestSummary   # Accumulate the entire TestSummary\n\nvar c = tree.initCursor (Count, Max)  # Accumulate Count and Max\nassert c.seekForward(1.Count, Right)\necho c.itemSummary  # some((count: 1, max: 3))\necho c.startPos  # (1, 1): (Count, Max)\necho c.endPos  # (2, 3): (Count, Max)\n```\n\n### Rope\n```nim\nimport nimsumtree/rope\n# Note tha $ for rope is slow and should not be used regularly, this is only for demonstration\nvar a = Rope.new(\"Hello world!\")\nassert $a == \"Hello world!\"\na.replace((6, 11), \"you\")\nassert $a == \"Hello you!\"\n\nlet b: Rope = a.slice(6, 10)\nassert $b == \"you!\"\n```\n\n### Rope\n```nim\nimport nimsumtree/[buffer, rope]\nconst initialContent = \"Hello world!\"\n\n# doc1 and doc2 could be on separate computers\nvar doc1: Buffer = initBuffer(0.ReplicaId, initialContent)\nvar doc2: Buffer = initBuffer(1.ReplicaId, initialContent)\n\nlet ops1 = doc1.edit([(6..\u003c12, \"?\")])\nlet ops2 = doc2.edit([(6..\u003c11, \"you\")])\n\nassert $doc1.visibleText == \"Hello ?\"\nassert $doc2.visibleText == \"Hello you!\"\n\ndoc1.applyRemote(@[ops2])\ndoc2.applyRemote(@[ops1])\n\nassert $doc1.visibleText == \"Hello you?\"\nassert $doc2.visibleText == \"Hello you?\"\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimaoth%2Fnimsumtree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnimaoth%2Fnimsumtree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnimaoth%2Fnimsumtree/lists"}