{"id":29116996,"url":"https://github.com/gaissmai/bart","last_synced_at":"2025-06-29T11:14:12.883Z","repository":{"id":219611769,"uuid":"749458354","full_name":"gaissmai/bart","owner":"gaissmai","description":"The Balanced Routing Table is an adaptation of D. Knuth's ART algorithm and requires significantly less memory and has an even better lookup speed.","archived":false,"fork":false,"pushed_at":"2025-06-15T21:40:55.000Z","size":4387,"stargazers_count":72,"open_issues_count":0,"forks_count":7,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-15T23:18:56.446Z","etag":null,"topics":["art","cidr","cidr-lookup","cidr-overlap","ip","ip-blacklist","ip-lookup","ip-routing","ip-subnet","ip-whitelist","ipv6","longest-prefix-match"],"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/gaissmai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2024-01-28T16:41:09.000Z","updated_at":"2025-06-01T07:15:16.000Z","dependencies_parsed_at":"2024-04-24T09:54:22.486Z","dependency_job_id":"286c6a46-9f01-4e1a-a404-51cce5a47996","html_url":"https://github.com/gaissmai/bart","commit_stats":null,"previous_names":["gaissmai/bart"],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/gaissmai/bart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaissmai%2Fbart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaissmai%2Fbart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaissmai%2Fbart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaissmai%2Fbart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gaissmai","download_url":"https://codeload.github.com/gaissmai/bart/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaissmai%2Fbart/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262581514,"owners_count":23331925,"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":["art","cidr","cidr-lookup","cidr-overlap","ip","ip-blacklist","ip-lookup","ip-routing","ip-subnet","ip-whitelist","ipv6","longest-prefix-match"],"created_at":"2025-06-29T11:13:54.835Z","updated_at":"2025-06-29T11:14:12.844Z","avatar_url":"https://github.com/gaissmai.png","language":"Go","funding_links":[],"categories":["Networking","网络"],"sub_categories":["Transliteration","音译"],"readme":"# package bart\n\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/gaissmai/bart)\n[![Go Reference](https://pkg.go.dev/badge/github.com/gaissmai/bart.svg)](https://pkg.go.dev/github.com/gaissmai/bart#section-documentation)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go)\n[![CI](https://github.com/gaissmai/bart/actions/workflows/go.yml/badge.svg)](https://github.com/gaissmai/bart/actions/workflows/go.yml)\n[![Coverage Status](https://coveralls.io/repos/github/gaissmai/bart/badge.svg)](https://coveralls.io/github/gaissmai/bart)\n[![Go Report Card](https://goreportcard.com/badge/github.com/gaissmai/bart)](https://goreportcard.com/report/github.com/gaissmai/bart)\n[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)\n\n## Overview\n\n`package bart` provides a Balanced-Routing-Table (BART).\n\nBART is balanced in terms of memory usage and lookup time for the longest-prefix\nmatch.\n\nBART is a multibit-trie with fixed stride length of 8 bits, using a fast mapping\nfunction (taken from the ART algorithm) to map the 256 prefixes in each level\nnode to form a complete-binary-tree.\n\nThis complete binary tree is implemented with popcount compressed sparse arrays\ntogether with path compression. This reduces storage consumption by almost two\norders of magnitude in comparison to ART, with even better lookup times for the\nlongest prefix match.\n\nThe BART algorithm is based on fixed size bit vectors and precalculated\nlookup tables. The lookup is performed entirely by fast,\ncache-friendly bitmask operations, which in modern CPUs are performed\nby advanced bit manipulation instruction sets (POPCNT, LZCNT, TZCNT, ...).\n\nThe algorithm was specially developed so that it can always work with a fixed\nlength of 256 bits. This means that the bitset fit very well in a cache line and\nthat loops over the bitset in hot paths can be accelerated by loop unrolling, e.g.\n\n```go\nfunc (b *BitSet256) popcnt() (cnt int) {\n\tcnt += bits.OnesCount64(b[0])\n\tcnt += bits.OnesCount64(b[1])\n\tcnt += bits.OnesCount64(b[2])\n\tcnt += bits.OnesCount64(b[3])\n\treturn\n}\n```\n\nThe BART algorithm is also excellent for determining whether two tables\ncontain overlapping IP addresses, just in a few nanoseconds.\n\nA `bart.Lite` wrapper is included, this is ideal for simple IP\nACLs (access-control-lists) with plain true/false results and no payload.\n\n## Example\n\n```golang\nfunc ExampleLite_Contains() {\n\tlite := new(bart.Lite)\n\n\t// Insert some prefixes\n\tprefixes := []string{\n\t\t\"192.168.0.0/16\",\n\t\t\"192.168.1.0/24\",\n\t\t\"2001:7c0:3100::/40\",\n\t\t\"2001:7c0:3100:1::/64\",\n\t\t\"fc00::/7\",\n\t}\n\n\tfor _, s := range prefixes {\n\t\tpfx := netip.MustParsePrefix(s)\n\t\tlite.Insert(pfx)\n\t}\n\n\t// Test some IP addresses for black/whitelist containment\n\tips := []string{\n\t\t\"192.168.1.100\",      // must match\n\t\t\"192.168.2.1\",        // must match\n\t\t\"2001:7c0:3100:1::1\", // must match\n\t\t\"2001:7c0:3100:2::1\", // must match\n\t\t\"fc00::1\",            // must match\n\t\t//\n\t\t\"172.16.0.1\",        // must NOT match\n\t\t\"2003:dead:beef::1\", // must NOT match\n\t}\n\n\tfor _, s := range ips {\n\t\tip := netip.MustParseAddr(s)\n\t\tok := lite.Contains(ip)\n\t\tfmt.Printf(\"%-20s is contained: %t\\n\", ip, ok)\n\t}\n\n\t// Output:\n\t// 192.168.1.100        is contained: true\n\t// 192.168.2.1          is contained: true\n\t// 2001:7c0:3100:1::1   is contained: true\n\t// 2001:7c0:3100:2::1   is contained: true\n\t// fc00::1              is contained: true\n\t// 172.16.0.1           is contained: false\n\t// 2003:dead:beef::1    is contained: false\n}\n```\n## API\n\nFrom release v0.18.x on, bart requires at least go1.23, the `iter.Seq2[netip.Prefix, V]` types for iterators\nare used. The lock-free versions of insert, update and delete are added, but still experimental.\n\n```golang\n  import \"github.com/gaissmai/bart\"\n  \n  type Table[V any] struct {\n  \t// Has unexported fields.\n  }\n    // Table is an IPv4 and IPv6 routing table with payload V. The zero value is\n    // ready to use.\n\n    // The Table is safe for concurrent readers but not for concurrent readers\n    // and/or writers. Either the update operations must be protected by an\n    // external lock mechanism or the various ...Persist functions must be used\n    // which return a modified routing table by leaving the original unchanged\n\n    // A Table must not be copied by value.\n\n  func (t *Table[V]) Contains(ip netip.Addr) bool\n  func (t *Table[V]) Lookup(ip netip.Addr) (val V, ok bool)\n\n  func (t *Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool)\n  func (t *Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool)\n\n  func (t *Table[V]) Insert(pfx netip.Prefix, val V)\n  func (t *Table[V]) Delete(pfx netip.Prefix)\n  func (t *Table[V]) Update(pfx netip.Prefix, cb func(val V, ok bool) V) (newVal V)\n\n  func (t *Table[V]) InsertPersist(pfx netip.Prefix, val V) *Table[V]\n  func (t *Table[V]) DeletePersist(pfx netip.Prefix) *Table[V]\n  func (t *Table[V]) UpdatePersist(pfx netip.Prefix, cb func(val V, ok bool) V) (pt *Table[V], newVal V)\n\n  func (t *Table[V]) Get(pfx netip.Prefix) (val V, ok bool)\n  func (t *Table[V]) GetAndDelete(pfx netip.Prefix) (val V, ok bool)\n  func (t *Table[V]) GetAndDeletePersist(pfx netip.Prefix) (pt *Table[V], val V, ok bool)\n\n  func (t *Table[V]) Union(o *Table[V])\n  func (t *Table[V]) Clone() *Table[V]\n\n  func (t *Table[V]) OverlapsPrefix(pfx netip.Prefix) bool\n\n  func (t *Table[V]) Overlaps(o *Table[V])  bool\n  func (t *Table[V]) Overlaps4(o *Table[V]) bool\n  func (t *Table[V]) Overlaps6(o *Table[V]) bool\n\n  func (t *Table[V]) Subnets(pfx netip.Prefix)   iter.Seq2[netip.Prefix, V]\n  func (t *Table[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V]\n\n  func (t *Table[V]) All()  iter.Seq2[netip.Prefix, V]\n  func (t *Table[V]) All4() iter.Seq2[netip.Prefix, V]\n  func (t *Table[V]) All6() iter.Seq2[netip.Prefix, V]\n\n  func (t *Table[V]) AllSorted()  iter.Seq2[netip.Prefix, V]\n  func (t *Table[V]) AllSorted4() iter.Seq2[netip.Prefix, V]\n  func (t *Table[V]) AllSorted6() iter.Seq2[netip.Prefix, V]\n\n  func (t *Table[V]) Size()  int\n  func (t *Table[V]) Size4() int\n  func (t *Table[V]) Size6() int\n\n  func (t *Table[V]) String() string\n  func (t *Table[V]) Fprint(w io.Writer) error\n  func (t *Table[V]) MarshalText() ([]byte, error)\n  func (t *Table[V]) MarshalJSON() ([]byte, error)\n\n  func (t *Table[V]) DumpList4() []DumpListNode[V]\n  func (t *Table[V]) DumpList6() []DumpListNode[V]\n```\n\n## benchmarks\n\nPlease see the extensive [benchmarks](https://github.com/gaissmai/iprbench) comparing `bart` with other IP routing table implementations.\n\nJust a teaser, `Contains` and `Lookup` against the Tier1 full Internet routing table with\nrandom IP address probes:\n\n```\ngoos: linux\ngoarch: amd64\npkg: github.com/gaissmai/bart\ncpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz\nBenchmarkFullMatch4/Contains        129756907\t         8.409 ns/op\nBenchmarkFullMatch6/Contains        96855786\t        11.72 ns/op\nBenchmarkFullMiss4/Contains         56269990\t        18.58 ns/op\nBenchmarkFullMiss6/Contains         131779195\t        10.08 ns/op\n\ngoos: linux\ngoarch: amd64\npkg: github.com/gaissmai/bart\ncpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz\nBenchmarkFullMatch4/Lookup         \t47039798\t        24.44 ns/op\nBenchmarkFullMatch6/Lookup         \t81769753\t        13.61 ns/op\nBenchmarkFullMiss4/Lookup          \t51986374\t        22.72 ns/op\nBenchmarkFullMiss6/Lookup          \t100000000\t        11.47 ns/op\n```\n\n## Compatibility Guarantees\n\nThe package is currently released as a pre-v1 version, which gives the author the freedom to break\nbackward compatibility to help improve the API as he learns which initial design decisions would need\nto be revisited to better support the use cases that the library solves for.\n\nThese occurrences are expected to be rare in frequency and the API is already quite stable.\n\n## CONTRIBUTION\n\nPlease open an issue for discussion before sending a pull request.\n\n## CREDIT\n\nStanding on the shoulders of giants.\n\nCredits for many inspirations go to\n\n- the clever guys at tailscale,\n- to Daniel Lemire for his inspiring blog,\n- to Donald E. Knuth for the **ART** routing algorithm and\n- to Yoichi Hariguchi who deciphered it for us mere mortals\n\nAnd last but not least to the Go team who do a wonderful job!\n\n## LICENSE\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaissmai%2Fbart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgaissmai%2Fbart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaissmai%2Fbart/lists"}