Update dependencies

This commit is contained in:
bluepython508
2025-04-09 01:00:12 +01:00
parent f0641ffd6e
commit 5a9cfc022c
882 changed files with 68930 additions and 24201 deletions

27
vendor/github.com/gaissmai/bart/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,27 @@
# Allowlisting gitignore template for GO projects prevents us
# from adding various unwanted local files, such as generated
# files, developer configurations or IDE-specific files etc.
#
# Recommended: Go.AllowList.gitignore
# Ignore everything
*
# But not these files...
!/.gitignore
!*.yml
!*.yaml
!*.go
!go.sum
!go.mod
!*.md
!LICENSE*
# ...even if they are in subdirectories
!*/
!doc/*
!testdata/*

34
vendor/github.com/gaissmai/bart/.golangci.yml generated vendored Normal file
View File

@@ -0,0 +1,34 @@
linters:
enable:
- gofmt
- gofumpt
- goimports
- govet
- gosimple
- gocyclo
- gosmopolitan
- errcheck
- staticcheck
- intrange
- ineffassign
- unused
- typecheck
- unconvert
- unparam
- misspell
- decorder
- errorlint
- predeclared
- reassign
- stylecheck
- usestdlibvars
- wastedassign
- nakedret
#
# - gosec
# - dupl
# - wrapcheck
linters-settings:
gocyclo:
min-complexity: 30

View File

@@ -1,38 +1,88 @@
# package bart
[![Go Reference](https://pkg.go.dev/badge/github.com/gaissmai/bart.svg)](https://pkg.go.dev/github.com/gaissmai/bart#section-documentation)
![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/gaissmai/bart)
[![Go Reference](https://pkg.go.dev/badge/github.com/gaissmai/bart.svg)](https://pkg.go.dev/github.com/gaissmai/bart#section-documentation)
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go)
[![CI](https://github.com/gaissmai/bart/actions/workflows/go.yml/badge.svg)](https://github.com/gaissmai/bart/actions/workflows/go.yml)
[![Coverage Status](https://coveralls.io/repos/github/gaissmai/bart/badge.svg)](https://coveralls.io/github/gaissmai/bart)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Go Report Card](https://goreportcard.com/badge/github.com/gaissmai/bart)](https://goreportcard.com/report/github.com/gaissmai/bart)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://stand-with-ukraine.pp.ua)
## Overview
`package bart` provides a Balanced-Routing-Table (BART).
BART is balanced in terms of memory consumption versus
lookup time.
The lookup time is by a factor of ~2 slower on average as the
routing algorithms ART, SMART, CPE, ... but reduces the memory
consumption by an order of magnitude in comparison.
BART is balanced in terms of memory usage and lookup time
for the longest-prefix match.
BART is a multibit-trie with fixed stride length of 8 bits,
using the _baseIndex_ function from the ART algorithm to
build the complete-binary-tree (CBT) of prefixes for each stride.
The second key factor is popcount array compression at each stride level
of the CBT prefix tree and backtracking along the CBT in O(k).
The CBT is implemented as a bitvector, backtracking is just
The CBT is implemented as a bit-vector, backtracking is just
a matter of fast cache friendly bitmask operations.
The child array at each stride level is also popcount compressed.
The Table is implemented with popcount compressed sparse arrays
together with path compression. This reduces storage consumption
by almost two orders of magnitude in comparison to ART with
comparable or even better lookup times for longest prefix match.
The algorithm is also excellent for determining whether two tables
contain overlapping IP addresses.
## Example
```golang
func ExampleTable_Contains() {
// Create a new routing table
table := new(bart.Table[struct{}])
// Insert some prefixes
prefixes := []string{
"192.168.0.0/16", // corporate
"192.168.1.0/24", // department
"2001:7c0:3100::/40", // corporate
"2001:7c0:3100:1::/64", // department
"fc00::/7", // unique local
}
for _, s := range prefixes {
pfx := netip.MustParsePrefix(s)
table.Insert(pfx, struct{}{})
}
// Test some IP addresses for black/whitelist containment
ips := []string{
"192.168.1.100", // must match, department
"192.168.2.1", // must match, corporate
"2001:7c0:3100:1::1", // must match, department
"2001:7c0:3100:2::1", // must match, corporate
"fc00::1", // must match, unique local
//
"172.16.0.1", // must NOT match
"2003:dead:beef::1", // must NOT match
}
for _, s := range ips {
ip := netip.MustParseAddr(s)
fmt.Printf("%-20s is contained: %t\n", ip, table.Contains(ip))
}
// Output:
// 192.168.1.100 is contained: true
// 192.168.2.1 is contained: true
// 2001:7c0:3100:1::1 is contained: true
// 2001:7c0:3100:2::1 is contained: true
// fc00::1 is contained: true
// 172.16.0.1 is contained: false
// 2003:dead:beef::1 is contained: false
}
```
## API
The API changes in v0.4.2, 0.5.3, v0.6.3, v0.10.1, v0.11.0
Release v0.18 requires at least go1.23 and we use the `iter.Seq2[netip.Prefix, V]` types for iterators.
The lock-free versions of insert, update and delete are added, but still experimentell.
```golang
import "github.com/gaissmai/bart"
@@ -44,41 +94,53 @@ The API changes in v0.4.2, 0.5.3, v0.6.3, v0.10.1, v0.11.0
ready to use.
The Table is safe for concurrent readers but not for concurrent readers
and/or writers.
and/or writers. Either the update operations must be protected by an
external lock mechanism or the various ...Persist functions must be used
which return a modified routing table by leaving the original unchanged
A Table must not be copied by value, see Table.Clone.
func (t *Table[V]) Insert(pfx netip.Prefix, val V)
func (t *Table[V]) Delete(pfx netip.Prefix)
func (t *Table[V]) Get(pfx netip.Prefix) (val V, ok bool)
func (t *Table[V]) Update(pfx netip.Prefix, cb func(val V, ok bool) V) (newVal V)
func (t *Table[V]) InsertPersist(pfx netip.Prefix, val V) *Table[V]
func (t *Table[V]) DeletePersist(pfx netip.Prefix) *Table[V]
func (t *Table[V]) UpdatePersist(pfx netip.Prefix, cb func(val V, ok bool) V) (pt *Table[V], newVal V)
func (t *Table[V]) Get(pfx netip.Prefix) (val V, ok bool)
func (t *Table[V]) GetAndDelete(pfx netip.Prefix) (val V, ok bool)
func (t *Table[V]) GetAndDeletePersist(pfx netip.Prefix) (pt *Table[V], val V, ok bool)
func (t *Table[V]) Union(o *Table[V])
func (t *Table[V]) Clone() *Table[V]
func (t *Table[V]) Contains(ip netip.Addr) bool
func (t *Table[V]) Lookup(ip netip.Addr) (val V, ok bool)
func (t *Table[V]) LookupPrefix(pfx netip.Prefix) (val V, ok bool)
func (t *Table[V]) LookupPrefixLPM(pfx netip.Prefix) (lpm netip.Prefix, val V, ok bool)
func (t *Table[V]) EachLookupPrefix(pfx netip.Prefix, yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) EachSubnet(pfx netip.Prefix, yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) OverlapsPrefix(pfx netip.Prefix) bool
func (t *Table[V]) Overlaps(o *Table[V]) bool
func (t *Table[V]) Overlaps(o *Table[V]) bool
func (t *Table[V]) Overlaps4(o *Table[V]) bool
func (t *Table[V]) Overlaps6(o *Table[V]) bool
func (t *Table[V]) Subnets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V]
func (t *Table[V]) Supernets(pfx netip.Prefix) iter.Seq2[netip.Prefix, V]
func (t *Table[V]) All() iter.Seq2[netip.Prefix, V]
func (t *Table[V]) All4() iter.Seq2[netip.Prefix, V]
func (t *Table[V]) All6() iter.Seq2[netip.Prefix, V]
func (t *Table[V]) AllSorted() iter.Seq2[netip.Prefix, V]
func (t *Table[V]) AllSorted4() iter.Seq2[netip.Prefix, V]
func (t *Table[V]) AllSorted6() iter.Seq2[netip.Prefix, V]
func (t *Table[V]) Size() int
func (t *Table[V]) Size4() int
func (t *Table[V]) Size6() int
func (t *Table[V]) All(yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) All4(yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) All6(yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) AllSorted(yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) All4Sorted(yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) All6Sorted(yield func(pfx netip.Prefix, val V) bool)
func (t *Table[V]) String() string
func (t *Table[V]) Fprint(w io.Writer) error
func (t *Table[V]) MarshalText() ([]byte, error)
@@ -92,31 +154,56 @@ The API changes in v0.4.2, 0.5.3, v0.6.3, v0.10.1, v0.11.0
Please see the extensive [benchmarks](https://github.com/gaissmai/iprbench) comparing `bart` with other IP routing table implementations.
Just a teaser, LPM lookups against the full Internet routing table with random probes:
Just a teaser, Contains and Lookups against the full Internet routing table with random IP address probes:
```
goos: linux
goarch: amd64
pkg: github.com/gaissmai/bart
cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
BenchmarkFullMatchV4/Contains 55906228 21.39 ns/op 0 B/op 0 allocs/op
BenchmarkFullMatchV6/Contains 100000000 11.38 ns/op 0 B/op 0 allocs/op
BenchmarkFullMissV4/Contains 52927538 22.69 ns/op 0 B/op 0 allocs/op
BenchmarkFullMissV6/Contains 250386540 4.883 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/gaissmai/bart 11.291s
BenchmarkFullMatchV4/Lookup 24484828 49.03 ns/op
BenchmarkFullMatchV6/Lookup 17098262 70.15 ns/op
BenchmarkFullMissV4/Lookup 24480925 49.15 ns/op
BenchmarkFullMissV6/Lookup 54955310 21.79 ns/op
goos: linux
goarch: amd64
pkg: github.com/gaissmai/bart
cpu: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
BenchmarkFullMatchV4/Lookup 53578766 21.77 ns/op 0 B/op 0 allocs/op
BenchmarkFullMatchV6/Lookup 57054618 21.07 ns/op 0 B/op 0 allocs/op
BenchmarkFullMissV4/Lookup 48289306 25.60 ns/op 0 B/op 0 allocs/op
BenchmarkFullMissV6/Lookup 142917571 8.387 ns/op 0 B/op 0 allocs/op
PASS
ok github.com/gaissmai/bart 10.455s
```
## Compatibility Guarantees
The package is currently released as a pre-v1 version, which gives the author the freedom to break
backward compatibility to help improve the API as he learns which initial design decisions would need
to be revisited to better support the use cases that the library solves for.
These occurrences are expected to be rare in frequency and the API is already quite stable.
## CONTRIBUTION
Please open an issue for discussion before sending a pull request.
## CREDIT
Credits for many inspirations go to the clever guys at tailscale,
to Daniel Lemire for the super-fast bitset package and
to Donald E. Knuth for the **ART** routing algorithm and
all the rest of his *Art* and for keeping important algorithms
in the public domain!
Standing on the shoulders of giants.
Credits for many inspirations go to
- the clever guys at tailscale,
- to Daniel Lemire for his inspiring blog,
- to Donald E. Knuth for the **ART** routing algorithm and
- to Yoichi Hariguchi who deciphered it for us mere mortals
And last but not least to the Go team who do a wonderful job!
## LICENSE

5
vendor/github.com/gaissmai/bart/SECURITY.md generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# Security Policy
## Reporting a Vulnerability
You can report privately a vulnerability by email at karl.gaissmaier@uni-ulm.de (author and maintainer).

542
vendor/github.com/gaissmai/bart/allot_lookuptbl.go generated vendored Normal file
View File

@@ -0,0 +1,542 @@
// Copyright (c) 2024 Karl Gaissmaier
// SPDX-License-Identifier: MIT
package bart
import "github.com/gaissmai/bart/internal/bitset"
// allotLookupTbl, as precalculated bitsets,
// map the baseIndex to bitset with precomputed complete binary tree.
//
// // 1 <= idx <= 511
// func allotRec(aTbl *bitset.BitSet, idx uint) {
// aTbl = aTbl.Set(idx)
// if idx >= 256 {
// return
// }
// allotRec(aTbl, idx<<1)
// allotRec(aTbl, idx<<1+1)
// }
//
// Only used for fast bitset intersections instead of
// range loops in table overlaps methods.
//
// Please read the ART paper ./doc/artlookup.pdf to understand the allotment algorithm.
var allotLookupTbl = [512]bitset.BitSet{
/* idx: 0 */ {}, // idx is invalid
/* idx: 1 */ {0xfffffffffffffffe, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff},
/* idx: 2 */ {0xffff00ff0f34, 0xffffffff, 0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0xffffffffffffffff},
/* idx: 3 */ {0xffff0000ff00f0c8, 0xffffffff00000000, 0x0, 0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff, 0xffffffffffffffff},
/* idx: 4 */ {0xff000f0310, 0xffff, 0xffffffff, 0x0, 0xffffffffffffffff},
/* idx: 5 */ {0xff0000f00c20, 0xffff0000, 0xffffffff00000000, 0x0, 0x0, 0xffffffffffffffff},
/* idx: 6 */ {0xff00000f003040, 0xffff00000000, 0x0, 0xffffffff, 0x0, 0x0, 0xffffffffffffffff},
/* idx: 7 */ {0xff000000f000c080, 0xffff000000000000, 0x0, 0xffffffff00000000, 0x0, 0x0, 0x0, 0xffffffffffffffff},
/* idx: 8 */ {0xf00030100, 0xff, 0xffff, 0x0, 0xffffffff},
/* idx: 9 */ {0xf0000c0200, 0xff00, 0xffff0000, 0x0, 0xffffffff00000000},
/* idx: 10 */ {0xf0000300400, 0xff0000, 0xffff00000000, 0x0, 0x0, 0xffffffff},
/* idx: 11 */ {0xf00000c00800, 0xff000000, 0xffff000000000000, 0x0, 0x0, 0xffffffff00000000},
/* idx: 12 */ {0xf000003001000, 0xff00000000, 0x0, 0xffff, 0x0, 0x0, 0xffffffff},
/* idx: 13 */ {0xf000000c002000, 0xff0000000000, 0x0, 0xffff0000, 0x0, 0x0, 0xffffffff00000000},
/* idx: 14 */ {0xf00000030004000, 0xff000000000000, 0x0, 0xffff00000000, 0x0, 0x0, 0x0, 0xffffffff},
/* idx: 15 */ {0xf0000000c0008000, 0xff00000000000000, 0x0, 0xffff000000000000, 0x0, 0x0, 0x0, 0xffffffff00000000},
/* idx: 16 */ {0x300010000, 0xf, 0xff, 0x0, 0xffff},
/* idx: 17 */ {0xc00020000, 0xf0, 0xff00, 0x0, 0xffff0000},
/* idx: 18 */ {0x3000040000, 0xf00, 0xff0000, 0x0, 0xffff00000000},
/* idx: 19 */ {0xc000080000, 0xf000, 0xff000000, 0x0, 0xffff000000000000},
/* idx: 20 */ {0x30000100000, 0xf0000, 0xff00000000, 0x0, 0x0, 0xffff},
/* idx: 21 */ {0xc0000200000, 0xf00000, 0xff0000000000, 0x0, 0x0, 0xffff0000},
/* idx: 22 */ {0x300000400000, 0xf000000, 0xff000000000000, 0x0, 0x0, 0xffff00000000},
/* idx: 23 */ {0xc00000800000, 0xf0000000, 0xff00000000000000, 0x0, 0x0, 0xffff000000000000},
/* idx: 24 */ {0x3000001000000, 0xf00000000, 0x0, 0xff, 0x0, 0x0, 0xffff},
/* idx: 25 */ {0xc000002000000, 0xf000000000, 0x0, 0xff00, 0x0, 0x0, 0xffff0000},
/* idx: 26 */ {0x30000004000000, 0xf0000000000, 0x0, 0xff0000, 0x0, 0x0, 0xffff00000000},
/* idx: 27 */ {0xc0000008000000, 0xf00000000000, 0x0, 0xff000000, 0x0, 0x0, 0xffff000000000000},
/* idx: 28 */ {0x300000010000000, 0xf000000000000, 0x0, 0xff00000000, 0x0, 0x0, 0x0, 0xffff},
/* idx: 29 */ {0xc00000020000000, 0xf0000000000000, 0x0, 0xff0000000000, 0x0, 0x0, 0x0, 0xffff0000},
/* idx: 30 */ {0x3000000040000000, 0xf00000000000000, 0x0, 0xff000000000000, 0x0, 0x0, 0x0, 0xffff00000000},
/* idx: 31 */ {0xc000000080000000, 0xf000000000000000, 0x0, 0xff00000000000000, 0x0, 0x0, 0x0, 0xffff000000000000},
/* idx: 32 */ {0x100000000, 0x3, 0xf, 0x0, 0xff},
/* idx: 33 */ {0x200000000, 0xc, 0xf0, 0x0, 0xff00},
/* idx: 34 */ {0x400000000, 0x30, 0xf00, 0x0, 0xff0000},
/* idx: 35 */ {0x800000000, 0xc0, 0xf000, 0x0, 0xff000000},
/* idx: 36 */ {0x1000000000, 0x300, 0xf0000, 0x0, 0xff00000000},
/* idx: 37 */ {0x2000000000, 0xc00, 0xf00000, 0x0, 0xff0000000000},
/* idx: 38 */ {0x4000000000, 0x3000, 0xf000000, 0x0, 0xff000000000000},
/* idx: 39 */ {0x8000000000, 0xc000, 0xf0000000, 0x0, 0xff00000000000000},
/* idx: 40 */ {0x10000000000, 0x30000, 0xf00000000, 0x0, 0x0, 0xff},
/* idx: 41 */ {0x20000000000, 0xc0000, 0xf000000000, 0x0, 0x0, 0xff00},
/* idx: 42 */ {0x40000000000, 0x300000, 0xf0000000000, 0x0, 0x0, 0xff0000},
/* idx: 43 */ {0x80000000000, 0xc00000, 0xf00000000000, 0x0, 0x0, 0xff000000},
/* idx: 44 */ {0x100000000000, 0x3000000, 0xf000000000000, 0x0, 0x0, 0xff00000000},
/* idx: 45 */ {0x200000000000, 0xc000000, 0xf0000000000000, 0x0, 0x0, 0xff0000000000},
/* idx: 46 */ {0x400000000000, 0x30000000, 0xf00000000000000, 0x0, 0x0, 0xff000000000000},
/* idx: 47 */ {0x800000000000, 0xc0000000, 0xf000000000000000, 0x0, 0x0, 0xff00000000000000},
/* idx: 48 */ {0x1000000000000, 0x300000000, 0x0, 0xf, 0x0, 0x0, 0xff},
/* idx: 49 */ {0x2000000000000, 0xc00000000, 0x0, 0xf0, 0x0, 0x0, 0xff00},
/* idx: 50 */ {0x4000000000000, 0x3000000000, 0x0, 0xf00, 0x0, 0x0, 0xff0000},
/* idx: 51 */ {0x8000000000000, 0xc000000000, 0x0, 0xf000, 0x0, 0x0, 0xff000000},
/* idx: 52 */ {0x10000000000000, 0x30000000000, 0x0, 0xf0000, 0x0, 0x0, 0xff00000000},
/* idx: 53 */ {0x20000000000000, 0xc0000000000, 0x0, 0xf00000, 0x0, 0x0, 0xff0000000000},
/* idx: 54 */ {0x40000000000000, 0x300000000000, 0x0, 0xf000000, 0x0, 0x0, 0xff000000000000},
/* idx: 55 */ {0x80000000000000, 0xc00000000000, 0x0, 0xf0000000, 0x0, 0x0, 0xff00000000000000},
/* idx: 56 */ {0x100000000000000, 0x3000000000000, 0x0, 0xf00000000, 0x0, 0x0, 0x0, 0xff},
/* idx: 57 */ {0x200000000000000, 0xc000000000000, 0x0, 0xf000000000, 0x0, 0x0, 0x0, 0xff00},
/* idx: 58 */ {0x400000000000000, 0x30000000000000, 0x0, 0xf0000000000, 0x0, 0x0, 0x0, 0xff0000},
/* idx: 59 */ {0x800000000000000, 0xc0000000000000, 0x0, 0xf00000000000, 0x0, 0x0, 0x0, 0xff000000},
/* idx: 60 */ {0x1000000000000000, 0x300000000000000, 0x0, 0xf000000000000, 0x0, 0x0, 0x0, 0xff00000000},
/* idx: 61 */ {0x2000000000000000, 0xc00000000000000, 0x0, 0xf0000000000000, 0x0, 0x0, 0x0, 0xff0000000000},
/* idx: 62 */ {0x4000000000000000, 0x3000000000000000, 0x0, 0xf00000000000000, 0x0, 0x0, 0x0, 0xff000000000000},
/* idx: 63 */ {0x8000000000000000, 0xc000000000000000, 0x0, 0xf000000000000000, 0x0, 0x0, 0x0, 0xff00000000000000},
/* idx: 64 */ {0x0, 0x1, 0x3, 0x0, 0xf},
/* idx: 65 */ {0x0, 0x2, 0xc, 0x0, 0xf0},
/* idx: 66 */ {0x0, 0x4, 0x30, 0x0, 0xf00},
/* idx: 67 */ {0x0, 0x8, 0xc0, 0x0, 0xf000},
/* idx: 68 */ {0x0, 0x10, 0x300, 0x0, 0xf0000},
/* idx: 69 */ {0x0, 0x20, 0xc00, 0x0, 0xf00000},
/* idx: 70 */ {0x0, 0x40, 0x3000, 0x0, 0xf000000},
/* idx: 71 */ {0x0, 0x80, 0xc000, 0x0, 0xf0000000},
/* idx: 72 */ {0x0, 0x100, 0x30000, 0x0, 0xf00000000},
/* idx: 73 */ {0x0, 0x200, 0xc0000, 0x0, 0xf000000000},
/* idx: 74 */ {0x0, 0x400, 0x300000, 0x0, 0xf0000000000},
/* idx: 75 */ {0x0, 0x800, 0xc00000, 0x0, 0xf00000000000},
/* idx: 76 */ {0x0, 0x1000, 0x3000000, 0x0, 0xf000000000000},
/* idx: 77 */ {0x0, 0x2000, 0xc000000, 0x0, 0xf0000000000000},
/* idx: 78 */ {0x0, 0x4000, 0x30000000, 0x0, 0xf00000000000000},
/* idx: 79 */ {0x0, 0x8000, 0xc0000000, 0x0, 0xf000000000000000},
/* idx: 80 */ {0x0, 0x10000, 0x300000000, 0x0, 0x0, 0xf},
/* idx: 81 */ {0x0, 0x20000, 0xc00000000, 0x0, 0x0, 0xf0},
/* idx: 82 */ {0x0, 0x40000, 0x3000000000, 0x0, 0x0, 0xf00},
/* idx: 83 */ {0x0, 0x80000, 0xc000000000, 0x0, 0x0, 0xf000},
/* idx: 84 */ {0x0, 0x100000, 0x30000000000, 0x0, 0x0, 0xf0000},
/* idx: 85 */ {0x0, 0x200000, 0xc0000000000, 0x0, 0x0, 0xf00000},
/* idx: 86 */ {0x0, 0x400000, 0x300000000000, 0x0, 0x0, 0xf000000},
/* idx: 87 */ {0x0, 0x800000, 0xc00000000000, 0x0, 0x0, 0xf0000000},
/* idx: 88 */ {0x0, 0x1000000, 0x3000000000000, 0x0, 0x0, 0xf00000000},
/* idx: 89 */ {0x0, 0x2000000, 0xc000000000000, 0x0, 0x0, 0xf000000000},
/* idx: 90 */ {0x0, 0x4000000, 0x30000000000000, 0x0, 0x0, 0xf0000000000},
/* idx: 91 */ {0x0, 0x8000000, 0xc0000000000000, 0x0, 0x0, 0xf00000000000},
/* idx: 92 */ {0x0, 0x10000000, 0x300000000000000, 0x0, 0x0, 0xf000000000000},
/* idx: 93 */ {0x0, 0x20000000, 0xc00000000000000, 0x0, 0x0, 0xf0000000000000},
/* idx: 94 */ {0x0, 0x40000000, 0x3000000000000000, 0x0, 0x0, 0xf00000000000000},
/* idx: 95 */ {0x0, 0x80000000, 0xc000000000000000, 0x0, 0x0, 0xf000000000000000},
/* idx: 96 */ {0x0, 0x100000000, 0x0, 0x3, 0x0, 0x0, 0xf},
/* idx: 97 */ {0x0, 0x200000000, 0x0, 0xc, 0x0, 0x0, 0xf0},
/* idx: 98 */ {0x0, 0x400000000, 0x0, 0x30, 0x0, 0x0, 0xf00},
/* idx: 99 */ {0x0, 0x800000000, 0x0, 0xc0, 0x0, 0x0, 0xf000},
/* idx: 100 */ {0x0, 0x1000000000, 0x0, 0x300, 0x0, 0x0, 0xf0000},
/* idx: 101 */ {0x0, 0x2000000000, 0x0, 0xc00, 0x0, 0x0, 0xf00000},
/* idx: 102 */ {0x0, 0x4000000000, 0x0, 0x3000, 0x0, 0x0, 0xf000000},
/* idx: 103 */ {0x0, 0x8000000000, 0x0, 0xc000, 0x0, 0x0, 0xf0000000},
/* idx: 104 */ {0x0, 0x10000000000, 0x0, 0x30000, 0x0, 0x0, 0xf00000000},
/* idx: 105 */ {0x0, 0x20000000000, 0x0, 0xc0000, 0x0, 0x0, 0xf000000000},
/* idx: 106 */ {0x0, 0x40000000000, 0x0, 0x300000, 0x0, 0x0, 0xf0000000000},
/* idx: 107 */ {0x0, 0x80000000000, 0x0, 0xc00000, 0x0, 0x0, 0xf00000000000},
/* idx: 108 */ {0x0, 0x100000000000, 0x0, 0x3000000, 0x0, 0x0, 0xf000000000000},
/* idx: 109 */ {0x0, 0x200000000000, 0x0, 0xc000000, 0x0, 0x0, 0xf0000000000000},
/* idx: 110 */ {0x0, 0x400000000000, 0x0, 0x30000000, 0x0, 0x0, 0xf00000000000000},
/* idx: 111 */ {0x0, 0x800000000000, 0x0, 0xc0000000, 0x0, 0x0, 0xf000000000000000},
/* idx: 112 */ {0x0, 0x1000000000000, 0x0, 0x300000000, 0x0, 0x0, 0x0, 0xf},
/* idx: 113 */ {0x0, 0x2000000000000, 0x0, 0xc00000000, 0x0, 0x0, 0x0, 0xf0},
/* idx: 114 */ {0x0, 0x4000000000000, 0x0, 0x3000000000, 0x0, 0x0, 0x0, 0xf00},
/* idx: 115 */ {0x0, 0x8000000000000, 0x0, 0xc000000000, 0x0, 0x0, 0x0, 0xf000},
/* idx: 116 */ {0x0, 0x10000000000000, 0x0, 0x30000000000, 0x0, 0x0, 0x0, 0xf0000},
/* idx: 117 */ {0x0, 0x20000000000000, 0x0, 0xc0000000000, 0x0, 0x0, 0x0, 0xf00000},
/* idx: 118 */ {0x0, 0x40000000000000, 0x0, 0x300000000000, 0x0, 0x0, 0x0, 0xf000000},
/* idx: 119 */ {0x0, 0x80000000000000, 0x0, 0xc00000000000, 0x0, 0x0, 0x0, 0xf0000000},
/* idx: 120 */ {0x0, 0x100000000000000, 0x0, 0x3000000000000, 0x0, 0x0, 0x0, 0xf00000000},
/* idx: 121 */ {0x0, 0x200000000000000, 0x0, 0xc000000000000, 0x0, 0x0, 0x0, 0xf000000000},
/* idx: 122 */ {0x0, 0x400000000000000, 0x0, 0x30000000000000, 0x0, 0x0, 0x0, 0xf0000000000},
/* idx: 123 */ {0x0, 0x800000000000000, 0x0, 0xc0000000000000, 0x0, 0x0, 0x0, 0xf00000000000},
/* idx: 124 */ {0x0, 0x1000000000000000, 0x0, 0x300000000000000, 0x0, 0x0, 0x0, 0xf000000000000},
/* idx: 125 */ {0x0, 0x2000000000000000, 0x0, 0xc00000000000000, 0x0, 0x0, 0x0, 0xf0000000000000},
/* idx: 126 */ {0x0, 0x4000000000000000, 0x0, 0x3000000000000000, 0x0, 0x0, 0x0, 0xf00000000000000},
/* idx: 127 */ {0x0, 0x8000000000000000, 0x0, 0xc000000000000000, 0x0, 0x0, 0x0, 0xf000000000000000},
/* idx: 128 */ {0x0, 0x0, 0x1, 0x0, 0x3},
/* idx: 129 */ {0x0, 0x0, 0x2, 0x0, 0xc},
/* idx: 130 */ {0x0, 0x0, 0x4, 0x0, 0x30},
/* idx: 131 */ {0x0, 0x0, 0x8, 0x0, 0xc0},
/* idx: 132 */ {0x0, 0x0, 0x10, 0x0, 0x300},
/* idx: 133 */ {0x0, 0x0, 0x20, 0x0, 0xc00},
/* idx: 134 */ {0x0, 0x0, 0x40, 0x0, 0x3000},
/* idx: 135 */ {0x0, 0x0, 0x80, 0x0, 0xc000},
/* idx: 136 */ {0x0, 0x0, 0x100, 0x0, 0x30000},
/* idx: 137 */ {0x0, 0x0, 0x200, 0x0, 0xc0000},
/* idx: 138 */ {0x0, 0x0, 0x400, 0x0, 0x300000},
/* idx: 139 */ {0x0, 0x0, 0x800, 0x0, 0xc00000},
/* idx: 140 */ {0x0, 0x0, 0x1000, 0x0, 0x3000000},
/* idx: 141 */ {0x0, 0x0, 0x2000, 0x0, 0xc000000},
/* idx: 142 */ {0x0, 0x0, 0x4000, 0x0, 0x30000000},
/* idx: 143 */ {0x0, 0x0, 0x8000, 0x0, 0xc0000000},
/* idx: 144 */ {0x0, 0x0, 0x10000, 0x0, 0x300000000},
/* idx: 145 */ {0x0, 0x0, 0x20000, 0x0, 0xc00000000},
/* idx: 146 */ {0x0, 0x0, 0x40000, 0x0, 0x3000000000},
/* idx: 147 */ {0x0, 0x0, 0x80000, 0x0, 0xc000000000},
/* idx: 148 */ {0x0, 0x0, 0x100000, 0x0, 0x30000000000},
/* idx: 149 */ {0x0, 0x0, 0x200000, 0x0, 0xc0000000000},
/* idx: 150 */ {0x0, 0x0, 0x400000, 0x0, 0x300000000000},
/* idx: 151 */ {0x0, 0x0, 0x800000, 0x0, 0xc00000000000},
/* idx: 152 */ {0x0, 0x0, 0x1000000, 0x0, 0x3000000000000},
/* idx: 153 */ {0x0, 0x0, 0x2000000, 0x0, 0xc000000000000},
/* idx: 154 */ {0x0, 0x0, 0x4000000, 0x0, 0x30000000000000},
/* idx: 155 */ {0x0, 0x0, 0x8000000, 0x0, 0xc0000000000000},
/* idx: 156 */ {0x0, 0x0, 0x10000000, 0x0, 0x300000000000000},
/* idx: 157 */ {0x0, 0x0, 0x20000000, 0x0, 0xc00000000000000},
/* idx: 158 */ {0x0, 0x0, 0x40000000, 0x0, 0x3000000000000000},
/* idx: 159 */ {0x0, 0x0, 0x80000000, 0x0, 0xc000000000000000},
/* idx: 160 */ {0x0, 0x0, 0x100000000, 0x0, 0x0, 0x3},
/* idx: 161 */ {0x0, 0x0, 0x200000000, 0x0, 0x0, 0xc},
/* idx: 162 */ {0x0, 0x0, 0x400000000, 0x0, 0x0, 0x30},
/* idx: 163 */ {0x0, 0x0, 0x800000000, 0x0, 0x0, 0xc0},
/* idx: 164 */ {0x0, 0x0, 0x1000000000, 0x0, 0x0, 0x300},
/* idx: 165 */ {0x0, 0x0, 0x2000000000, 0x0, 0x0, 0xc00},
/* idx: 166 */ {0x0, 0x0, 0x4000000000, 0x0, 0x0, 0x3000},
/* idx: 167 */ {0x0, 0x0, 0x8000000000, 0x0, 0x0, 0xc000},
/* idx: 168 */ {0x0, 0x0, 0x10000000000, 0x0, 0x0, 0x30000},
/* idx: 169 */ {0x0, 0x0, 0x20000000000, 0x0, 0x0, 0xc0000},
/* idx: 170 */ {0x0, 0x0, 0x40000000000, 0x0, 0x0, 0x300000},
/* idx: 171 */ {0x0, 0x0, 0x80000000000, 0x0, 0x0, 0xc00000},
/* idx: 172 */ {0x0, 0x0, 0x100000000000, 0x0, 0x0, 0x3000000},
/* idx: 173 */ {0x0, 0x0, 0x200000000000, 0x0, 0x0, 0xc000000},
/* idx: 174 */ {0x0, 0x0, 0x400000000000, 0x0, 0x0, 0x30000000},
/* idx: 175 */ {0x0, 0x0, 0x800000000000, 0x0, 0x0, 0xc0000000},
/* idx: 176 */ {0x0, 0x0, 0x1000000000000, 0x0, 0x0, 0x300000000},
/* idx: 177 */ {0x0, 0x0, 0x2000000000000, 0x0, 0x0, 0xc00000000},
/* idx: 178 */ {0x0, 0x0, 0x4000000000000, 0x0, 0x0, 0x3000000000},
/* idx: 179 */ {0x0, 0x0, 0x8000000000000, 0x0, 0x0, 0xc000000000},
/* idx: 180 */ {0x0, 0x0, 0x10000000000000, 0x0, 0x0, 0x30000000000},
/* idx: 181 */ {0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0xc0000000000},
/* idx: 182 */ {0x0, 0x0, 0x40000000000000, 0x0, 0x0, 0x300000000000},
/* idx: 183 */ {0x0, 0x0, 0x80000000000000, 0x0, 0x0, 0xc00000000000},
/* idx: 184 */ {0x0, 0x0, 0x100000000000000, 0x0, 0x0, 0x3000000000000},
/* idx: 185 */ {0x0, 0x0, 0x200000000000000, 0x0, 0x0, 0xc000000000000},
/* idx: 186 */ {0x0, 0x0, 0x400000000000000, 0x0, 0x0, 0x30000000000000},
/* idx: 187 */ {0x0, 0x0, 0x800000000000000, 0x0, 0x0, 0xc0000000000000},
/* idx: 188 */ {0x0, 0x0, 0x1000000000000000, 0x0, 0x0, 0x300000000000000},
/* idx: 189 */ {0x0, 0x0, 0x2000000000000000, 0x0, 0x0, 0xc00000000000000},
/* idx: 190 */ {0x0, 0x0, 0x4000000000000000, 0x0, 0x0, 0x3000000000000000},
/* idx: 191 */ {0x0, 0x0, 0x8000000000000000, 0x0, 0x0, 0xc000000000000000},
/* idx: 192 */ {0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x3},
/* idx: 193 */ {0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0xc},
/* idx: 194 */ {0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x30},
/* idx: 195 */ {0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0xc0},
/* idx: 196 */ {0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x300},
/* idx: 197 */ {0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0xc00},
/* idx: 198 */ {0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x3000},
/* idx: 199 */ {0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0xc000},
/* idx: 200 */ {0x0, 0x0, 0x0, 0x100, 0x0, 0x0, 0x30000},
/* idx: 201 */ {0x0, 0x0, 0x0, 0x200, 0x0, 0x0, 0xc0000},
/* idx: 202 */ {0x0, 0x0, 0x0, 0x400, 0x0, 0x0, 0x300000},
/* idx: 203 */ {0x0, 0x0, 0x0, 0x800, 0x0, 0x0, 0xc00000},
/* idx: 204 */ {0x0, 0x0, 0x0, 0x1000, 0x0, 0x0, 0x3000000},
/* idx: 205 */ {0x0, 0x0, 0x0, 0x2000, 0x0, 0x0, 0xc000000},
/* idx: 206 */ {0x0, 0x0, 0x0, 0x4000, 0x0, 0x0, 0x30000000},
/* idx: 207 */ {0x0, 0x0, 0x0, 0x8000, 0x0, 0x0, 0xc0000000},
/* idx: 208 */ {0x0, 0x0, 0x0, 0x10000, 0x0, 0x0, 0x300000000},
/* idx: 209 */ {0x0, 0x0, 0x0, 0x20000, 0x0, 0x0, 0xc00000000},
/* idx: 210 */ {0x0, 0x0, 0x0, 0x40000, 0x0, 0x0, 0x3000000000},
/* idx: 211 */ {0x0, 0x0, 0x0, 0x80000, 0x0, 0x0, 0xc000000000},
/* idx: 212 */ {0x0, 0x0, 0x0, 0x100000, 0x0, 0x0, 0x30000000000},
/* idx: 213 */ {0x0, 0x0, 0x0, 0x200000, 0x0, 0x0, 0xc0000000000},
/* idx: 214 */ {0x0, 0x0, 0x0, 0x400000, 0x0, 0x0, 0x300000000000},
/* idx: 215 */ {0x0, 0x0, 0x0, 0x800000, 0x0, 0x0, 0xc00000000000},
/* idx: 216 */ {0x0, 0x0, 0x0, 0x1000000, 0x0, 0x0, 0x3000000000000},
/* idx: 217 */ {0x0, 0x0, 0x0, 0x2000000, 0x0, 0x0, 0xc000000000000},
/* idx: 218 */ {0x0, 0x0, 0x0, 0x4000000, 0x0, 0x0, 0x30000000000000},
/* idx: 219 */ {0x0, 0x0, 0x0, 0x8000000, 0x0, 0x0, 0xc0000000000000},
/* idx: 220 */ {0x0, 0x0, 0x0, 0x10000000, 0x0, 0x0, 0x300000000000000},
/* idx: 221 */ {0x0, 0x0, 0x0, 0x20000000, 0x0, 0x0, 0xc00000000000000},
/* idx: 222 */ {0x0, 0x0, 0x0, 0x40000000, 0x0, 0x0, 0x3000000000000000},
/* idx: 223 */ {0x0, 0x0, 0x0, 0x80000000, 0x0, 0x0, 0xc000000000000000},
/* idx: 224 */ {0x0, 0x0, 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x3},
/* idx: 225 */ {0x0, 0x0, 0x0, 0x200000000, 0x0, 0x0, 0x0, 0xc},
/* idx: 226 */ {0x0, 0x0, 0x0, 0x400000000, 0x0, 0x0, 0x0, 0x30},
/* idx: 227 */ {0x0, 0x0, 0x0, 0x800000000, 0x0, 0x0, 0x0, 0xc0},
/* idx: 228 */ {0x0, 0x0, 0x0, 0x1000000000, 0x0, 0x0, 0x0, 0x300},
/* idx: 229 */ {0x0, 0x0, 0x0, 0x2000000000, 0x0, 0x0, 0x0, 0xc00},
/* idx: 230 */ {0x0, 0x0, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x3000},
/* idx: 231 */ {0x0, 0x0, 0x0, 0x8000000000, 0x0, 0x0, 0x0, 0xc000},
/* idx: 232 */ {0x0, 0x0, 0x0, 0x10000000000, 0x0, 0x0, 0x0, 0x30000},
/* idx: 233 */ {0x0, 0x0, 0x0, 0x20000000000, 0x0, 0x0, 0x0, 0xc0000},
/* idx: 234 */ {0x0, 0x0, 0x0, 0x40000000000, 0x0, 0x0, 0x0, 0x300000},
/* idx: 235 */ {0x0, 0x0, 0x0, 0x80000000000, 0x0, 0x0, 0x0, 0xc00000},
/* idx: 236 */ {0x0, 0x0, 0x0, 0x100000000000, 0x0, 0x0, 0x0, 0x3000000},
/* idx: 237 */ {0x0, 0x0, 0x0, 0x200000000000, 0x0, 0x0, 0x0, 0xc000000},
/* idx: 238 */ {0x0, 0x0, 0x0, 0x400000000000, 0x0, 0x0, 0x0, 0x30000000},
/* idx: 239 */ {0x0, 0x0, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0xc0000000},
/* idx: 240 */ {0x0, 0x0, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x300000000},
/* idx: 241 */ {0x0, 0x0, 0x0, 0x2000000000000, 0x0, 0x0, 0x0, 0xc00000000},
/* idx: 242 */ {0x0, 0x0, 0x0, 0x4000000000000, 0x0, 0x0, 0x0, 0x3000000000},
/* idx: 243 */ {0x0, 0x0, 0x0, 0x8000000000000, 0x0, 0x0, 0x0, 0xc000000000},
/* idx: 244 */ {0x0, 0x0, 0x0, 0x10000000000000, 0x0, 0x0, 0x0, 0x30000000000},
/* idx: 245 */ {0x0, 0x0, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0xc0000000000},
/* idx: 246 */ {0x0, 0x0, 0x0, 0x40000000000000, 0x0, 0x0, 0x0, 0x300000000000},
/* idx: 247 */ {0x0, 0x0, 0x0, 0x80000000000000, 0x0, 0x0, 0x0, 0xc00000000000},
/* idx: 248 */ {0x0, 0x0, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0x3000000000000},
/* idx: 249 */ {0x0, 0x0, 0x0, 0x200000000000000, 0x0, 0x0, 0x0, 0xc000000000000},
/* idx: 250 */ {0x0, 0x0, 0x0, 0x400000000000000, 0x0, 0x0, 0x0, 0x30000000000000},
/* idx: 251 */ {0x0, 0x0, 0x0, 0x800000000000000, 0x0, 0x0, 0x0, 0xc0000000000000},
/* idx: 252 */ {0x0, 0x0, 0x0, 0x1000000000000000, 0x0, 0x0, 0x0, 0x300000000000000},
/* idx: 253 */ {0x0, 0x0, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0xc00000000000000},
/* idx: 254 */ {0x0, 0x0, 0x0, 0x4000000000000000, 0x0, 0x0, 0x0, 0x3000000000000000},
/* idx: 255 */ {0x0, 0x0, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0xc000000000000000},
//
// START of HOST ROUTES, pfxLen == 8
// [:4] are all 0 and only one bit is set in [4:]
//
/* idx: 256 */ {0x0, 0x0, 0x0, 0x0, 0x1},
/* idx: 257 */ {0x0, 0x0, 0x0, 0x0, 0x2},
/* idx: 258 */ {0x0, 0x0, 0x0, 0x0, 0x4},
/* idx: 259 */ {0x0, 0x0, 0x0, 0x0, 0x8},
/* idx: 260 */ {0x0, 0x0, 0x0, 0x0, 0x10},
/* idx: 261 */ {0x0, 0x0, 0x0, 0x0, 0x20},
/* idx: 262 */ {0x0, 0x0, 0x0, 0x0, 0x40},
/* idx: 263 */ {0x0, 0x0, 0x0, 0x0, 0x80},
/* idx: 264 */ {0x0, 0x0, 0x0, 0x0, 0x100},
/* idx: 265 */ {0x0, 0x0, 0x0, 0x0, 0x200},
/* idx: 266 */ {0x0, 0x0, 0x0, 0x0, 0x400},
/* idx: 267 */ {0x0, 0x0, 0x0, 0x0, 0x800},
/* idx: 268 */ {0x0, 0x0, 0x0, 0x0, 0x1000},
/* idx: 269 */ {0x0, 0x0, 0x0, 0x0, 0x2000},
/* idx: 270 */ {0x0, 0x0, 0x0, 0x0, 0x4000},
/* idx: 271 */ {0x0, 0x0, 0x0, 0x0, 0x8000},
/* idx: 272 */ {0x0, 0x0, 0x0, 0x0, 0x10000},
/* idx: 273 */ {0x0, 0x0, 0x0, 0x0, 0x20000},
/* idx: 274 */ {0x0, 0x0, 0x0, 0x0, 0x40000},
/* idx: 275 */ {0x0, 0x0, 0x0, 0x0, 0x80000},
/* idx: 276 */ {0x0, 0x0, 0x0, 0x0, 0x100000},
/* idx: 277 */ {0x0, 0x0, 0x0, 0x0, 0x200000},
/* idx: 278 */ {0x0, 0x0, 0x0, 0x0, 0x400000},
/* idx: 279 */ {0x0, 0x0, 0x0, 0x0, 0x800000},
/* idx: 280 */ {0x0, 0x0, 0x0, 0x0, 0x1000000},
/* idx: 281 */ {0x0, 0x0, 0x0, 0x0, 0x2000000},
/* idx: 282 */ {0x0, 0x0, 0x0, 0x0, 0x4000000},
/* idx: 283 */ {0x0, 0x0, 0x0, 0x0, 0x8000000},
/* idx: 284 */ {0x0, 0x0, 0x0, 0x0, 0x10000000},
/* idx: 285 */ {0x0, 0x0, 0x0, 0x0, 0x20000000},
/* idx: 286 */ {0x0, 0x0, 0x0, 0x0, 0x40000000},
/* idx: 287 */ {0x0, 0x0, 0x0, 0x0, 0x80000000},
/* idx: 288 */ {0x0, 0x0, 0x0, 0x0, 0x100000000},
/* idx: 289 */ {0x0, 0x0, 0x0, 0x0, 0x200000000},
/* idx: 290 */ {0x0, 0x0, 0x0, 0x0, 0x400000000},
/* idx: 291 */ {0x0, 0x0, 0x0, 0x0, 0x800000000},
/* idx: 292 */ {0x0, 0x0, 0x0, 0x0, 0x1000000000},
/* idx: 293 */ {0x0, 0x0, 0x0, 0x0, 0x2000000000},
/* idx: 294 */ {0x0, 0x0, 0x0, 0x0, 0x4000000000},
/* idx: 295 */ {0x0, 0x0, 0x0, 0x0, 0x8000000000},
/* idx: 296 */ {0x0, 0x0, 0x0, 0x0, 0x10000000000},
/* idx: 297 */ {0x0, 0x0, 0x0, 0x0, 0x20000000000},
/* idx: 298 */ {0x0, 0x0, 0x0, 0x0, 0x40000000000},
/* idx: 299 */ {0x0, 0x0, 0x0, 0x0, 0x80000000000},
/* idx: 300 */ {0x0, 0x0, 0x0, 0x0, 0x100000000000},
/* idx: 301 */ {0x0, 0x0, 0x0, 0x0, 0x200000000000},
/* idx: 302 */ {0x0, 0x0, 0x0, 0x0, 0x400000000000},
/* idx: 303 */ {0x0, 0x0, 0x0, 0x0, 0x800000000000},
/* idx: 304 */ {0x0, 0x0, 0x0, 0x0, 0x1000000000000},
/* idx: 305 */ {0x0, 0x0, 0x0, 0x0, 0x2000000000000},
/* idx: 306 */ {0x0, 0x0, 0x0, 0x0, 0x4000000000000},
/* idx: 307 */ {0x0, 0x0, 0x0, 0x0, 0x8000000000000},
/* idx: 308 */ {0x0, 0x0, 0x0, 0x0, 0x10000000000000},
/* idx: 309 */ {0x0, 0x0, 0x0, 0x0, 0x20000000000000},
/* idx: 310 */ {0x0, 0x0, 0x0, 0x0, 0x40000000000000},
/* idx: 311 */ {0x0, 0x0, 0x0, 0x0, 0x80000000000000},
/* idx: 312 */ {0x0, 0x0, 0x0, 0x0, 0x100000000000000},
/* idx: 313 */ {0x0, 0x0, 0x0, 0x0, 0x200000000000000},
/* idx: 314 */ {0x0, 0x0, 0x0, 0x0, 0x400000000000000},
/* idx: 315 */ {0x0, 0x0, 0x0, 0x0, 0x800000000000000},
/* idx: 316 */ {0x0, 0x0, 0x0, 0x0, 0x1000000000000000},
/* idx: 317 */ {0x0, 0x0, 0x0, 0x0, 0x2000000000000000},
/* idx: 318 */ {0x0, 0x0, 0x0, 0x0, 0x4000000000000000},
/* idx: 319 */ {0x0, 0x0, 0x0, 0x0, 0x8000000000000000},
/* idx: 320 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1},
/* idx: 321 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
/* idx: 322 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4},
/* idx: 323 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
/* idx: 324 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10},
/* idx: 325 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20},
/* idx: 326 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40},
/* idx: 327 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80},
/* idx: 328 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100},
/* idx: 329 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200},
/* idx: 330 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400},
/* idx: 331 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800},
/* idx: 332 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000},
/* idx: 333 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000},
/* idx: 334 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000},
/* idx: 335 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000},
/* idx: 336 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000},
/* idx: 337 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000},
/* idx: 338 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000},
/* idx: 339 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000},
/* idx: 340 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000},
/* idx: 341 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000},
/* idx: 342 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000},
/* idx: 343 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000},
/* idx: 344 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000},
/* idx: 345 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000},
/* idx: 346 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000},
/* idx: 347 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000},
/* idx: 348 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000},
/* idx: 349 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000},
/* idx: 350 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000},
/* idx: 351 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000},
/* idx: 352 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000},
/* idx: 353 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000},
/* idx: 354 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000},
/* idx: 355 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000},
/* idx: 356 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000},
/* idx: 357 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000},
/* idx: 358 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000},
/* idx: 359 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000},
/* idx: 360 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000},
/* idx: 361 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000},
/* idx: 362 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000},
/* idx: 363 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000},
/* idx: 364 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000},
/* idx: 365 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000},
/* idx: 366 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000},
/* idx: 367 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000},
/* idx: 368 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000},
/* idx: 369 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000},
/* idx: 370 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000},
/* idx: 371 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000},
/* idx: 372 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000000},
/* idx: 373 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000},
/* idx: 374 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000000},
/* idx: 375 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000000},
/* idx: 376 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000000},
/* idx: 377 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000000},
/* idx: 378 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000000},
/* idx: 379 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000000},
/* idx: 380 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000},
/* idx: 381 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000},
/* idx: 382 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000000},
/* idx: 383 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000},
/* idx: 384 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1},
/* idx: 385 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
/* idx: 386 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4},
/* idx: 387 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
/* idx: 388 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10},
/* idx: 389 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20},
/* idx: 390 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40},
/* idx: 391 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80},
/* idx: 392 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100},
/* idx: 393 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200},
/* idx: 394 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400},
/* idx: 395 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800},
/* idx: 396 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000},
/* idx: 397 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000},
/* idx: 398 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000},
/* idx: 399 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000},
/* idx: 400 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000},
/* idx: 401 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000},
/* idx: 402 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000},
/* idx: 403 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000},
/* idx: 404 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000},
/* idx: 405 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000},
/* idx: 406 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000},
/* idx: 407 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000},
/* idx: 408 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000},
/* idx: 409 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000},
/* idx: 410 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000},
/* idx: 411 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000},
/* idx: 412 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000},
/* idx: 413 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000},
/* idx: 414 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000},
/* idx: 415 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000},
/* idx: 416 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000},
/* idx: 417 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000},
/* idx: 418 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000},
/* idx: 419 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000},
/* idx: 420 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000},
/* idx: 421 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000},
/* idx: 422 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000},
/* idx: 423 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000},
/* idx: 424 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000},
/* idx: 425 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000},
/* idx: 426 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000},
/* idx: 427 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000},
/* idx: 428 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000},
/* idx: 429 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000},
/* idx: 430 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000},
/* idx: 431 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000},
/* idx: 432 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000},
/* idx: 433 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000},
/* idx: 434 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000},
/* idx: 435 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000},
/* idx: 436 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000000},
/* idx: 437 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000},
/* idx: 438 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000000},
/* idx: 439 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000000},
/* idx: 440 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000000},
/* idx: 441 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000000},
/* idx: 442 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000000},
/* idx: 443 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000000},
/* idx: 444 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000},
/* idx: 445 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000},
/* idx: 446 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000000},
/* idx: 447 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000},
/* idx: 448 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1},
/* idx: 449 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2},
/* idx: 450 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4},
/* idx: 451 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8},
/* idx: 452 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10},
/* idx: 453 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20},
/* idx: 454 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40},
/* idx: 455 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80},
/* idx: 456 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100},
/* idx: 457 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200},
/* idx: 458 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400},
/* idx: 459 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800},
/* idx: 460 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000},
/* idx: 461 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000},
/* idx: 462 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000},
/* idx: 463 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000},
/* idx: 464 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000},
/* idx: 465 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000},
/* idx: 466 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000},
/* idx: 467 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000},
/* idx: 468 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000},
/* idx: 469 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000},
/* idx: 470 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000},
/* idx: 471 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000},
/* idx: 472 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000},
/* idx: 473 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000},
/* idx: 474 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000},
/* idx: 475 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000},
/* idx: 476 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000},
/* idx: 477 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000},
/* idx: 478 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000},
/* idx: 479 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000},
/* idx: 480 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000},
/* idx: 481 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000},
/* idx: 482 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000},
/* idx: 483 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000},
/* idx: 484 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000},
/* idx: 485 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000},
/* idx: 486 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000},
/* idx: 487 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000},
/* idx: 488 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000},
/* idx: 489 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000},
/* idx: 490 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000},
/* idx: 491 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000},
/* idx: 492 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000},
/* idx: 493 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000},
/* idx: 494 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000},
/* idx: 495 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000},
/* idx: 496 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000},
/* idx: 497 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000},
/* idx: 498 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000},
/* idx: 499 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000},
/* idx: 500 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10000000000000},
/* idx: 501 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20000000000000},
/* idx: 502 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x40000000000000},
/* idx: 503 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000000000000},
/* idx: 504 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x100000000000000},
/* idx: 505 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x200000000000000},
/* idx: 506 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x400000000000000},
/* idx: 507 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x800000000000000},
/* idx: 508 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1000000000000000},
/* idx: 509 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2000000000000000},
/* idx: 510 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4000000000000000},
/* idx: 511 */ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8000000000000000},
}

File diff suppressed because it is too large Load Diff

View File

@@ -14,9 +14,9 @@ type nodeType byte
const (
nullNode nodeType = iota // empty node
fullNode // prefixes and children
leafNode // only prefixes
intermediateNode // only children
fullNode // prefixes and children or path-compressed prefixes
leafNode // no children, only prefixes or path-compressed prefixes
intermediateNode // only children, no prefix nor path-compressed prefixes
)
// ##################################################
@@ -27,65 +27,47 @@ const (
func (t *Table[V]) dumpString() string {
w := new(strings.Builder)
t.dump(w)
return w.String()
}
// dump the table structure and all the nodes to w.
//
// Output:
//
// [FULL] depth: 0 path: [] / 0
// indexs(#6): 1 66 128 133 266 383
// prefxs(#6): 0/0 8/6 0/7 10/7 10/8 127/8
// childs(#3): 10 127 192
//
// .[IMED] depth: 1 path: [10] / 8
// .childs(#1): 0
//
// ..[LEAF] depth: 2 path: [10.0] / 16
// ..indexs(#2): 256 257
// ..prefxs(#2): 0/8 1/8
//
// .[IMED] depth: 1 path: [127] / 8
// .childs(#1): 0
//
// ..[IMED] depth: 2 path: [127.0] / 16
// ..childs(#1): 0
//
// ...[LEAF] depth: 3 path: [127.0.0] / 24
// ...indexs(#1): 257
// ...prefxs(#1): 1/8
//
// ...
func (t *Table[V]) dump(w io.Writer) {
t.init()
if t == nil {
return
}
fmt.Fprint(w, "### IPv4:")
t.rootV4.dumpRec(w, zeroPath, 0, true)
if t.size4 > 0 {
fmt.Fprintln(w)
fmt.Fprintf(w, "### IPv4: size(%d), nodes(%d)", t.size4, t.root4.nodeStatsRec().nodes)
t.root4.dumpRec(w, stridePath{}, 0, true)
}
fmt.Fprint(w, "### IPv6:")
t.rootV6.dumpRec(w, zeroPath, 0, false)
if t.size6 > 0 {
fmt.Fprintln(w)
fmt.Fprintf(w, "### IPv6: size(%d), nodes(%d)", t.size6, t.root6.nodeStatsRec().nodes)
t.root6.dumpRec(w, stridePath{}, 0, false)
}
}
// dumpRec, rec-descent the trie.
func (n *node[V]) dumpRec(w io.Writer, path [16]byte, depth int, is4 bool) {
func (n *node[V]) dumpRec(w io.Writer, path stridePath, depth int, is4 bool) {
// dump this node
n.dump(w, path, depth, is4)
// make backing arrays, no heap allocs
addrBackingArray := [maxNodeChildren]uint{}
// the node may have childs, the rec-descent monster starts
for i, addr := range n.allChildAddrs(addrBackingArray[:]) {
// the node may have childs, rec-descent down
for i, addr := range n.children.All() {
octet := byte(addr)
child := n.children[i]
path[depth] = octet
child.dumpRec(w, path, depth+1, is4)
if child, ok := n.children.Items[i].(*node[V]); ok {
child.dumpRec(w, path, depth+1, is4)
}
}
}
// dump the node to w.
func (n *node[V]) dump(w io.Writer, path [16]byte, depth int, is4 bool) {
func (n *node[V]) dump(w io.Writer, path stridePath, depth int, is4 bool) {
bits := depth * strideLen
indent := strings.Repeat(".", depth)
@@ -93,42 +75,97 @@ func (n *node[V]) dump(w io.Writer, path [16]byte, depth int, is4 bool) {
fmt.Fprintf(w, "\n%s[%s] depth: %d path: [%s] / %d\n",
indent, n.hasType(), depth, ipStridePath(path, depth, is4), bits)
if nPfxLen := len(n.prefixes); nPfxLen != 0 {
// make backing arrays, no heap allocs
idxBackingArray := [maxNodePrefixes]uint{}
allIndices := n.allStrideIndexes(idxBackingArray[:])
if nPfxCount := n.prefixes.Len(); nPfxCount != 0 {
// no heap allocs
allIndices := n.prefixes.All()
// print the baseIndices for this node.
fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxLen, allIndices)
fmt.Fprintf(w, "%sindexs(#%d): %v\n", indent, nPfxCount, allIndices)
// print the prefixes for this node
fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxLen)
fmt.Fprintf(w, "%sprefxs(#%d):", indent, nPfxCount)
for _, idx := range allIndices {
octet, bits := baseIndexToPrefix(idx)
fmt.Fprintf(w, " %s/%d", octetFmt(octet, is4), bits)
octet, pfxLen := idxToPfx(idx)
fmt.Fprintf(w, " %s/%d", octetFmt(octet, is4), pfxLen)
}
fmt.Fprintln(w)
// print the values for this node
fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxLen)
fmt.Fprintf(w, "%svalues(#%d):", indent, nPfxCount)
for _, val := range n.prefixes {
for _, val := range n.prefixes.Items {
fmt.Fprintf(w, " %v", val)
}
fmt.Fprintln(w)
}
if childs := len(n.children); childs != 0 {
// print the childs for this node
fmt.Fprintf(w, "%schilds(#%d):", indent, childs)
if n.children.Len() != 0 {
addrBackingArray := [maxNodeChildren]uint{}
for _, addr := range n.allChildAddrs(addrBackingArray[:]) {
octet := byte(addr)
fmt.Fprintf(w, " %s", octetFmt(octet, is4))
nodeAddrs := make([]uint, 0, maxNodeChildren)
leafAddrs := make([]uint, 0, maxNodeChildren)
// the node has recursive child nodes or path-compressed leaves
for i, addr := range n.children.All() {
switch n.children.Items[i].(type) {
case *node[V]:
nodeAddrs = append(nodeAddrs, addr)
continue
case *leaf[V]:
leafAddrs = append(leafAddrs, addr)
default:
panic("logic error, wrong node type")
}
}
fmt.Fprintln(w)
if nodeCount := len(nodeAddrs); nodeCount > 0 {
// print the childs for this node
fmt.Fprintf(w, "%schilds(#%d):", indent, nodeCount)
for _, addr := range nodeAddrs {
octet := byte(addr)
fmt.Fprintf(w, " %s", octetFmt(octet, is4))
}
fmt.Fprintln(w)
}
if leafCount := len(leafAddrs); leafCount > 0 {
// print the pathcomp prefixes for this node
fmt.Fprintf(w, "%sleaves(#%d):", indent, leafCount)
for _, addr := range leafAddrs {
octet := byte(addr)
k := n.children.MustGet(addr)
pc := k.(*leaf[V])
fmt.Fprintf(w, " %s:{%s, %v}", octetFmt(octet, is4), pc.prefix, pc.value)
}
fmt.Fprintln(w)
}
}
}
// hasType returns the nodeType.
func (n *node[V]) hasType() nodeType {
s := n.nodeStats()
switch {
case s.pfxs == 0 && s.childs == 0:
return nullNode
case s.nodes == 0:
return leafNode
case (s.pfxs > 0 || s.leaves > 0) && s.nodes > 0:
return fullNode
case (s.pfxs == 0 && s.leaves == 0) && s.nodes > 0:
return intermediateNode
default:
panic(fmt.Sprintf("UNREACHABLE: pfx: %d, chld: %d, node: %d, leaf: %d",
s.pfxs, s.childs, s.nodes, s.leaves))
}
}
@@ -137,6 +174,7 @@ func octetFmt(octet byte, is4 bool) string {
if is4 {
return fmt.Sprintf("%d", octet)
}
return fmt.Sprintf("0x%02x", octet)
}
@@ -144,7 +182,7 @@ func octetFmt(octet byte, is4 bool) string {
//
// 127.0.0
// 2001:0d
func ipStridePath(path [16]byte, depth int, is4 bool) string {
func ipStridePath(path stridePath, depth int, is4 bool) string {
buf := new(strings.Builder)
if is4 {
@@ -152,8 +190,10 @@ func ipStridePath(path [16]byte, depth int, is4 bool) string {
if i != 0 {
buf.WriteString(".")
}
buf.WriteString(strconv.Itoa(int(b)))
}
return buf.String()
}
@@ -161,8 +201,10 @@ func ipStridePath(path [16]byte, depth int, is4 bool) string {
if i != 0 && i%2 == 0 {
buf.WriteString(":")
}
buf.WriteString(fmt.Sprintf("%02x", b))
}
return buf.String()
}
@@ -177,29 +219,72 @@ func (nt nodeType) String() string {
return "LEAF"
case intermediateNode:
return "IMED"
default:
return "unreachable"
}
panic("unreachable")
}
// hasType returns the nodeType.
func (n *node[V]) hasType() nodeType {
lenPefixes := len(n.prefixes)
lenChilds := len(n.children)
if lenPefixes == 0 && lenChilds != 0 {
return intermediateNode
}
if lenPefixes == 0 && lenChilds == 0 {
return nullNode
}
if lenPefixes != 0 && lenChilds == 0 {
return leafNode
}
if lenPefixes != 0 && lenChilds != 0 {
return fullNode
}
panic("unreachable")
// stats, only used for dump, tests and benchmarks
type stats struct {
pfxs int
childs int
nodes int
leaves int
}
// node statistics for this single node
func (n *node[V]) nodeStats() stats {
var s stats
s.pfxs = n.prefixes.Len()
s.childs = n.children.Len()
for i := range n.children.All() {
switch n.children.Items[i].(type) {
case *node[V]:
s.nodes++
case *leaf[V]:
s.leaves++
default:
panic("logic error, wrong node type")
}
}
return s
}
// nodeStatsRec, calculate the number of pfxs, nodes and leaves under n, rec-descent.
func (n *node[V]) nodeStatsRec() stats {
var s stats
if n == nil || n.isEmpty() {
return s
}
s.pfxs = n.prefixes.Len()
s.childs = n.children.Len()
s.nodes = 1 // this node
s.leaves = 0
for _, kidAny := range n.children.Items {
switch kid := kidAny.(type) {
case *node[V]:
// rec-descent
rs := kid.nodeStatsRec()
s.pfxs += rs.pfxs
s.childs += rs.childs
s.nodes += rs.nodes
s.leaves += rs.leaves
case *leaf[V]:
s.leaves++
default:
panic("logic error, wrong node type")
}
}
return s
}

View File

@@ -0,0 +1,326 @@
// Copyright (c) 2024 Karl Gaissmaier
// SPDX-License-Identifier: MIT
// Package bitset implements bitsets, a mapping
// between non-negative integers and boolean values.
//
// Studied [github.com/bits-and-blooms/bitset] inside out
// and rewrote needed parts from scratch for this project.
//
// This implementation is smaller and faster as the more
// general [github.com/bits-and-blooms/bitset].
//
// All functions can be inlined!
//
// can inline BitSet.Set with cost 63
// can inline BitSet.Clear with cost 24
// can inline BitSet.Test with cost 26
// can inline BitSet.Rank0 with cost 66
// can inline BitSet.Clone with cost 7
// can inline BitSet.Compact with cost 35
// can inline BitSet.FirstSet with cost 25
// can inline BitSet.NextSet with cost 71
// can inline BitSet.AsSlice with cost 50
// can inline BitSet.All with cost 62
// can inline BitSet.IntersectsAny with cost 42
// can inline BitSet.IntersectionTop with cost 56
// can inline BitSet.IntersectionCardinality with cost 35
// can inline (*BitSet).InPlaceIntersection with cost 71
// can inline (*BitSet).InPlaceUnion with cost 77
// can inline BitSet.Size with cost 16
// can inline popcount with cost 12
// can inline popcountAnd with cost 30
package bitset
import (
"math/bits"
)
// A BitSet is a slice of words. This is an internal package
// with a wide open public API.
type BitSet []uint64
// xIdx calculates the index of i in a []uint64
// func wIdx(i uint) int {
// return int(i >> 6) // like (i / 64) but faster
// }
// bIdx calculates the index of i in a `uint64`
// func bIdx(i uint) uint {
// return i & 63 // like (i % 64) but faster
// }
//
// just as an explanation of the expressions,
//
// i>>6 or i<<6 and i&63
//
// not factored out as functions to make most of the methods
// inlineable with minimal costs.
// Set bit i to 1, the capacity of the bitset is increased accordingly.
func (b BitSet) Set(i uint) BitSet {
// grow?
if i >= uint(len(b)<<6) {
words := int((i + 64) >> 6)
switch {
case b == nil:
b = make([]uint64, words)
case cap(b) >= words:
b = b[:words]
default:
// be exact, don't use append!
// max 512 prefixes/node (8*uint64), and a cache line has 64 Bytes
newset := make([]uint64, words)
copy(newset, b)
b = newset
}
}
b[i>>6] |= 1 << (i & 63)
return b
}
// Clear bit i to 0.
func (b BitSet) Clear(i uint) BitSet {
if x := int(i >> 6); x < len(b) {
b[x] &^= 1 << (i & 63)
}
return b
}
// Test if bit i is set.
func (b BitSet) Test(i uint) (ok bool) {
if x := int(i >> 6); x < len(b) {
return b[x]&(1<<(i&63)) != 0
}
return
}
// Clone this BitSet, returning a new BitSet that has the same bits set.
func (b BitSet) Clone() BitSet {
return append(b[:0:0], b...)
}
// Compact, preserve all set bits, while minimizing memory usage.
func (b BitSet) Compact() BitSet {
last := len(b) - 1
// find last word with at least one bit set.
for ; last >= 0; last-- {
if b[last] != 0 {
b = b[: last+1 : last+1]
return b
}
}
// BitSet was empty, shrink to nil
return nil
}
// FirstSet returns the first bit set along with an ok code.
func (b BitSet) FirstSet() (uint, bool) {
for x, word := range b {
if word != 0 {
return uint(x<<6 + bits.TrailingZeros64(word)), true
}
}
return 0, false
}
// NextSet returns the next bit set from the specified index,
// including possibly the current index along with an ok code.
func (b BitSet) NextSet(i uint) (uint, bool) {
x := int(i >> 6)
if x >= len(b) {
return 0, false
}
// process the first (maybe partial) word
first := b[x] >> (i & 63) // i % 64
if first != 0 {
return i + uint(bits.TrailingZeros64(first)), true
}
// process the following words until next bit is set
// x < len(b), no out-of-bounds panic in following slice expression
x++
for j, word := range b[x:] {
if word != 0 {
return uint((x+j)<<6 + bits.TrailingZeros64(word)), true
}
}
return 0, false
}
// AsSlice returns all set bits as slice of uint without
// heap allocations.
//
// This is faster than All, but also more dangerous,
// it panics if the capacity of buf is < b.Size()
func (b BitSet) AsSlice(buf []uint) []uint {
buf = buf[:cap(buf)] // len = cap
size := 0
for idx, word := range b {
for ; word != 0; size++ {
// panics if capacity of buf is exceeded.
buf[size] = uint(idx<<6 + bits.TrailingZeros64(word))
// clear the rightmost set bit
word &= word - 1
}
}
buf = buf[:size]
return buf
}
// All returns all set bits. This is simpler but slower than AsSlice.
func (b BitSet) All() []uint {
buf := make([]uint, b.Size())
slot := 0
for idx, word := range b {
for word != 0 {
buf[slot] = uint(idx<<6 + bits.TrailingZeros64(word))
slot++
// clear the rightmost set bit
word &= word - 1
}
}
return buf
}
// IntersectsAny returns true if the intersection of base set with the compare set
// is not the empty set.
func (b BitSet) IntersectsAny(c BitSet) bool {
i := min(len(b), len(c)) - 1
// bounds check eliminated (BCE)
for ; i >= 0 && i < len(b) && i < len(c); i-- {
if b[i]&c[i] != 0 {
return true
}
}
return false
}
// IntersectionTop computes the intersection of base set with the compare set.
// If the result set isn't empty, it returns the top most set bit and true.
func (b BitSet) IntersectionTop(c BitSet) (top uint, ok bool) {
i := min(len(b), len(c)) - 1
// bounds check eliminated (BCE)
for ; i >= 0 && i < len(b) && i < len(c); i-- {
if word := b[i] & c[i]; word != 0 {
return uint(i<<6+bits.Len64(word)) - 1, true
}
}
return
}
// IntersectionCardinality computes the popcount of the intersection.
func (b BitSet) IntersectionCardinality(c BitSet) int {
return popcntAnd(b, c)
}
// InPlaceIntersection overwrites and computes the intersection of
// base set with the compare set. This is the BitSet equivalent of & (and).
// If len(c) > len(b), new memory is allocated.
func (b *BitSet) InPlaceIntersection(c BitSet) {
// bounds check eliminated, range until minLen(b,c)
for i := 0; i < len(*b) && i < len(c); i++ {
(*b)[i] &= c[i]
}
// b >= c
if len(*b) >= len(c) {
// bounds check eliminated
for i := len(c); i < len(*b); i++ {
(*b)[i] = 0
}
return
}
// b < c
newset := make([]uint64, len(c))
copy(newset, *b)
*b = newset
}
// InPlaceUnion creates the destructive union of base set with compare set.
// This is the BitSet equivalent of | (or).
// If len(c) > len(b), new memory is allocated.
func (b *BitSet) InPlaceUnion(c BitSet) {
// b >= c
if len(*b) >= len(c) {
// bounds check eliminated
for i := 0; i < len(*b) && i < len(c); i++ {
(*b)[i] |= c[i]
}
return
}
// b < c
newset := make([]uint64, len(c))
copy(newset, *b)
*b = newset
// bounds check eliminated
for i := 0; i < len(*b) && i < len(c); i++ {
(*b)[i] |= c[i]
}
}
// Size (number of set bits).
func (b BitSet) Size() int {
return popcntSlice(b)
}
// Rank0 is equal to Rank(i) - 1
//
// With inlined popcount to make Rank0 itself inlineable.
func (b BitSet) Rank0(i uint) (rnk int) {
// Rank count is inclusive
i++
if wordIdx := int(i >> 6); wordIdx >= len(b) {
// inlined popcount, whole slice
for _, x := range b {
rnk += bits.OnesCount64(x)
}
} else {
// inlined popcount, partial slice ...
for _, x := range b[:wordIdx] {
rnk += bits.OnesCount64(x)
}
// ... plus partial word?
if bitsIdx := i & 63; bitsIdx != 0 {
rnk += bits.OnesCount64(b[wordIdx] << (64 - bitsIdx))
}
}
// correct for offset by one
return rnk - 1
}
// popcntSlice
func popcntSlice(s []uint64) (cnt int) {
for _, x := range s {
// count all the bits set in slice.
cnt += bits.OnesCount64(x)
}
return
}
// popcntAnd
func popcntAnd(s, m []uint64) (cnt int) {
for j := 0; j < len(s) && j < len(m); j++ {
// words are bitwise & followed by popcount.
cnt += bits.OnesCount64(s[j] & m[j])
}
return
}

View File

@@ -0,0 +1,160 @@
// Copyright (c) 2024 Karl Gaissmaier
// SPDX-License-Identifier: MIT
// package sparse implements a generic sparse array
// with popcount compression.
package sparse
import (
"github.com/gaissmai/bart/internal/bitset"
)
// Array, a generic implementation of a sparse array
// with popcount compression and payload T.
type Array[T any] struct {
bitset.BitSet
Items []T
}
// Get the value at i from sparse array.
//
// example: Array.Get(5) -> Array.Items[1]
//
// ⬇
// BitSet: [0|0|1|0|0|1|0|1|...] <- 3 bits set
// Items: [*|*|*] <- len(Items) = 3
// ⬆
//
// BitSet.Test(5): true
// BitSet.popcount(5): 2, for interval [0,5]
// BitSet.Rank0(5): 1, equal popcount(5)-1
func (s *Array[T]) Get(i uint) (value T, ok bool) {
if s.Test(i) {
return s.Items[s.Rank0(i)], true
}
return
}
// MustGet, use it only after a successful test
// or the behavior is undefined, maybe it panics.
func (s *Array[T]) MustGet(i uint) T {
return s.Items[s.Rank0(i)]
}
// UpdateAt or set the value at i via callback. The new value is returned
// and true if the value was already present.
func (s *Array[T]) UpdateAt(i uint, cb func(T, bool) T) (newValue T, wasPresent bool) {
var rank0 int
// if already set, get current value
var oldValue T
if wasPresent = s.Test(i); wasPresent {
rank0 = s.Rank0(i)
oldValue = s.Items[rank0]
}
// callback function to get updated or new value
newValue = cb(oldValue, wasPresent)
// already set, update and return value
if wasPresent {
s.Items[rank0] = newValue
return newValue, wasPresent
}
// new value, insert into bitset ...
s.BitSet = s.Set(i)
// bitset has changed, recalc rank
rank0 = s.Rank0(i)
// ... and insert value into slice
s.insertItem(rank0, newValue)
return newValue, wasPresent
}
// Len returns the number of items in sparse array.
func (s *Array[T]) Len() int {
return len(s.Items)
}
// Copy returns a shallow copy of the Array.
// The elements are copied using assignment, this is no deep clone.
func (s *Array[T]) Copy() *Array[T] {
if s == nil {
return nil
}
return &Array[T]{
BitSet: s.BitSet.Clone(),
Items: append(s.Items[:0:0], s.Items...),
}
}
// InsertAt a value at i into the sparse array.
// If the value already exists, overwrite it with val and return true.
func (s *Array[T]) InsertAt(i uint, value T) (exists bool) {
// slot exists, overwrite value
if s.Len() != 0 && s.Test(i) {
s.Items[s.Rank0(i)] = value
return true
}
// new, insert into bitset ...
s.BitSet = s.Set(i)
// ... and slice
s.insertItem(s.Rank0(i), value)
return false
}
// DeleteAt a value at i from the sparse array, zeroes the tail.
func (s *Array[T]) DeleteAt(i uint) (value T, exists bool) {
if s.Len() == 0 || !s.Test(i) {
return
}
rank0 := s.Rank0(i)
value = s.Items[rank0]
// delete from slice
s.deleteItem(rank0)
// delete from bitset
s.BitSet = s.Clear(i)
return value, true
}
// insertItem inserts the item at index i, shift the rest one pos right
//
// It panics if i is out of range.
func (s *Array[T]) insertItem(i int, item T) {
if len(s.Items) < cap(s.Items) {
s.Items = s.Items[:len(s.Items)+1] // fast resize, no alloc
} else {
var zero T
s.Items = append(s.Items, zero) // append one item, mostly enlarge cap by more than one item
}
copy(s.Items[i+1:], s.Items[i:])
s.Items[i] = item
}
// deleteItem at index i, shift the rest one pos left and clears the tail item
//
// It panics if i is out of range.
func (s *Array[T]) deleteItem(i int) {
var zero T
nl := len(s.Items) - 1 // new len
copy(s.Items[i:], s.Items[i+1:]) // overwrite item at [i]
s.Items[nl] = zero // clear the tail item
s.Items = s.Items[:nl] // new len, keep cap is unchanged
}

View File

@@ -1,8 +1,8 @@
package bart
// Copyright (c) 2024 Karl Gaissmaier
// SPDX-License-Identifier: MIT
package bart
import (
"encoding/json"
"net/netip"
@@ -19,7 +19,9 @@ type DumpListNode[V any] struct {
// MarshalJSON dumps the table into two sorted lists: for ipv4 and ipv6.
// Every root and subnet is an array, not a map, because the order matters.
func (t *Table[V]) MarshalJSON() ([]byte, error) {
t.init()
if t == nil {
return nil, nil
}
result := struct {
Ipv4 []DumpListNode[V] `json:"ipv4,omitempty"`
@@ -40,24 +42,27 @@ func (t *Table[V]) MarshalJSON() ([]byte, error) {
// DumpList4 dumps the ipv4 tree into a list of roots and their subnets.
// It can be used to analyze the tree or build custom json representation.
func (t *Table[V]) DumpList4() []DumpListNode[V] {
t.init()
if t.rootV4 == nil {
if t == nil {
return nil
}
return t.rootV4.dumpListRec(0, zeroPath, 0, true)
return t.root4.dumpListRec(0, stridePath{}, 0, true)
}
// DumpList6 dumps the ipv6 tree into a list of roots and their subnets.
// It can be used to analyze the tree or build custom json representation.
func (t *Table[V]) DumpList6() []DumpListNode[V] {
t.init()
if t.rootV6 == nil {
if t == nil {
return nil
}
return t.rootV6.dumpListRec(0, zeroPath, 0, false)
return t.root6.dumpListRec(0, stridePath{}, 0, false)
}
func (n *node[V]) dumpListRec(parentIdx uint, path [16]byte, depth int, is4 bool) []DumpListNode[V] {
func (n *node[V]) dumpListRec(parentIdx uint, path stridePath, depth int, is4 bool) []DumpListNode[V] {
// recursion stop condition
if n == nil {
return nil
}
directKids := n.getKidsRec(parentIdx, path, depth, is4)
slices.SortFunc(directKids, cmpKidByPrefix[V])

538
vendor/github.com/gaissmai/bart/lpm_lookuptbl.go generated vendored Normal file
View File

@@ -0,0 +1,538 @@
package bart
import "github.com/gaissmai/bart/internal/bitset"
// lpmLookupTbl is the backtracking sequence in the complete binary tree as bitstring.
//
// for idx := 1; idx > 0; idx >>= 1 { b.Set(idx) }
//
// allows a one shot bitset intersection algorithm:
//
// func (n *node[V]) lpmTest(idx uint) bool {
// return n.prefixes.IntersectsAny(lpmLookupTbl[idx])
// }
//
// instead of a sequence of single bitset tests:
//
// func (n *node[V]) lpmTest(idx uint) bool {
// for ; idx > 0; idx >>= 1 {
// if n.prefixes.Test(idx) {
// return true
// }
// }
// return false
// }
var lpmLookupTbl = [512]bitset.BitSet{
/* idx: 0 */ {}, // invalid
/* idx: 1 */ {0x2}, // 0b0000_0010
/* idx: 2 */ {0x6}, // 0b0000_0110
/* idx: 3 */ {0xa}, // 0b0000_1010
/* idx: 4 */ {0x16}, // ...
/* idx: 5 */ {0x26},
/* idx: 6 */ {0x4a},
/* idx: 7 */ {0x8a},
/* idx: 8 */ {0x116},
/* idx: 9 */ {0x216},
/* idx: 10 */ {0x426},
/* idx: 11 */ {0x826},
/* idx: 12 */ {0x104a},
/* idx: 13 */ {0x204a},
/* idx: 14 */ {0x408a},
/* idx: 15 */ {0x808a},
/* idx: 16 */ {0x10116},
/* idx: 17 */ {0x20116},
/* idx: 18 */ {0x40216},
/* idx: 19 */ {0x80216},
/* idx: 20 */ {0x100426},
/* idx: 21 */ {0x200426},
/* idx: 22 */ {0x400826},
/* idx: 23 */ {0x800826},
/* idx: 24 */ {0x100104a},
/* idx: 25 */ {0x200104a},
/* idx: 26 */ {0x400204a},
/* idx: 27 */ {0x800204a},
/* idx: 28 */ {0x1000408a},
/* idx: 29 */ {0x2000408a},
/* idx: 30 */ {0x4000808a},
/* idx: 31 */ {0x8000808a},
/* idx: 32 */ {0x100010116},
/* idx: 33 */ {0x200010116},
/* idx: 34 */ {0x400020116},
/* idx: 35 */ {0x800020116},
/* idx: 36 */ {0x1000040216},
/* idx: 37 */ {0x2000040216},
/* idx: 38 */ {0x4000080216},
/* idx: 39 */ {0x8000080216},
/* idx: 40 */ {0x10000100426},
/* idx: 41 */ {0x20000100426},
/* idx: 42 */ {0x40000200426},
/* idx: 43 */ {0x80000200426},
/* idx: 44 */ {0x100000400826},
/* idx: 45 */ {0x200000400826},
/* idx: 46 */ {0x400000800826},
/* idx: 47 */ {0x800000800826},
/* idx: 48 */ {0x100000100104a},
/* idx: 49 */ {0x200000100104a},
/* idx: 50 */ {0x400000200104a},
/* idx: 51 */ {0x800000200104a},
/* idx: 52 */ {0x1000000400204a},
/* idx: 53 */ {0x2000000400204a},
/* idx: 54 */ {0x4000000800204a},
/* idx: 55 */ {0x8000000800204a},
/* idx: 56 */ {0x10000001000408a},
/* idx: 57 */ {0x20000001000408a},
/* idx: 58 */ {0x40000002000408a},
/* idx: 59 */ {0x80000002000408a},
/* idx: 60 */ {0x100000004000808a},
/* idx: 61 */ {0x200000004000808a},
/* idx: 62 */ {0x400000008000808a},
/* idx: 63 */ {0x800000008000808a},
/* idx: 64 */ {0x100010116, 0x1},
/* idx: 65 */ {0x100010116, 0x2},
/* idx: 66 */ {0x200010116, 0x4},
/* idx: 67 */ {0x200010116, 0x8},
/* idx: 68 */ {0x400020116, 0x10},
/* idx: 69 */ {0x400020116, 0x20},
/* idx: 70 */ {0x800020116, 0x40},
/* idx: 71 */ {0x800020116, 0x80},
/* idx: 72 */ {0x1000040216, 0x100},
/* idx: 73 */ {0x1000040216, 0x200},
/* idx: 74 */ {0x2000040216, 0x400},
/* idx: 75 */ {0x2000040216, 0x800},
/* idx: 76 */ {0x4000080216, 0x1000},
/* idx: 77 */ {0x4000080216, 0x2000},
/* idx: 78 */ {0x8000080216, 0x4000},
/* idx: 79 */ {0x8000080216, 0x8000},
/* idx: 80 */ {0x10000100426, 0x10000},
/* idx: 81 */ {0x10000100426, 0x20000},
/* idx: 82 */ {0x20000100426, 0x40000},
/* idx: 83 */ {0x20000100426, 0x80000},
/* idx: 84 */ {0x40000200426, 0x100000},
/* idx: 85 */ {0x40000200426, 0x200000},
/* idx: 86 */ {0x80000200426, 0x400000},
/* idx: 87 */ {0x80000200426, 0x800000},
/* idx: 88 */ {0x100000400826, 0x1000000},
/* idx: 89 */ {0x100000400826, 0x2000000},
/* idx: 90 */ {0x200000400826, 0x4000000},
/* idx: 91 */ {0x200000400826, 0x8000000},
/* idx: 92 */ {0x400000800826, 0x10000000},
/* idx: 93 */ {0x400000800826, 0x20000000},
/* idx: 94 */ {0x800000800826, 0x40000000},
/* idx: 95 */ {0x800000800826, 0x80000000},
/* idx: 96 */ {0x100000100104a, 0x100000000},
/* idx: 97 */ {0x100000100104a, 0x200000000},
/* idx: 98 */ {0x200000100104a, 0x400000000},
/* idx: 99 */ {0x200000100104a, 0x800000000},
/* idx: 100 */ {0x400000200104a, 0x1000000000},
/* idx: 101 */ {0x400000200104a, 0x2000000000},
/* idx: 102 */ {0x800000200104a, 0x4000000000},
/* idx: 103 */ {0x800000200104a, 0x8000000000},
/* idx: 104 */ {0x1000000400204a, 0x10000000000},
/* idx: 105 */ {0x1000000400204a, 0x20000000000},
/* idx: 106 */ {0x2000000400204a, 0x40000000000},
/* idx: 107 */ {0x2000000400204a, 0x80000000000},
/* idx: 108 */ {0x4000000800204a, 0x100000000000},
/* idx: 109 */ {0x4000000800204a, 0x200000000000},
/* idx: 110 */ {0x8000000800204a, 0x400000000000},
/* idx: 111 */ {0x8000000800204a, 0x800000000000},
/* idx: 112 */ {0x10000001000408a, 0x1000000000000},
/* idx: 113 */ {0x10000001000408a, 0x2000000000000},
/* idx: 114 */ {0x20000001000408a, 0x4000000000000},
/* idx: 115 */ {0x20000001000408a, 0x8000000000000},
/* idx: 116 */ {0x40000002000408a, 0x10000000000000},
/* idx: 117 */ {0x40000002000408a, 0x20000000000000},
/* idx: 118 */ {0x80000002000408a, 0x40000000000000},
/* idx: 119 */ {0x80000002000408a, 0x80000000000000},
/* idx: 120 */ {0x100000004000808a, 0x100000000000000},
/* idx: 121 */ {0x100000004000808a, 0x200000000000000},
/* idx: 122 */ {0x200000004000808a, 0x400000000000000},
/* idx: 123 */ {0x200000004000808a, 0x800000000000000},
/* idx: 124 */ {0x400000008000808a, 0x1000000000000000},
/* idx: 125 */ {0x400000008000808a, 0x2000000000000000},
/* idx: 126 */ {0x800000008000808a, 0x4000000000000000},
/* idx: 127 */ {0x800000008000808a, 0x8000000000000000},
/* idx: 128 */ {0x100010116, 0x1, 0x1},
/* idx: 129 */ {0x100010116, 0x1, 0x2},
/* idx: 130 */ {0x100010116, 0x2, 0x4},
/* idx: 131 */ {0x100010116, 0x2, 0x8},
/* idx: 132 */ {0x200010116, 0x4, 0x10},
/* idx: 133 */ {0x200010116, 0x4, 0x20},
/* idx: 134 */ {0x200010116, 0x8, 0x40},
/* idx: 135 */ {0x200010116, 0x8, 0x80},
/* idx: 136 */ {0x400020116, 0x10, 0x100},
/* idx: 137 */ {0x400020116, 0x10, 0x200},
/* idx: 138 */ {0x400020116, 0x20, 0x400},
/* idx: 139 */ {0x400020116, 0x20, 0x800},
/* idx: 140 */ {0x800020116, 0x40, 0x1000},
/* idx: 141 */ {0x800020116, 0x40, 0x2000},
/* idx: 142 */ {0x800020116, 0x80, 0x4000},
/* idx: 143 */ {0x800020116, 0x80, 0x8000},
/* idx: 144 */ {0x1000040216, 0x100, 0x10000},
/* idx: 145 */ {0x1000040216, 0x100, 0x20000},
/* idx: 146 */ {0x1000040216, 0x200, 0x40000},
/* idx: 147 */ {0x1000040216, 0x200, 0x80000},
/* idx: 148 */ {0x2000040216, 0x400, 0x100000},
/* idx: 149 */ {0x2000040216, 0x400, 0x200000},
/* idx: 150 */ {0x2000040216, 0x800, 0x400000},
/* idx: 151 */ {0x2000040216, 0x800, 0x800000},
/* idx: 152 */ {0x4000080216, 0x1000, 0x1000000},
/* idx: 153 */ {0x4000080216, 0x1000, 0x2000000},
/* idx: 154 */ {0x4000080216, 0x2000, 0x4000000},
/* idx: 155 */ {0x4000080216, 0x2000, 0x8000000},
/* idx: 156 */ {0x8000080216, 0x4000, 0x10000000},
/* idx: 157 */ {0x8000080216, 0x4000, 0x20000000},
/* idx: 158 */ {0x8000080216, 0x8000, 0x40000000},
/* idx: 159 */ {0x8000080216, 0x8000, 0x80000000},
/* idx: 160 */ {0x10000100426, 0x10000, 0x100000000},
/* idx: 161 */ {0x10000100426, 0x10000, 0x200000000},
/* idx: 162 */ {0x10000100426, 0x20000, 0x400000000},
/* idx: 163 */ {0x10000100426, 0x20000, 0x800000000},
/* idx: 164 */ {0x20000100426, 0x40000, 0x1000000000},
/* idx: 165 */ {0x20000100426, 0x40000, 0x2000000000},
/* idx: 166 */ {0x20000100426, 0x80000, 0x4000000000},
/* idx: 167 */ {0x20000100426, 0x80000, 0x8000000000},
/* idx: 168 */ {0x40000200426, 0x100000, 0x10000000000},
/* idx: 169 */ {0x40000200426, 0x100000, 0x20000000000},
/* idx: 170 */ {0x40000200426, 0x200000, 0x40000000000},
/* idx: 171 */ {0x40000200426, 0x200000, 0x80000000000},
/* idx: 172 */ {0x80000200426, 0x400000, 0x100000000000},
/* idx: 173 */ {0x80000200426, 0x400000, 0x200000000000},
/* idx: 174 */ {0x80000200426, 0x800000, 0x400000000000},
/* idx: 175 */ {0x80000200426, 0x800000, 0x800000000000},
/* idx: 176 */ {0x100000400826, 0x1000000, 0x1000000000000},
/* idx: 177 */ {0x100000400826, 0x1000000, 0x2000000000000},
/* idx: 178 */ {0x100000400826, 0x2000000, 0x4000000000000},
/* idx: 179 */ {0x100000400826, 0x2000000, 0x8000000000000},
/* idx: 180 */ {0x200000400826, 0x4000000, 0x10000000000000},
/* idx: 181 */ {0x200000400826, 0x4000000, 0x20000000000000},
/* idx: 182 */ {0x200000400826, 0x8000000, 0x40000000000000},
/* idx: 183 */ {0x200000400826, 0x8000000, 0x80000000000000},
/* idx: 184 */ {0x400000800826, 0x10000000, 0x100000000000000},
/* idx: 185 */ {0x400000800826, 0x10000000, 0x200000000000000},
/* idx: 186 */ {0x400000800826, 0x20000000, 0x400000000000000},
/* idx: 187 */ {0x400000800826, 0x20000000, 0x800000000000000},
/* idx: 188 */ {0x800000800826, 0x40000000, 0x1000000000000000},
/* idx: 189 */ {0x800000800826, 0x40000000, 0x2000000000000000},
/* idx: 190 */ {0x800000800826, 0x80000000, 0x4000000000000000},
/* idx: 191 */ {0x800000800826, 0x80000000, 0x8000000000000000},
/* idx: 192 */ {0x100000100104a, 0x100000000, 0x0, 0x1},
/* idx: 193 */ {0x100000100104a, 0x100000000, 0x0, 0x2},
/* idx: 194 */ {0x100000100104a, 0x200000000, 0x0, 0x4},
/* idx: 195 */ {0x100000100104a, 0x200000000, 0x0, 0x8},
/* idx: 196 */ {0x200000100104a, 0x400000000, 0x0, 0x10},
/* idx: 197 */ {0x200000100104a, 0x400000000, 0x0, 0x20},
/* idx: 198 */ {0x200000100104a, 0x800000000, 0x0, 0x40},
/* idx: 199 */ {0x200000100104a, 0x800000000, 0x0, 0x80},
/* idx: 200 */ {0x400000200104a, 0x1000000000, 0x0, 0x100},
/* idx: 201 */ {0x400000200104a, 0x1000000000, 0x0, 0x200},
/* idx: 202 */ {0x400000200104a, 0x2000000000, 0x0, 0x400},
/* idx: 203 */ {0x400000200104a, 0x2000000000, 0x0, 0x800},
/* idx: 204 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000},
/* idx: 205 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000},
/* idx: 206 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000},
/* idx: 207 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000},
/* idx: 208 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000},
/* idx: 209 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000},
/* idx: 210 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000},
/* idx: 211 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000},
/* idx: 212 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000},
/* idx: 213 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000},
/* idx: 214 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000},
/* idx: 215 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000},
/* idx: 216 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000},
/* idx: 217 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000},
/* idx: 218 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000},
/* idx: 219 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000},
/* idx: 220 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000},
/* idx: 221 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000},
/* idx: 222 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000},
/* idx: 223 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000},
/* idx: 224 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000},
/* idx: 225 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000},
/* idx: 226 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000},
/* idx: 227 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000},
/* idx: 228 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000},
/* idx: 229 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000},
/* idx: 230 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000},
/* idx: 231 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000},
/* idx: 232 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000},
/* idx: 233 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000},
/* idx: 234 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000},
/* idx: 235 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000},
/* idx: 236 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000},
/* idx: 237 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000},
/* idx: 238 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000},
/* idx: 239 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000},
/* idx: 240 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000},
/* idx: 241 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000},
/* idx: 242 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000},
/* idx: 243 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000},
/* idx: 244 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000},
/* idx: 245 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000},
/* idx: 246 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000},
/* idx: 247 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000},
/* idx: 248 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000},
/* idx: 249 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000},
/* idx: 250 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000},
/* idx: 251 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000},
/* idx: 252 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000},
/* idx: 253 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000},
/* idx: 254 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000},
/* idx: 255 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000},
/* idx: 256 */ {0x100010116, 0x1, 0x1, 0x0, 0x1},
/* idx: 257 */ {0x100010116, 0x1, 0x1, 0x0, 0x2},
/* idx: 258 */ {0x100010116, 0x1, 0x2, 0x0, 0x4},
/* idx: 259 */ {0x100010116, 0x1, 0x2, 0x0, 0x8},
/* idx: 260 */ {0x100010116, 0x2, 0x4, 0x0, 0x10},
/* idx: 261 */ {0x100010116, 0x2, 0x4, 0x0, 0x20},
/* idx: 262 */ {0x100010116, 0x2, 0x8, 0x0, 0x40},
/* idx: 263 */ {0x100010116, 0x2, 0x8, 0x0, 0x80},
/* idx: 264 */ {0x200010116, 0x4, 0x10, 0x0, 0x100},
/* idx: 265 */ {0x200010116, 0x4, 0x10, 0x0, 0x200},
/* idx: 266 */ {0x200010116, 0x4, 0x20, 0x0, 0x400},
/* idx: 267 */ {0x200010116, 0x4, 0x20, 0x0, 0x800},
/* idx: 268 */ {0x200010116, 0x8, 0x40, 0x0, 0x1000},
/* idx: 269 */ {0x200010116, 0x8, 0x40, 0x0, 0x2000},
/* idx: 270 */ {0x200010116, 0x8, 0x80, 0x0, 0x4000},
/* idx: 271 */ {0x200010116, 0x8, 0x80, 0x0, 0x8000},
/* idx: 272 */ {0x400020116, 0x10, 0x100, 0x0, 0x10000},
/* idx: 273 */ {0x400020116, 0x10, 0x100, 0x0, 0x20000},
/* idx: 274 */ {0x400020116, 0x10, 0x200, 0x0, 0x40000},
/* idx: 275 */ {0x400020116, 0x10, 0x200, 0x0, 0x80000},
/* idx: 276 */ {0x400020116, 0x20, 0x400, 0x0, 0x100000},
/* idx: 277 */ {0x400020116, 0x20, 0x400, 0x0, 0x200000},
/* idx: 278 */ {0x400020116, 0x20, 0x800, 0x0, 0x400000},
/* idx: 279 */ {0x400020116, 0x20, 0x800, 0x0, 0x800000},
/* idx: 280 */ {0x800020116, 0x40, 0x1000, 0x0, 0x1000000},
/* idx: 281 */ {0x800020116, 0x40, 0x1000, 0x0, 0x2000000},
/* idx: 282 */ {0x800020116, 0x40, 0x2000, 0x0, 0x4000000},
/* idx: 283 */ {0x800020116, 0x40, 0x2000, 0x0, 0x8000000},
/* idx: 284 */ {0x800020116, 0x80, 0x4000, 0x0, 0x10000000},
/* idx: 285 */ {0x800020116, 0x80, 0x4000, 0x0, 0x20000000},
/* idx: 286 */ {0x800020116, 0x80, 0x8000, 0x0, 0x40000000},
/* idx: 287 */ {0x800020116, 0x80, 0x8000, 0x0, 0x80000000},
/* idx: 288 */ {0x1000040216, 0x100, 0x10000, 0x0, 0x100000000},
/* idx: 289 */ {0x1000040216, 0x100, 0x10000, 0x0, 0x200000000},
/* idx: 290 */ {0x1000040216, 0x100, 0x20000, 0x0, 0x400000000},
/* idx: 291 */ {0x1000040216, 0x100, 0x20000, 0x0, 0x800000000},
/* idx: 292 */ {0x1000040216, 0x200, 0x40000, 0x0, 0x1000000000},
/* idx: 293 */ {0x1000040216, 0x200, 0x40000, 0x0, 0x2000000000},
/* idx: 294 */ {0x1000040216, 0x200, 0x80000, 0x0, 0x4000000000},
/* idx: 295 */ {0x1000040216, 0x200, 0x80000, 0x0, 0x8000000000},
/* idx: 296 */ {0x2000040216, 0x400, 0x100000, 0x0, 0x10000000000},
/* idx: 297 */ {0x2000040216, 0x400, 0x100000, 0x0, 0x20000000000},
/* idx: 298 */ {0x2000040216, 0x400, 0x200000, 0x0, 0x40000000000},
/* idx: 299 */ {0x2000040216, 0x400, 0x200000, 0x0, 0x80000000000},
/* idx: 300 */ {0x2000040216, 0x800, 0x400000, 0x0, 0x100000000000},
/* idx: 301 */ {0x2000040216, 0x800, 0x400000, 0x0, 0x200000000000},
/* idx: 302 */ {0x2000040216, 0x800, 0x800000, 0x0, 0x400000000000},
/* idx: 303 */ {0x2000040216, 0x800, 0x800000, 0x0, 0x800000000000},
/* idx: 304 */ {0x4000080216, 0x1000, 0x1000000, 0x0, 0x1000000000000},
/* idx: 305 */ {0x4000080216, 0x1000, 0x1000000, 0x0, 0x2000000000000},
/* idx: 306 */ {0x4000080216, 0x1000, 0x2000000, 0x0, 0x4000000000000},
/* idx: 307 */ {0x4000080216, 0x1000, 0x2000000, 0x0, 0x8000000000000},
/* idx: 308 */ {0x4000080216, 0x2000, 0x4000000, 0x0, 0x10000000000000},
/* idx: 309 */ {0x4000080216, 0x2000, 0x4000000, 0x0, 0x20000000000000},
/* idx: 310 */ {0x4000080216, 0x2000, 0x8000000, 0x0, 0x40000000000000},
/* idx: 311 */ {0x4000080216, 0x2000, 0x8000000, 0x0, 0x80000000000000},
/* idx: 312 */ {0x8000080216, 0x4000, 0x10000000, 0x0, 0x100000000000000},
/* idx: 313 */ {0x8000080216, 0x4000, 0x10000000, 0x0, 0x200000000000000},
/* idx: 314 */ {0x8000080216, 0x4000, 0x20000000, 0x0, 0x400000000000000},
/* idx: 315 */ {0x8000080216, 0x4000, 0x20000000, 0x0, 0x800000000000000},
/* idx: 316 */ {0x8000080216, 0x8000, 0x40000000, 0x0, 0x1000000000000000},
/* idx: 317 */ {0x8000080216, 0x8000, 0x40000000, 0x0, 0x2000000000000000},
/* idx: 318 */ {0x8000080216, 0x8000, 0x80000000, 0x0, 0x4000000000000000},
/* idx: 319 */ {0x8000080216, 0x8000, 0x80000000, 0x0, 0x8000000000000000},
/* idx: 320 */ {0x10000100426, 0x10000, 0x100000000, 0x0, 0x0, 0x1},
/* idx: 321 */ {0x10000100426, 0x10000, 0x100000000, 0x0, 0x0, 0x2},
/* idx: 322 */ {0x10000100426, 0x10000, 0x200000000, 0x0, 0x0, 0x4},
/* idx: 323 */ {0x10000100426, 0x10000, 0x200000000, 0x0, 0x0, 0x8},
/* idx: 324 */ {0x10000100426, 0x20000, 0x400000000, 0x0, 0x0, 0x10},
/* idx: 325 */ {0x10000100426, 0x20000, 0x400000000, 0x0, 0x0, 0x20},
/* idx: 326 */ {0x10000100426, 0x20000, 0x800000000, 0x0, 0x0, 0x40},
/* idx: 327 */ {0x10000100426, 0x20000, 0x800000000, 0x0, 0x0, 0x80},
/* idx: 328 */ {0x20000100426, 0x40000, 0x1000000000, 0x0, 0x0, 0x100},
/* idx: 329 */ {0x20000100426, 0x40000, 0x1000000000, 0x0, 0x0, 0x200},
/* idx: 330 */ {0x20000100426, 0x40000, 0x2000000000, 0x0, 0x0, 0x400},
/* idx: 331 */ {0x20000100426, 0x40000, 0x2000000000, 0x0, 0x0, 0x800},
/* idx: 332 */ {0x20000100426, 0x80000, 0x4000000000, 0x0, 0x0, 0x1000},
/* idx: 333 */ {0x20000100426, 0x80000, 0x4000000000, 0x0, 0x0, 0x2000},
/* idx: 334 */ {0x20000100426, 0x80000, 0x8000000000, 0x0, 0x0, 0x4000},
/* idx: 335 */ {0x20000100426, 0x80000, 0x8000000000, 0x0, 0x0, 0x8000},
/* idx: 336 */ {0x40000200426, 0x100000, 0x10000000000, 0x0, 0x0, 0x10000},
/* idx: 337 */ {0x40000200426, 0x100000, 0x10000000000, 0x0, 0x0, 0x20000},
/* idx: 338 */ {0x40000200426, 0x100000, 0x20000000000, 0x0, 0x0, 0x40000},
/* idx: 339 */ {0x40000200426, 0x100000, 0x20000000000, 0x0, 0x0, 0x80000},
/* idx: 340 */ {0x40000200426, 0x200000, 0x40000000000, 0x0, 0x0, 0x100000},
/* idx: 341 */ {0x40000200426, 0x200000, 0x40000000000, 0x0, 0x0, 0x200000},
/* idx: 342 */ {0x40000200426, 0x200000, 0x80000000000, 0x0, 0x0, 0x400000},
/* idx: 343 */ {0x40000200426, 0x200000, 0x80000000000, 0x0, 0x0, 0x800000},
/* idx: 344 */ {0x80000200426, 0x400000, 0x100000000000, 0x0, 0x0, 0x1000000},
/* idx: 345 */ {0x80000200426, 0x400000, 0x100000000000, 0x0, 0x0, 0x2000000},
/* idx: 346 */ {0x80000200426, 0x400000, 0x200000000000, 0x0, 0x0, 0x4000000},
/* idx: 347 */ {0x80000200426, 0x400000, 0x200000000000, 0x0, 0x0, 0x8000000},
/* idx: 348 */ {0x80000200426, 0x800000, 0x400000000000, 0x0, 0x0, 0x10000000},
/* idx: 349 */ {0x80000200426, 0x800000, 0x400000000000, 0x0, 0x0, 0x20000000},
/* idx: 350 */ {0x80000200426, 0x800000, 0x800000000000, 0x0, 0x0, 0x40000000},
/* idx: 351 */ {0x80000200426, 0x800000, 0x800000000000, 0x0, 0x0, 0x80000000},
/* idx: 352 */ {0x100000400826, 0x1000000, 0x1000000000000, 0x0, 0x0, 0x100000000},
/* idx: 353 */ {0x100000400826, 0x1000000, 0x1000000000000, 0x0, 0x0, 0x200000000},
/* idx: 354 */ {0x100000400826, 0x1000000, 0x2000000000000, 0x0, 0x0, 0x400000000},
/* idx: 355 */ {0x100000400826, 0x1000000, 0x2000000000000, 0x0, 0x0, 0x800000000},
/* idx: 356 */ {0x100000400826, 0x2000000, 0x4000000000000, 0x0, 0x0, 0x1000000000},
/* idx: 357 */ {0x100000400826, 0x2000000, 0x4000000000000, 0x0, 0x0, 0x2000000000},
/* idx: 358 */ {0x100000400826, 0x2000000, 0x8000000000000, 0x0, 0x0, 0x4000000000},
/* idx: 359 */ {0x100000400826, 0x2000000, 0x8000000000000, 0x0, 0x0, 0x8000000000},
/* idx: 360 */ {0x200000400826, 0x4000000, 0x10000000000000, 0x0, 0x0, 0x10000000000},
/* idx: 361 */ {0x200000400826, 0x4000000, 0x10000000000000, 0x0, 0x0, 0x20000000000},
/* idx: 362 */ {0x200000400826, 0x4000000, 0x20000000000000, 0x0, 0x0, 0x40000000000},
/* idx: 363 */ {0x200000400826, 0x4000000, 0x20000000000000, 0x0, 0x0, 0x80000000000},
/* idx: 364 */ {0x200000400826, 0x8000000, 0x40000000000000, 0x0, 0x0, 0x100000000000},
/* idx: 365 */ {0x200000400826, 0x8000000, 0x40000000000000, 0x0, 0x0, 0x200000000000},
/* idx: 366 */ {0x200000400826, 0x8000000, 0x80000000000000, 0x0, 0x0, 0x400000000000},
/* idx: 367 */ {0x200000400826, 0x8000000, 0x80000000000000, 0x0, 0x0, 0x800000000000},
/* idx: 368 */ {0x400000800826, 0x10000000, 0x100000000000000, 0x0, 0x0, 0x1000000000000},
/* idx: 369 */ {0x400000800826, 0x10000000, 0x100000000000000, 0x0, 0x0, 0x2000000000000},
/* idx: 370 */ {0x400000800826, 0x10000000, 0x200000000000000, 0x0, 0x0, 0x4000000000000},
/* idx: 371 */ {0x400000800826, 0x10000000, 0x200000000000000, 0x0, 0x0, 0x8000000000000},
/* idx: 372 */ {0x400000800826, 0x20000000, 0x400000000000000, 0x0, 0x0, 0x10000000000000},
/* idx: 373 */ {0x400000800826, 0x20000000, 0x400000000000000, 0x0, 0x0, 0x20000000000000},
/* idx: 374 */ {0x400000800826, 0x20000000, 0x800000000000000, 0x0, 0x0, 0x40000000000000},
/* idx: 375 */ {0x400000800826, 0x20000000, 0x800000000000000, 0x0, 0x0, 0x80000000000000},
/* idx: 376 */ {0x800000800826, 0x40000000, 0x1000000000000000, 0x0, 0x0, 0x100000000000000},
/* idx: 377 */ {0x800000800826, 0x40000000, 0x1000000000000000, 0x0, 0x0, 0x200000000000000},
/* idx: 378 */ {0x800000800826, 0x40000000, 0x2000000000000000, 0x0, 0x0, 0x400000000000000},
/* idx: 379 */ {0x800000800826, 0x40000000, 0x2000000000000000, 0x0, 0x0, 0x800000000000000},
/* idx: 380 */ {0x800000800826, 0x80000000, 0x4000000000000000, 0x0, 0x0, 0x1000000000000000},
/* idx: 381 */ {0x800000800826, 0x80000000, 0x4000000000000000, 0x0, 0x0, 0x2000000000000000},
/* idx: 382 */ {0x800000800826, 0x80000000, 0x8000000000000000, 0x0, 0x0, 0x4000000000000000},
/* idx: 383 */ {0x800000800826, 0x80000000, 0x8000000000000000, 0x0, 0x0, 0x8000000000000000},
/* idx: 384 */ {0x100000100104a, 0x100000000, 0x0, 0x1, 0x0, 0x0, 0x1},
/* idx: 385 */ {0x100000100104a, 0x100000000, 0x0, 0x1, 0x0, 0x0, 0x2},
/* idx: 386 */ {0x100000100104a, 0x100000000, 0x0, 0x2, 0x0, 0x0, 0x4},
/* idx: 387 */ {0x100000100104a, 0x100000000, 0x0, 0x2, 0x0, 0x0, 0x8},
/* idx: 388 */ {0x100000100104a, 0x200000000, 0x0, 0x4, 0x0, 0x0, 0x10},
/* idx: 389 */ {0x100000100104a, 0x200000000, 0x0, 0x4, 0x0, 0x0, 0x20},
/* idx: 390 */ {0x100000100104a, 0x200000000, 0x0, 0x8, 0x0, 0x0, 0x40},
/* idx: 391 */ {0x100000100104a, 0x200000000, 0x0, 0x8, 0x0, 0x0, 0x80},
/* idx: 392 */ {0x200000100104a, 0x400000000, 0x0, 0x10, 0x0, 0x0, 0x100},
/* idx: 393 */ {0x200000100104a, 0x400000000, 0x0, 0x10, 0x0, 0x0, 0x200},
/* idx: 394 */ {0x200000100104a, 0x400000000, 0x0, 0x20, 0x0, 0x0, 0x400},
/* idx: 395 */ {0x200000100104a, 0x400000000, 0x0, 0x20, 0x0, 0x0, 0x800},
/* idx: 396 */ {0x200000100104a, 0x800000000, 0x0, 0x40, 0x0, 0x0, 0x1000},
/* idx: 397 */ {0x200000100104a, 0x800000000, 0x0, 0x40, 0x0, 0x0, 0x2000},
/* idx: 398 */ {0x200000100104a, 0x800000000, 0x0, 0x80, 0x0, 0x0, 0x4000},
/* idx: 399 */ {0x200000100104a, 0x800000000, 0x0, 0x80, 0x0, 0x0, 0x8000},
/* idx: 400 */ {0x400000200104a, 0x1000000000, 0x0, 0x100, 0x0, 0x0, 0x10000},
/* idx: 401 */ {0x400000200104a, 0x1000000000, 0x0, 0x100, 0x0, 0x0, 0x20000},
/* idx: 402 */ {0x400000200104a, 0x1000000000, 0x0, 0x200, 0x0, 0x0, 0x40000},
/* idx: 403 */ {0x400000200104a, 0x1000000000, 0x0, 0x200, 0x0, 0x0, 0x80000},
/* idx: 404 */ {0x400000200104a, 0x2000000000, 0x0, 0x400, 0x0, 0x0, 0x100000},
/* idx: 405 */ {0x400000200104a, 0x2000000000, 0x0, 0x400, 0x0, 0x0, 0x200000},
/* idx: 406 */ {0x400000200104a, 0x2000000000, 0x0, 0x800, 0x0, 0x0, 0x400000},
/* idx: 407 */ {0x400000200104a, 0x2000000000, 0x0, 0x800, 0x0, 0x0, 0x800000},
/* idx: 408 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000, 0x0, 0x0, 0x1000000},
/* idx: 409 */ {0x800000200104a, 0x4000000000, 0x0, 0x1000, 0x0, 0x0, 0x2000000},
/* idx: 410 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000, 0x0, 0x0, 0x4000000},
/* idx: 411 */ {0x800000200104a, 0x4000000000, 0x0, 0x2000, 0x0, 0x0, 0x8000000},
/* idx: 412 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000, 0x0, 0x0, 0x10000000},
/* idx: 413 */ {0x800000200104a, 0x8000000000, 0x0, 0x4000, 0x0, 0x0, 0x20000000},
/* idx: 414 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000, 0x0, 0x0, 0x40000000},
/* idx: 415 */ {0x800000200104a, 0x8000000000, 0x0, 0x8000, 0x0, 0x0, 0x80000000},
/* idx: 416 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000, 0x0, 0x0, 0x100000000},
/* idx: 417 */ {0x1000000400204a, 0x10000000000, 0x0, 0x10000, 0x0, 0x0, 0x200000000},
/* idx: 418 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000, 0x0, 0x0, 0x400000000},
/* idx: 419 */ {0x1000000400204a, 0x10000000000, 0x0, 0x20000, 0x0, 0x0, 0x800000000},
/* idx: 420 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000, 0x0, 0x0, 0x1000000000},
/* idx: 421 */ {0x1000000400204a, 0x20000000000, 0x0, 0x40000, 0x0, 0x0, 0x2000000000},
/* idx: 422 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000, 0x0, 0x0, 0x4000000000},
/* idx: 423 */ {0x1000000400204a, 0x20000000000, 0x0, 0x80000, 0x0, 0x0, 0x8000000000},
/* idx: 424 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000, 0x0, 0x0, 0x10000000000},
/* idx: 425 */ {0x2000000400204a, 0x40000000000, 0x0, 0x100000, 0x0, 0x0, 0x20000000000},
/* idx: 426 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000, 0x0, 0x0, 0x40000000000},
/* idx: 427 */ {0x2000000400204a, 0x40000000000, 0x0, 0x200000, 0x0, 0x0, 0x80000000000},
/* idx: 428 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000, 0x0, 0x0, 0x100000000000},
/* idx: 429 */ {0x2000000400204a, 0x80000000000, 0x0, 0x400000, 0x0, 0x0, 0x200000000000},
/* idx: 430 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000, 0x0, 0x0, 0x400000000000},
/* idx: 431 */ {0x2000000400204a, 0x80000000000, 0x0, 0x800000, 0x0, 0x0, 0x800000000000},
/* idx: 432 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000, 0x0, 0x0, 0x1000000000000},
/* idx: 433 */ {0x4000000800204a, 0x100000000000, 0x0, 0x1000000, 0x0, 0x0, 0x2000000000000},
/* idx: 434 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000, 0x0, 0x0, 0x4000000000000},
/* idx: 435 */ {0x4000000800204a, 0x100000000000, 0x0, 0x2000000, 0x0, 0x0, 0x8000000000000},
/* idx: 436 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000, 0x0, 0x0, 0x10000000000000},
/* idx: 437 */ {0x4000000800204a, 0x200000000000, 0x0, 0x4000000, 0x0, 0x0, 0x20000000000000},
/* idx: 438 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000, 0x0, 0x0, 0x40000000000000},
/* idx: 439 */ {0x4000000800204a, 0x200000000000, 0x0, 0x8000000, 0x0, 0x0, 0x80000000000000},
/* idx: 440 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000, 0x0, 0x0, 0x100000000000000},
/* idx: 441 */ {0x8000000800204a, 0x400000000000, 0x0, 0x10000000, 0x0, 0x0, 0x200000000000000},
/* idx: 442 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000, 0x0, 0x0, 0x400000000000000},
/* idx: 443 */ {0x8000000800204a, 0x400000000000, 0x0, 0x20000000, 0x0, 0x0, 0x800000000000000},
/* idx: 444 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000, 0x0, 0x0, 0x1000000000000000},
/* idx: 445 */ {0x8000000800204a, 0x800000000000, 0x0, 0x40000000, 0x0, 0x0, 0x2000000000000000},
/* idx: 446 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000, 0x0, 0x0, 0x4000000000000000},
/* idx: 447 */ {0x8000000800204a, 0x800000000000, 0x0, 0x80000000, 0x0, 0x0, 0x8000000000000000},
/* idx: 448 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x1},
/* idx: 449 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x2},
/* idx: 450 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000, 0x0, 0x0, 0x0, 0x4},
/* idx: 451 */ {0x10000001000408a, 0x1000000000000, 0x0, 0x200000000, 0x0, 0x0, 0x0, 0x8},
/* idx: 452 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000, 0x0, 0x0, 0x0, 0x10},
/* idx: 453 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x400000000, 0x0, 0x0, 0x0, 0x20},
/* idx: 454 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000, 0x0, 0x0, 0x0, 0x40},
/* idx: 455 */ {0x10000001000408a, 0x2000000000000, 0x0, 0x800000000, 0x0, 0x0, 0x0, 0x80},
/* idx: 456 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000, 0x0, 0x0, 0x0, 0x100},
/* idx: 457 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x1000000000, 0x0, 0x0, 0x0, 0x200},
/* idx: 458 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000, 0x0, 0x0, 0x0, 0x400},
/* idx: 459 */ {0x20000001000408a, 0x4000000000000, 0x0, 0x2000000000, 0x0, 0x0, 0x0, 0x800},
/* idx: 460 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x1000},
/* idx: 461 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x4000000000, 0x0, 0x0, 0x0, 0x2000},
/* idx: 462 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000, 0x0, 0x0, 0x0, 0x4000},
/* idx: 463 */ {0x20000001000408a, 0x8000000000000, 0x0, 0x8000000000, 0x0, 0x0, 0x0, 0x8000},
/* idx: 464 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000, 0x0, 0x0, 0x0, 0x10000},
/* idx: 465 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x10000000000, 0x0, 0x0, 0x0, 0x20000},
/* idx: 466 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000, 0x0, 0x0, 0x0, 0x40000},
/* idx: 467 */ {0x40000002000408a, 0x10000000000000, 0x0, 0x20000000000, 0x0, 0x0, 0x0, 0x80000},
/* idx: 468 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000, 0x0, 0x0, 0x0, 0x100000},
/* idx: 469 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x40000000000, 0x0, 0x0, 0x0, 0x200000},
/* idx: 470 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000, 0x0, 0x0, 0x0, 0x400000},
/* idx: 471 */ {0x40000002000408a, 0x20000000000000, 0x0, 0x80000000000, 0x0, 0x0, 0x0, 0x800000},
/* idx: 472 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000, 0x0, 0x0, 0x0, 0x1000000},
/* idx: 473 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x100000000000, 0x0, 0x0, 0x0, 0x2000000},
/* idx: 474 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000, 0x0, 0x0, 0x0, 0x4000000},
/* idx: 475 */ {0x80000002000408a, 0x40000000000000, 0x0, 0x200000000000, 0x0, 0x0, 0x0, 0x8000000},
/* idx: 476 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000, 0x0, 0x0, 0x0, 0x10000000},
/* idx: 477 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x400000000000, 0x0, 0x0, 0x0, 0x20000000},
/* idx: 478 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0x40000000},
/* idx: 479 */ {0x80000002000408a, 0x80000000000000, 0x0, 0x800000000000, 0x0, 0x0, 0x0, 0x80000000},
/* idx: 480 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x100000000},
/* idx: 481 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x1000000000000, 0x0, 0x0, 0x0, 0x200000000},
/* idx: 482 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000, 0x0, 0x0, 0x0, 0x400000000},
/* idx: 483 */ {0x100000004000808a, 0x100000000000000, 0x0, 0x2000000000000, 0x0, 0x0, 0x0, 0x800000000},
/* idx: 484 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000, 0x0, 0x0, 0x0, 0x1000000000},
/* idx: 485 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x4000000000000, 0x0, 0x0, 0x0, 0x2000000000},
/* idx: 486 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000, 0x0, 0x0, 0x0, 0x4000000000},
/* idx: 487 */ {0x100000004000808a, 0x200000000000000, 0x0, 0x8000000000000, 0x0, 0x0, 0x0, 0x8000000000},
/* idx: 488 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000, 0x0, 0x0, 0x0, 0x10000000000},
/* idx: 489 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x10000000000000, 0x0, 0x0, 0x0, 0x20000000000},
/* idx: 490 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x40000000000},
/* idx: 491 */ {0x200000004000808a, 0x400000000000000, 0x0, 0x20000000000000, 0x0, 0x0, 0x0, 0x80000000000},
/* idx: 492 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000, 0x0, 0x0, 0x0, 0x100000000000},
/* idx: 493 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x40000000000000, 0x0, 0x0, 0x0, 0x200000000000},
/* idx: 494 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000, 0x0, 0x0, 0x0, 0x400000000000},
/* idx: 495 */ {0x200000004000808a, 0x800000000000000, 0x0, 0x80000000000000, 0x0, 0x0, 0x0, 0x800000000000},
/* idx: 496 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0x1000000000000},
/* idx: 497 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x100000000000000, 0x0, 0x0, 0x0, 0x2000000000000},
/* idx: 498 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000, 0x0, 0x0, 0x0, 0x4000000000000},
/* idx: 499 */ {0x400000008000808a, 0x1000000000000000, 0x0, 0x200000000000000, 0x0, 0x0, 0x0, 0x8000000000000},
/* idx: 500 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000, 0x0, 0x0, 0x0, 0x10000000000000},
/* idx: 501 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x400000000000000, 0x0, 0x0, 0x0, 0x20000000000000},
/* idx: 502 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000, 0x0, 0x0, 0x0, 0x40000000000000},
/* idx: 503 */ {0x400000008000808a, 0x2000000000000000, 0x0, 0x800000000000000, 0x0, 0x0, 0x0, 0x80000000000000},
/* idx: 504 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000, 0x0, 0x0, 0x0, 0x100000000000000},
/* idx: 505 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x1000000000000000, 0x0, 0x0, 0x0, 0x200000000000000},
/* idx: 506 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0x400000000000000},
/* idx: 507 */ {0x800000008000808a, 0x4000000000000000, 0x0, 0x2000000000000000, 0x0, 0x0, 0x0, 0x800000000000000},
/* idx: 508 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000, 0x0, 0x0, 0x0, 0x1000000000000000},
/* idx: 509 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x4000000000000000, 0x0, 0x0, 0x0, 0x2000000000000000},
/* idx: 510 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0x4000000000000000},
/* idx: 511 */ {0x800000008000808a, 0x8000000000000000, 0x0, 0x8000000000000000, 0x0, 0x0, 0x0, 0x8000000000000000},
}

1263
vendor/github.com/gaissmai/bart/node.go generated vendored

File diff suppressed because it is too large Load Diff

305
vendor/github.com/gaissmai/bart/overlaps.go generated vendored Normal file
View File

@@ -0,0 +1,305 @@
package bart
import (
"net/netip"
"github.com/gaissmai/bart/internal/bitset"
)
// overlaps returns true if any IP in the nodes n or o overlaps.
func (n *node[V]) overlaps(o *node[V], depth int) bool {
nPfxCount := n.prefixes.Len()
oPfxCount := o.prefixes.Len()
nChildCount := n.children.Len()
oChildCount := o.children.Len()
// ##############################
// 1. Test if any routes overlaps
// ##############################
// full cross check
if nPfxCount > 0 && oPfxCount > 0 {
if n.overlapsRoutes(o) {
return true
}
}
// ####################################
// 2. Test if routes overlaps any child
// ####################################
// swap nodes to help chance on its way,
// if the first call to expensive overlapsChildrenIn() is already true,
// if both orders are false it doesn't help either
if nChildCount > oChildCount {
n, o = o, n
nPfxCount = n.prefixes.Len()
oPfxCount = o.prefixes.Len()
nChildCount = n.children.Len()
oChildCount = o.children.Len()
}
if nPfxCount > 0 && oChildCount > 0 {
if n.overlapsChildrenIn(o) {
return true
}
}
// symmetric reverse
if oPfxCount > 0 && nChildCount > 0 {
if o.overlapsChildrenIn(n) {
return true
}
}
// ###########################################
// 3. childs with same octet in nodes n and o
// ###########################################
// stop condition, n or o have no childs
if nChildCount == 0 || oChildCount == 0 {
return false
}
// stop condition, no child with identical octet in n and o
if !n.children.IntersectsAny(o.children.BitSet) {
return false
}
return n.overlapsSameChildren(o, depth)
}
// overlapsRoutes, test if n overlaps o prefixes and vice versa
func (n *node[V]) overlapsRoutes(o *node[V]) bool {
// some prefixes are identical, trivial overlap
if n.prefixes.IntersectsAny(o.prefixes.BitSet) {
return true
}
// get the lowest idx (biggest prefix)
nFirstIdx, _ := n.prefixes.FirstSet()
oFirstIdx, _ := o.prefixes.FirstSet()
// start with other min value, see ART algo
nIdx := oFirstIdx
oIdx := nFirstIdx
// make full cross check
nOK := true
oOK := true
// zip, range over n and o together to help chance on its way
for nOK || oOK {
if nOK {
// does any route in o overlap this prefix from n
if nIdx, nOK = n.prefixes.NextSet(nIdx); nOK {
if o.lpmTest(nIdx) {
return true
}
nIdx++
}
}
if oOK {
// does any route in n overlap this prefix from o
if oIdx, oOK = o.prefixes.NextSet(oIdx); oOK {
if n.lpmTest(oIdx) {
return true
}
oIdx++
}
}
}
return false
}
// overlapsChildrenIn, test if prefixes in n overlaps child octets in o.
func (n *node[V]) overlapsChildrenIn(o *node[V]) bool {
pfxCount := n.prefixes.Len()
childCount := o.children.Len()
// heuristic, compare benchmarks
// when will we range over the children and when will we do bitset calc?
magicNumber := 15
doRange := childCount < magicNumber || pfxCount > magicNumber
// do range over, not so many childs and maybe to many prefixes for other algo below
if doRange {
lowerBound, _ := n.prefixes.FirstSet()
for _, addr := range o.children.AsSlice(make([]uint, 0, maxNodeChildren)) {
idx := hostIndex(addr)
if idx < lowerBound { // lpm match impossible
continue
}
if n.lpmTest(idx) {
return true
}
}
return false
}
// do bitset intersection, alloted route table with child octets
// maybe to many childs for range over or not so many prefixes to
// build the alloted routing table from them
// make allot table with prefixes as bitsets, bitsets are precalculated
// just union the bitsets to one bitset (allot table) for all prefixes
// in this node
prefixRoutes := bitset.BitSet(make([]uint64, 8))
allIndices := n.prefixes.AsSlice(make([]uint, 0, maxNodePrefixes))
for _, idx := range allIndices {
// get pre alloted bitset for idx
prefixRoutes.InPlaceUnion(allotLookupTbl[idx])
}
// clone a bitset without heap allocation
// shift-right children bitset by 256 (firstHostIndex)
c8 := make([]uint64, 8)
copy(c8[4:], o.children.BitSet) // 4*64= 256
hostRoutes := bitset.BitSet(c8)
return prefixRoutes.IntersectsAny(hostRoutes)
}
// overlapsSameChildren, find same octets with bitset intersection.
func (n *node[V]) overlapsSameChildren(o *node[V], depth int) bool {
// clone a bitset without heap allocation
c4 := [4]uint64{}
copy(c4[:], n.children.BitSet)
nChildrenBitsetCloned := bitset.BitSet(c4[:])
// intersect in place the cloned child bitset from n with o
nChildrenBitsetCloned.InPlaceIntersection(o.children.BitSet)
allCommonChildren := nChildrenBitsetCloned.AsSlice(make([]uint, 0, maxNodeChildren))
// range over all child addrs, common in n and o
for _, addr := range allCommonChildren {
nChild := n.children.MustGet(addr)
oChild := o.children.MustGet(addr)
if overlapsTwoChilds[V](nChild, oChild, depth+1) {
return true
}
}
return false
}
// overlapsTwoChilds, childs can be node or leaf.
func overlapsTwoChilds[V any](nChild, oChild any, depth int) bool {
// 4 possible different combinations for n and o
//
// node, node --> overlapsRec
// node, leaf --> overlapsPrefixAtDepth
// leaf, node --> overlapsPrefixAtDepth
// leaf, leaf --> netip.Prefix.Overlaps
//
switch nKind := nChild.(type) {
case *node[V]:
switch oKind := oChild.(type) {
case *node[V]: // node, node
return nKind.overlaps(oKind, depth)
case *leaf[V]: // node, leaf
return nKind.overlapsPrefixAtDepth(oKind.prefix, depth)
}
case *leaf[V]:
switch oKind := oChild.(type) {
case *node[V]: // leaf, node
return oKind.overlapsPrefixAtDepth(nKind.prefix, depth)
case *leaf[V]: // leaf, leaf
return oKind.prefix.Overlaps(nKind.prefix)
}
default:
panic("logic error, wrong node type")
}
return false
}
// overlapsPrefixAtDepth, returns true if node overlaps with prefix
// starting with prefix octet at depth.
//
// Needed for path compressed prefix some level down in the node trie.
func (n *node[V]) overlapsPrefixAtDepth(pfx netip.Prefix, depth int) bool {
ip := pfx.Addr()
bits := pfx.Bits()
lastIdx, lastBits := lastOctetIdxAndBits(bits)
octets := ip.AsSlice()
octets = octets[:lastIdx+1]
for ; depth < len(octets); depth++ {
octet := octets[depth]
addr := uint(octet)
// full octet path in node trie, check overlap with last prefix octet
if depth == lastIdx {
return n.overlapsIdx(pfxToIdx(octet, lastBits))
}
// test if any route overlaps prefix´ so far
// no best match needed, forward tests without backtracking
if n.prefixes.Len() != 0 && n.lpmTest(hostIndex(addr)) {
return true
}
if !n.children.Test(addr) {
return false
}
// next child, node or leaf
switch kid := n.children.MustGet(addr).(type) {
case *node[V]:
n = kid
continue
case *leaf[V]:
return kid.prefix.Overlaps(pfx)
default:
panic("logic error, wrong node type")
}
}
panic("unreachable: " + pfx.String())
}
// overlapsIdx returns true if node overlaps with prefix.
func (n *node[V]) overlapsIdx(idx uint) bool {
// 1. Test if any route in this node overlaps prefix?
if n.lpmTest(idx) {
return true
}
// 2. Test if prefix overlaps any route in this node
// use bitset intersections instead of range loops
// shallow copy pre alloted bitset for idx
allotedPrefixRoutes := allotLookupTbl[idx]
if allotedPrefixRoutes.IntersectsAny(n.prefixes.BitSet) {
return true
}
// 3. Test if prefix overlaps any child in this node
// shift-right children bitset by 256 (firstHostIndex)
c8 := [8]uint64{}
copy(c8[4:], n.children.BitSet) // 4*64= 256
hostRoutes := bitset.BitSet(c8[:])
// use bitsets intersection instead of range loops
return allotedPrefixRoutes.IntersectsAny(hostRoutes)
}

View File

@@ -5,6 +5,7 @@ package bart
import (
"bytes"
"cmp"
"fmt"
"io"
"net/netip"
@@ -18,7 +19,8 @@ import (
type kid[V any] struct {
// for traversing
n *node[V]
path [16]byte
is4 bool
path stridePath
depth int
idx uint
@@ -27,14 +29,14 @@ type kid[V any] struct {
val V
}
// MarshalText implements the encoding.TextMarshaler interface,
// MarshalText implements the [encoding.TextMarshaler] interface,
// just a wrapper for [Table.Fprint].
func (t *Table[V]) MarshalText() ([]byte, error) {
t.init()
w := new(bytes.Buffer)
if err := t.Fprint(w); err != nil {
return nil, err
}
return w.Bytes(), nil
}
@@ -42,46 +44,47 @@ func (t *Table[V]) MarshalText() ([]byte, error) {
// as string, just a wrapper for [Table.Fprint].
// If Fprint returns an error, String panics.
func (t *Table[V]) String() string {
t.init()
w := new(strings.Builder)
if err := t.Fprint(w); err != nil {
panic(err)
}
return w.String()
}
// Fprint writes a hierarchical tree diagram of the ordered CIDRs to w.
// If w is nil, Fprint panics.
// Fprint writes a hierarchical tree diagram of the ordered CIDRs
// with default formatted payload V to w. If w is nil, Fprint panics.
//
// The order from top to bottom is in ascending order of the prefix address
// and the subtree structure is determined by the CIDRs coverage.
//
// ▼
// ├─ 10.0.0.0/8 (9.9.9.9)
// │ ├─ 10.0.0.0/24 (8.8.8.8)
// │ └─ 10.0.1.0/24 (10.0.0.0)
// ├─ 127.0.0.0/8 (127.0.0.1)
// │ └─ 127.0.0.1/32 (127.0.0.1)
// ├─ 169.254.0.0/16 (10.0.0.0)
// ├─ 172.16.0.0/12 (8.8.8.8)
// └─ 192.168.0.0/16 (9.9.9.9)
// └─ 192.168.1.0/24 (127.0.0.1)
// ├─ 10.0.0.0/8 (V)
// │ ├─ 10.0.0.0/24 (V)
// │ └─ 10.0.1.0/24 (V)
// ├─ 127.0.0.0/8 (V)
// │ └─ 127.0.0.1/32 (V)
// ├─ 169.254.0.0/16 (V)
// ├─ 172.16.0.0/12 (V)
// └─ 192.168.0.0/16 (V)
// └─ 192.168.1.0/24 (V)
// ▼
// └─ ::/0 (2001:db8::1)
// ├─ ::1/128 (::1%lo)
// ├─ 2000::/3 (2001:db8::1)
// │ └─ 2001:db8::/32 (2001:db8::1)
// └─ fe80::/10 (::1%eth0)
// └─ ::/0 (V)
// ├─ ::1/128 (V)
// ├─ 2000::/3 (V)
// │ └─ 2001:db8::/32 (V)
// └─ fe80::/10 (V)
func (t *Table[V]) Fprint(w io.Writer) error {
t.init()
// v4
if err := t.fprint(w, true); err != nil {
return err
}
// v6
if err := t.fprint(w, false); err != nil {
return err
}
return nil
}
@@ -95,16 +98,30 @@ func (t *Table[V]) fprint(w io.Writer, is4 bool) error {
if _, err := fmt.Fprint(w, "▼\n"); err != nil {
return err
}
if err := n.fprintRec(w, 0, zeroPath, 0, is4, ""); err != nil {
startKid := kid[V]{
n: nil,
idx: 0,
path: stridePath{},
is4: is4,
}
if err := n.fprintRec(w, startKid, ""); err != nil {
return err
}
return nil
}
// fprintRec, the output is a hierarchical CIDR tree starting with parentIdx and byte path.
func (n *node[V]) fprintRec(w io.Writer, parentIdx uint, path [16]byte, depth int, is4 bool, pad string) error {
// get direct childs for this parentIdx ...
directKids := n.getKidsRec(parentIdx, path, depth, is4)
// fprintRec, the output is a hierarchical CIDR tree starting with this kid.
func (n *node[V]) fprintRec(w io.Writer, parent kid[V], pad string) error {
// recursion stop condition
if n == nil {
return nil
}
// get direct childs for this kid ...
directKids := n.getKidsRec(parent.idx, parent.path, parent.depth, parent.is4)
// sort them by netip.Prefix, not by baseIndex
slices.SortFunc(directKids, cmpKidByPrefix[V])
@@ -129,7 +146,7 @@ func (n *node[V]) fprintRec(w io.Writer, parentIdx uint, path [16]byte, depth in
// rec-descent with this prefix as parentIdx.
// hierarchical nested tree view, two rec-descent functions
// work together to spoil the reader.
if err := kid.n.fprintRec(w, kid.idx, kid.path, kid.depth, is4, pad+spacer); err != nil {
if err := kid.n.fprintRec(w, kid, pad+spacer); err != nil {
return err
}
}
@@ -143,71 +160,104 @@ func (n *node[V]) fprintRec(w io.Writer, parentIdx uint, path [16]byte, depth in
//
// See the artlookup.pdf paper in the doc folder,
// the baseIndex function is the key.
func (n *node[V]) getKidsRec(parentIdx uint, path [16]byte, depth int, is4 bool) []kid[V] {
directKids := []kid[V]{}
func (n *node[V]) getKidsRec(parentIdx uint, path stridePath, depth int, is4 bool) []kid[V] {
// recursion stop condition
if n == nil {
return nil
}
// make backing arrays, no heap allocs
idxBackingArray := [maxNodePrefixes]uint{}
for _, idx := range n.allStrideIndexes(idxBackingArray[:]) {
var directKids []kid[V]
for _, idx := range n.prefixes.All() {
// parent or self, handled alreday in an upper stack frame.
if idx <= parentIdx {
continue
}
// check if lpmIdx for this idx' parent is equal to parentIdx
lpmIdx, _, _ := n.lpm(idx >> 1)
if lpmIdx == parentIdx {
// idx is directKid
val, _ := n.getValue(idx)
cidr, _ := cidrFromPath(path, depth, is4, idx)
lpmIdx, _, _ := n.lpmGet(idx >> 1)
directKids = append(directKids, kid[V]{n, path, depth, idx, cidr, val})
// if idx is directKid?
if lpmIdx == parentIdx {
cidr := cidrFromPath(path, depth, is4, idx)
kid := kid[V]{
n: n,
is4: is4,
path: path,
depth: depth,
idx: idx,
cidr: cidr,
val: n.prefixes.MustGet(idx),
}
directKids = append(directKids, kid)
}
}
// the node may have childs, the rec-descent monster starts
addrBackingArray := [maxNodeChildren]uint{}
for i, addr := range n.allChildAddrs(addrBackingArray[:]) {
octet := byte(addr)
// the node may have childs and leaves, the rec-descent monster starts
for i, addr := range n.children.All() {
// do a longest-prefix-match
lpmIdx, _, _ := n.lpm(octetToBaseIndex(octet))
lpmIdx, _, _ := n.lpmGet(hostIndex(addr))
if lpmIdx == parentIdx {
c := n.children[i]
path[depth] = octet
switch k := n.children.Items[i].(type) {
case *node[V]:
path[depth] = byte(addr)
// traverse, rec-descent call with next child node
directKids = append(directKids, c.getKidsRec(0, path, depth+1, is4)...)
// traverse, rec-descent call with next child node
directKids = append(directKids, k.getKidsRec(0, path, depth+1, is4)...)
case *leaf[V]:
kid := kid[V]{
n: nil, // path compressed item, stop recursion
is4: is4,
cidr: k.prefix,
val: k.value,
}
directKids = append(directKids, kid)
}
}
}
return directKids
}
// cidrFromPath, get prefix back from byte path, depth, octet and pfxLen.
func cidrFromPath(path [16]byte, depth int, is4 bool, idx uint) (netip.Prefix, error) {
octet, pfxLen := baseIndexToPrefix(idx)
// cmpKidByPrefix, all prefixes are already normalized (Masked).
func cmpKidByPrefix[V any](a, b kid[V]) int {
return cmpPrefix(a.cidr, b.cidr)
}
// set (partially) masked byte in path at depth
// cmpPrefix, compare func for prefix sort,
// all cidrs are already normalized
func cmpPrefix(a, b netip.Prefix) int {
if cmp := a.Addr().Compare(b.Addr()); cmp != 0 {
return cmp
}
return cmp.Compare(a.Bits(), b.Bits())
}
// cidrFromPath, get prefix back from byte path, depth, octet and pfxLen.
func cidrFromPath(path stridePath, depth int, is4 bool, idx uint) netip.Prefix {
octet, pfxLen := idxToPfx(idx)
// set masked byte in path at depth
path[depth] = octet
// zero/mask the bytes after prefix bits
clear(path[depth+1:])
// make ip addr from octets
var ip netip.Addr
if is4 {
b4 := [4]byte{}
copy(b4[:], path[:4])
ip = netip.AddrFrom4(b4)
ip = netip.AddrFrom4([4]byte(path[:4]))
} else {
ip = netip.AddrFrom16(path)
}
// calc bits with pathLen and pfxLen
bits := depth*strideLen + pfxLen
bits := depth<<3 + pfxLen
// make a normalized prefix from ip/bits
return ip.Prefix(bits)
}
// cmpKidByPrefix, all prefixes are already normalized (Masked).
func cmpKidByPrefix[V any](a, b kid[V]) int {
return cmpPrefix(a.cidr, b.cidr)
// return a normalized prefix from ip/bits
return netip.PrefixFrom(ip, bits)
}

File diff suppressed because it is too large Load Diff