├── .travis.yml ├── queue.go ├── radix32.go ├── radix64.go └── radix_test.go /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | -------------------------------------------------------------------------------- /queue.go: -------------------------------------------------------------------------------- 1 | package bitradix 2 | 3 | type node32 struct { 4 | *Radix32 5 | branch int // -1 root, 0 left branch, 1 right branch 6 | } 7 | type queue32 []*node32 8 | 9 | type node64 struct { 10 | *Radix64 11 | branch int 12 | } 13 | type queue64 []*node64 14 | 15 | // Push adds a node32 to the queue. 16 | func (q *queue32) Push(n *node32) { 17 | *q = append(*q, n) 18 | } 19 | 20 | // Pop removes and returns a node from the queue in first to last order. 21 | func (q *queue32) Pop() *node32 { 22 | lq := len(*q) 23 | if lq == 0 { 24 | return nil 25 | } 26 | n := (*q)[0] 27 | switch lq { 28 | case 1: 29 | *q = (*q)[:0] 30 | default: 31 | *q = (*q)[1:lq] 32 | } 33 | return n 34 | } 35 | 36 | func (q *queue64) Push(n *node64) { 37 | *q = append(*q, n) 38 | } 39 | 40 | func (q *queue64) Pop() *node64 { 41 | lq := len(*q) 42 | if lq == 0 { 43 | return nil 44 | } 45 | n := (*q)[0] 46 | switch lq { 47 | case 1: 48 | *q = (*q)[:0] 49 | default: 50 | *q = (*q)[1:lq] 51 | } 52 | return n 53 | } 54 | -------------------------------------------------------------------------------- /radix32.go: -------------------------------------------------------------------------------- 1 | // Package bitradix implements a radix tree that branches on the bits of a 32 or 2 | // 64 bits unsigned integer key. 3 | // 4 | // A radix tree is defined in: 5 | // Donald R. Morrison. "PATRICIA -- practical algorithm to retrieve 6 | // information coded in alphanumeric". Journal of the ACM, 15(4):514-534, 7 | // October 1968 8 | // 9 | // This website provides some background information on Radix trees. 10 | // http://faculty.simpson.edu/lydia.sinapova/www/cmsc250/LN250_Weiss/L08-Radix.htm 11 | package bitradix 12 | 13 | const ( 14 | bitSize32 = 32 15 | bitSize64 = 64 16 | mask32 = 0xFFFFFFFF 17 | mask64 = 0xFFFFFFFFFFFFFFFF 18 | ) 19 | 20 | // Radix32 implements a radix tree with an uint32 as its key. 21 | type Radix32 struct { 22 | branch [2]*Radix32 // branch[0] is left branch for 0, and branch[1] the right for 1 23 | parent *Radix32 24 | key uint32 // the key under which this value is stored 25 | bits int // the number of significant bits, if 0 the key has not been set. 26 | Value interface{} // The value stored. 27 | } 28 | 29 | // New32 returns an empty, initialized Radix32 tree. 30 | func New32() *Radix32 { 31 | // It gets two branches by default 32 | return &Radix32{[2]*Radix32{ 33 | &Radix32{[2]*Radix32{nil, nil}, nil, 0, 0, nil}, 34 | &Radix32{[2]*Radix32{nil, nil}, nil, 0, 0, nil}, 35 | }, nil, 0, 0, nil} 36 | } 37 | 38 | // Key returns the key under which this node is stored. 39 | func (r *Radix32) Key() uint32 { 40 | return r.key 41 | } 42 | 43 | // Bits returns the number of significant bits for the key. 44 | // A value of zero indicates a key that has not been set. 45 | func (r *Radix32) Bits() int { 46 | return r.bits 47 | } 48 | 49 | // Leaf returns true is r is an leaf node, when false is returned 50 | // the node is a non-leaf node. 51 | func (r *Radix32) Leaf() bool { 52 | return r.branch[0] == nil && r.branch[1] == nil 53 | } 54 | 55 | // Insert inserts a new value n in the tree r (possibly silently overwriting an existing value). 56 | // It returns the inserted node, r must be the root of the tree. 57 | func (r *Radix32) Insert(n uint32, bits int, v interface{}) *Radix32 { 58 | if r.parent != nil { 59 | panic("bitradix: not the root node") 60 | } 61 | return r.insert(n, bits, v, bitSize32-1) 62 | } 63 | 64 | // Remove removes a value from the tree r. It returns the node removed, or nil 65 | // when nothing is found, r must be the root of the tree. 66 | func (r *Radix32) Remove(n uint32, bits int) *Radix32 { 67 | if r.parent != nil { 68 | panic("bitradix: not the root node") 69 | } 70 | return r.remove(n, bits, bitSize32-1) 71 | } 72 | 73 | // Find searches the tree for the key n, where the first bits bits of n 74 | // are significant. It returns the node found or a node with a common prefix. It 75 | // returns nil when nothing can be found. 76 | func (r *Radix32) Find(n uint32, bits int) *Radix32 { 77 | if r.parent != nil { 78 | panic("bitradix: not the root node") 79 | } 80 | return r.find(n, bits, bitSize32-1, nil) 81 | } 82 | 83 | // Do traverses the tree r in breadth-first order. For each visited node, 84 | // the function f is called with the current node, and the branch taken 85 | // (0 for the zero, 1 for the one branch, -1 is used for the root node). 86 | func (r *Radix32) Do(f func(*Radix32, int)) { 87 | q := make(queue32, 0) 88 | 89 | q.Push(&node32{r, -1}) 90 | x := q.Pop() 91 | for x != nil { 92 | f(x.Radix32, x.branch) 93 | for i, b := range x.Radix32.branch { 94 | if b != nil { 95 | q.Push(&node32{b, i}) 96 | } 97 | } 98 | x = q.Pop() 99 | } 100 | } 101 | 102 | // Implement insert 103 | func (r *Radix32) insert(n uint32, bits int, v interface{}, bit int) *Radix32 { 104 | switch r.Leaf() { 105 | case false: // Non-leaf node, one or two branches, possibly a key 106 | if bit < 0 { 107 | panic("bitradix: bit index smaller than zero") 108 | } 109 | bnew := bitK32(n, bit) 110 | if r.bits == 0 && bits == bitSize32-bit { // I should be put here 111 | r.set(n, bits, v) 112 | return r 113 | } 114 | if r.bits > 0 && bits == bitSize32-bit { 115 | bcur := bitK32(r.key, bit) 116 | if r.bits > bits { 117 | b1 := r.bits 118 | n1 := r.key 119 | v1 := r.Value 120 | r.set(n, bits, v) 121 | if r.branch[bcur] == nil { 122 | r.branch[bcur] = r.new() 123 | } 124 | r.branch[bcur].insert(n1, b1, v1, bit-1) 125 | return r 126 | } 127 | } 128 | if r.branch[bnew] == nil { 129 | r.branch[bnew] = r.new() 130 | } 131 | return r.branch[bnew].insert(n, bits, v, bit-1) 132 | case true: // External node, (optional) key, no branches 133 | if r.bits == 0 || r.key == n { // nothing here yet, put something in, or equal keys 134 | r.set(n, bits, v) 135 | return r 136 | } 137 | if bit < 0 { 138 | panic("bitradix: bit index smaller than zero") 139 | } 140 | bcur := bitK32(r.key, bit) 141 | bnew := bitK32(n, bit) 142 | if bcur == bnew { 143 | r.branch[bcur] = r.new() 144 | if r.bits > 0 && (bits == bitSize32-bit || bits < r.bits) { 145 | b1 := r.bits 146 | n1 := r.key 147 | v1 := r.Value 148 | r.set(n, bits, v) 149 | r.branch[bnew].insert(n1, b1, v1, bit-1) 150 | return r 151 | } 152 | if r.bits > 0 && bits >= r.bits { 153 | // current key can not be put further down, leave it 154 | // but continue 155 | return r.branch[bnew].insert(n, bits, v, bit-1) 156 | } 157 | // fill this node, with the current key - and call ourselves 158 | r.branch[bcur].set(r.key, r.bits, r.Value) 159 | r.clear() 160 | return r.branch[bnew].insert(n, bits, v, bit-1) 161 | } 162 | // not equal, keep current node, and branch off in child 163 | r.branch[bcur] = r.new() 164 | // fill this node, with the current key - and call ourselves 165 | r.branch[bcur].set(r.key, r.bits, r.Value) 166 | r.clear() 167 | r.branch[bnew] = r.new() 168 | return r.branch[bnew].insert(n, bits, v, bit-1) 169 | } 170 | panic("bitradix: not reached") 171 | } 172 | 173 | // Walk the tree searching for n, keep the last node that has a key in tow. 174 | // This is the node we should retreat to when we find and delete our node. 175 | func (r *Radix32) remove(n uint32, bits, bit int) *Radix32 { 176 | if r.bits > 0 && r.bits == bits { 177 | // possible hit 178 | mask := uint32(mask32 << (bitSize32 - uint(r.bits))) 179 | if r.key&mask == n&mask { 180 | // save r in r1 181 | r1 := &Radix32{[2]*Radix32{nil, nil}, nil, r.key, r.bits, r.Value} 182 | r.prune(true) 183 | return r1 184 | } 185 | } 186 | k := bitK32(n, bit) 187 | if r.Leaf() || r.branch[k] == nil { // dead end 188 | return nil 189 | } 190 | return r.branch[bitK32(n, bit)].remove(n, bits, bit-1) 191 | } 192 | 193 | // Prune the tree, when b is true the current node is deleted. 194 | func (r *Radix32) prune(b bool) { 195 | if b { 196 | if r.parent == nil { 197 | r.clear() 198 | return 199 | } 200 | // we are a node, we have a parent, so the parent is a non-leaf node 201 | if r.parent.branch[0] == r { 202 | // kill that branch 203 | r.parent.branch[0] = nil 204 | } 205 | if r.parent.branch[1] == r { 206 | r.parent.branch[1] = nil 207 | } 208 | r.parent.prune(false) 209 | return 210 | } 211 | if r == nil { 212 | return 213 | } 214 | if r.bits != 0 { 215 | // fun stops 216 | return 217 | } 218 | // Does I have one or two childeren, if one, move my self up one node 219 | // Also the child must be a leaf node! 220 | b0 := r.branch[0] 221 | b1 := r.branch[1] 222 | if b0 != nil && b1 != nil { 223 | // two branches, we cannot replace ourselves with a child 224 | return 225 | } 226 | if b0 != nil { 227 | if !b0.Leaf() { 228 | return 229 | } 230 | // move b0 into this node 231 | r.set(b0.key, b0.bits, b0.Value) 232 | r.branch[0] = b0.branch[0] 233 | r.branch[1] = b0.branch[1] 234 | } 235 | if b1 != nil { 236 | if !b1.Leaf() { 237 | return 238 | } 239 | // move b1 into this node 240 | r.set(b1.key, b1.bits, b1.Value) 241 | r.branch[0] = b1.branch[0] 242 | r.branch[1] = b1.branch[1] 243 | } 244 | r.parent.prune(false) 245 | } 246 | 247 | func (r *Radix32) find(n uint32, bits, bit int, last *Radix32) *Radix32 { 248 | switch r.Leaf() { 249 | case false: 250 | // A prefix that is matching (BETTER MATCHING) 251 | mask := uint32(mask32 << (bitSize32 - uint(r.bits))) 252 | if r.bits > 0 && r.key&mask == n&mask { 253 | // fmt.Printf("Setting last to %d %s\n", r.key, r.Value) 254 | if last == nil { 255 | last = r 256 | } else { 257 | // Only when bigger 258 | if r.bits >= last.bits { 259 | last = r 260 | } 261 | } 262 | } 263 | if r.bits == bits && r.key&mask == n&mask { 264 | // our key 265 | return r 266 | } 267 | 268 | k := bitK32(n, bit) 269 | if r.branch[k] == nil { 270 | return last // REALLY? 271 | } 272 | return r.branch[k].find(n, bits, bit-1, last) 273 | case true: 274 | // It this our key...!? 275 | mask := uint32(mask32 << (bitSize32 - uint(r.bits))) 276 | if r.key&mask == n&mask { 277 | return r 278 | } 279 | return last 280 | } 281 | panic("bitradix: not reached") 282 | } 283 | 284 | // Return a new node, with r as its parent 285 | func (r *Radix32) new() *Radix32 { 286 | return &Radix32{[2]*Radix32{nil, nil}, r, 0, 0, nil} 287 | } 288 | 289 | func (r *Radix32) set(key uint32, bits int, value interface{}) { 290 | r.key = key 291 | r.bits = bits 292 | r.Value = value 293 | } 294 | 295 | func (r *Radix32) clear() { 296 | r.key = 0 297 | r.bits = 0 298 | r.Value = nil 299 | } 300 | 301 | // From: http://stackoverflow.com/questions/2249731/how-to-get-bit-by-bit-data-from-a-integer-value-in-c 302 | 303 | // Return bit k from n. We count from the right, MSB left. 304 | // So k = 0 is the last bit on the left and k = 31 is the first bit on the right. 305 | func bitK32(n uint32, k int) byte { 306 | return byte((n & (1 << uint(k))) >> uint(k)) 307 | } 308 | -------------------------------------------------------------------------------- /radix64.go: -------------------------------------------------------------------------------- 1 | package bitradix 2 | 3 | // Radix64 implements a radix tree with an uint64 as its key. 4 | type Radix64 struct { 5 | branch [2]*Radix64 // branch[0] is left branch for 0, and branch[1] the right for 1 6 | parent *Radix64 7 | key uint64 // the key under which this value is stored 8 | bits int // the number of significant bits, if 0 the key has not been set. 9 | Value interface{} // The value stored. 10 | } 11 | 12 | func New64() *Radix64 { 13 | // It gets two branches by default 14 | return &Radix64{[2]*Radix64{ 15 | &Radix64{[2]*Radix64{nil, nil}, nil, 0, 0, nil}, 16 | &Radix64{[2]*Radix64{nil, nil}, nil, 0, 0, nil}, 17 | }, nil, 0, 0, nil} 18 | } 19 | 20 | func (r *Radix64) Key() uint64 { 21 | return r.key 22 | } 23 | 24 | func (r *Radix64) Bits() int { 25 | return r.bits 26 | } 27 | 28 | func (r *Radix64) Leaf() bool { 29 | return r.branch[0] == nil && r.branch[1] == nil 30 | } 31 | 32 | func (r *Radix64) Insert(n uint64, bits int, v interface{}) *Radix64 { 33 | if r.parent != nil { 34 | panic("bitradix: not the root node") 35 | } 36 | return r.insert(n, bits, v, bitSize32-1) 37 | } 38 | 39 | func (r *Radix64) Remove(n uint64, bits int) *Radix64 { 40 | if r.parent != nil { 41 | panic("bitradix: not the root node") 42 | } 43 | return r.remove(n, bits, bitSize32-1) 44 | } 45 | 46 | func (r *Radix64) Find(n uint64, bits int) *Radix64 { 47 | if r.parent != nil { 48 | panic("bitradix: not the root node") 49 | } 50 | return r.find(n, bits, bitSize32-1, nil) 51 | } 52 | 53 | func (r *Radix64) Do(f func(*Radix64, int)) { 54 | q := make(queue64, 0) 55 | 56 | q.Push(&node64{r, -1}) 57 | x := q.Pop() 58 | for x != nil { 59 | f(x.Radix64, x.branch) 60 | for i, b := range x.Radix64.branch { 61 | if b != nil { 62 | q.Push(&node64{b, i}) 63 | } 64 | } 65 | x = q.Pop() 66 | } 67 | } 68 | 69 | func (r *Radix64) insert(n uint64, bits int, v interface{}, bit int) *Radix64 { 70 | switch r.Leaf() { 71 | case false: // Non-leaf node, one or two branches, possibly a key 72 | if bit < 0 { 73 | panic("bitradix: bit index smaller than zero") 74 | } 75 | bnew := bitK64(n, bit) 76 | if r.bits == 0 && bits == bitSize32-bit { // I should be put here 77 | r.set(n, bits, v) 78 | return r 79 | } 80 | if r.bits > 0 && bits == bitSize32-bit { 81 | bcur := bitK64(r.key, bit) 82 | if r.bits > bits { 83 | b1 := r.bits 84 | n1 := r.key 85 | v1 := r.Value 86 | r.set(n, bits, v) 87 | if r.branch[bcur] == nil { 88 | r.branch[bcur] = r.new() 89 | } 90 | r.branch[bcur].insert(n1, b1, v1, bit-1) 91 | return r 92 | } 93 | } 94 | if r.branch[bnew] == nil { 95 | r.branch[bnew] = r.new() 96 | } 97 | return r.branch[bnew].insert(n, bits, v, bit-1) 98 | case true: // External node, (optional) key, no branches 99 | if r.bits == 0 || r.key == n { // nothing here yet, put something in, or equal keys 100 | r.set(n, bits, v) 101 | return r 102 | } 103 | if bit < 0 { 104 | panic("bitradix: bit index smaller than zero") 105 | } 106 | bcur := bitK64(r.key, bit) 107 | bnew := bitK64(n, bit) 108 | if bcur == bnew { 109 | r.branch[bcur] = r.new() 110 | if r.bits > 0 && (bits == bitSize32-bit || bits < r.bits) { 111 | b1 := r.bits 112 | n1 := r.key 113 | v1 := r.Value 114 | r.set(n, bits, v) 115 | r.branch[bnew].insert(n1, b1, v1, bit-1) 116 | return r 117 | } 118 | if r.bits > 0 && bits >= r.bits { 119 | // current key can not be put further down, leave it 120 | // but continue 121 | return r.branch[bnew].insert(n, bits, v, bit-1) 122 | } 123 | // fill this node, with the current key - and call ourselves 124 | r.branch[bcur].set(r.key, r.bits, r.Value) 125 | r.clear() 126 | return r.branch[bnew].insert(n, bits, v, bit-1) 127 | } 128 | // not equal, keep current node, and branch off in child 129 | r.branch[bcur] = r.new() 130 | // fill this node, with the current key - and call ourselves 131 | r.branch[bcur].set(r.key, r.bits, r.Value) 132 | r.clear() 133 | r.branch[bnew] = r.new() 134 | return r.branch[bnew].insert(n, bits, v, bit-1) 135 | } 136 | panic("bitradix: not reached") 137 | } 138 | 139 | func (r *Radix64) remove(n uint64, bits, bit int) *Radix64 { 140 | if r.bits > 0 && r.bits == bits { 141 | // possible hit 142 | mask := uint64(mask64 << (bitSize32 - uint(r.bits))) 143 | if r.key&mask == n&mask { 144 | // save r in r1 145 | r1 := &Radix64{[2]*Radix64{nil, nil}, nil, r.key, r.bits, r.Value} 146 | r.prune(true) 147 | return r1 148 | } 149 | } 150 | k := bitK64(n, bit) 151 | if r.Leaf() || r.branch[k] == nil { // dead end 152 | return nil 153 | } 154 | return r.branch[bitK64(n, bit)].remove(n, bits, bit-1) 155 | } 156 | 157 | func (r *Radix64) prune(b bool) { 158 | if b { 159 | if r.parent == nil { 160 | r.clear() 161 | return 162 | } 163 | // we are a node, we have a parent, so the parent is a non-leaf node 164 | if r.parent.branch[0] == r { 165 | // kill that branch 166 | r.parent.branch[0] = nil 167 | } 168 | if r.parent.branch[1] == r { 169 | r.parent.branch[1] = nil 170 | } 171 | r.parent.prune(false) 172 | return 173 | } 174 | if r == nil { 175 | return 176 | } 177 | if r.bits != 0 { 178 | // fun stops 179 | return 180 | } 181 | // Does I have one or two childeren, if one, move my self up one node 182 | // Also the child must be a leaf node! 183 | b0 := r.branch[0] 184 | b1 := r.branch[1] 185 | if b0 != nil && b1 != nil { 186 | // two branches, we cannot replace ourselves with a child 187 | return 188 | } 189 | if b0 != nil { 190 | if !b0.Leaf() { 191 | return 192 | } 193 | // move b0 into this node 194 | r.set(b0.key, b0.bits, b0.Value) 195 | r.branch[0] = b0.branch[0] 196 | r.branch[1] = b0.branch[1] 197 | } 198 | if b1 != nil { 199 | if !b1.Leaf() { 200 | return 201 | } 202 | // move b1 into this node 203 | r.set(b1.key, b1.bits, b1.Value) 204 | r.branch[0] = b1.branch[0] 205 | r.branch[1] = b1.branch[1] 206 | } 207 | r.parent.prune(false) 208 | } 209 | 210 | func (r *Radix64) find(n uint64, bits, bit int, last *Radix64) *Radix64 { 211 | switch r.Leaf() { 212 | case false: 213 | // A prefix that is matching (BETTER MATCHING) 214 | mask := uint64(mask64 << (bitSize32 - uint(r.bits))) 215 | if r.bits > 0 && r.key&mask == n&mask { 216 | // fmt.Printf("Setting last to %d %s\n", r.key, r.Value) 217 | if last == nil { 218 | last = r 219 | } else { 220 | // Only when bigger 221 | if r.bits >= last.bits { 222 | last = r 223 | } 224 | } 225 | } 226 | if r.bits == bits && r.key&mask == n&mask { 227 | // our key 228 | return r 229 | } 230 | 231 | k := bitK64(n, bit) 232 | if r.branch[k] == nil { 233 | return last // REALLY? 234 | } 235 | return r.branch[k].find(n, bits, bit-1, last) 236 | case true: 237 | // It this our key...!? 238 | mask := uint64(mask64 << (bitSize32 - uint(r.bits))) 239 | if r.key&mask == n&mask { 240 | return r 241 | } 242 | return last 243 | } 244 | panic("bitradix: not reached") 245 | } 246 | 247 | func (r *Radix64) new() *Radix64 { 248 | return &Radix64{[2]*Radix64{nil, nil}, r, 0, 0, nil} 249 | } 250 | 251 | func (r *Radix64) set(key uint64, bits int, value interface{}) { 252 | r.key = key 253 | r.bits = bits 254 | r.Value = value 255 | } 256 | 257 | func (r *Radix64) clear() { 258 | r.key = 0 259 | r.bits = 0 260 | r.Value = nil 261 | } 262 | 263 | func bitK64(n uint64, k int) byte { 264 | return byte((n & (1 << uint(k))) >> uint(k)) 265 | } 266 | -------------------------------------------------------------------------------- /radix_test.go: -------------------------------------------------------------------------------- 1 | package bitradix 2 | 3 | import ( 4 | "net" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | type bittest struct { 10 | key uint32 11 | bit int 12 | } 13 | 14 | var tests = map[uint32]uint32{ 15 | 0x80000000: 2012, 16 | 0x40000000: 2010, 17 | 0x90000000: 2013, 18 | } 19 | 20 | const bits32 = 5 21 | 22 | func newTree32() *Radix32 { 23 | r := New32() 24 | for k, v := range tests { 25 | r.Insert(k, bits32, v) 26 | } 27 | return r 28 | } 29 | 30 | func TestInsert(t *testing.T) { 31 | tests := map[bittest]uint32{ 32 | bittest{0x81000000, 9}: 2012, 33 | bittest{0x80000000, 2}: 2013, 34 | } 35 | r := New32() 36 | for bits, value := range tests { 37 | t.Logf("Inserting %032b/%d\n", bits.key, bits.bit) 38 | if x := r.Insert(bits.key, bits.bit, value); x.Value != value { 39 | t.Logf("Expected %d, got %d for %d (node type %v)\n", value, x.Value, bits.key, x.Leaf()) 40 | t.Fail() 41 | } 42 | t.Logf("Tree\n") 43 | r.Do(func(r1 *Radix32, i int) { t.Logf("(%2d): %032b/%d -> %d\n", i, r1.key, r1.bits, r1.Value) }) 44 | } 45 | } 46 | 47 | func TestInsert2(t *testing.T) { 48 | tests := map[bittest]uint32{ 49 | bittest{0x81000000, 9}: 2012, 50 | bittest{0xA0000000, 4}: 1000, 51 | bittest{0x80000000, 2}: 2013, 52 | } 53 | r := New32() 54 | for bits, value := range tests { 55 | t.Logf("Inserting %032b/%d\n", bits.key, bits.bit) 56 | if x := r.Insert(bits.key, bits.bit, value); x.Value != value { 57 | t.Logf("Expected %d, got %d for %d (node type %v)\n", value, x.Value, bits.key, x.Leaf()) 58 | t.Fail() 59 | } 60 | t.Logf("Tree\n") 61 | r.Do(func(r1 *Radix32, i int) { t.Logf("(%2d): %032b/%d -> %d\n", i, r1.key, r1.bits, r1.Value) }) 62 | } 63 | } 64 | 65 | func TestInsertIdempotent(t *testing.T) { 66 | r := New32() 67 | r.Insert(0x80000000, bits32, 2012) 68 | t.Logf("Tree\n") 69 | r.Do(func(r1 *Radix32, i int) { t.Logf("(%2d): %032b/%d -> %d\n", i, r1.key, r1.bits, r1.Value) }) 70 | r.Insert(0x80000000, bits32, 2013) 71 | t.Logf("Tree\n") 72 | r.Do(func(r1 *Radix32, i int) { t.Logf("(%2d): %032b/%d -> %d\n", i, r1.key, r1.bits, r1.Value) }) 73 | if x := r.Find(0x80000000, bits32); x.Value != 2013 { 74 | t.Logf("Expected %d, got %d for %d\n", 2013, x.Value, 0x08) 75 | t.Fail() 76 | } 77 | } 78 | 79 | func TestFindExact(t *testing.T) { 80 | tests := map[uint32]uint32{ 81 | 0x80000000: 2012, 82 | 0x40000000: 2010, 83 | 0x90000000: 2013, 84 | } 85 | r := New32() 86 | for k, v := range tests { 87 | t.Logf("Tree after insert of %032b (%x %d)\n", k, k, k) 88 | r.Insert(k, bits32, v) 89 | r.Do(func(r1 *Radix32, i int) { t.Logf("%p (%2d): %032b/%d -> %d\n", r1, i, r1.key, r1.bits, r1.Value) }) 90 | } 91 | for k, v := range tests { 92 | x := r.Find(k, bits32) 93 | if x == nil { 94 | t.Logf("Got nil for %032b\n", k) 95 | t.Fail() 96 | continue 97 | } 98 | if x.Value != v { 99 | t.Logf("Expected %d, got %d for %032b (node type %v)\n", v, x.Value, k, x.Leaf()) 100 | t.Fail() 101 | } 102 | } 103 | } 104 | 105 | func TestRemove(t *testing.T) { 106 | r := newTree32() 107 | t.Logf("Tree complete\n") 108 | r.Do(func(r1 *Radix32, i int) { 109 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 110 | }) 111 | k, v := uint32(0x40000000), uint32(2010) 112 | t.Logf("Tree after removal of %032b/%d %d (%x %d)\n", k, bits32, v, k, k) 113 | r.Remove(k, bits32) 114 | r.Do(func(r1 *Radix32, i int) { 115 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 116 | }) 117 | k, v = uint32(0x80000000), uint32(2012) 118 | t.Logf("Tree after removal of %032b/%d %d (%x %d)\n", k, bits32, v, k, k) 119 | r.Remove(k, bits32) 120 | r.Do(func(r1 *Radix32, i int) { 121 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 122 | }) 123 | k, v = uint32(0x90000000), uint32(2013) 124 | t.Logf("Tree after removal of %032b/%d %d (%x %d)\n", k, bits32, v, k, k) 125 | r.Remove(k, bits32) 126 | r.Do(func(r1 *Radix32, i int) { 127 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 128 | }) 129 | } 130 | 131 | // Insert one value and remove it again 132 | func TestRemove2(t *testing.T) { 133 | r := New32() 134 | t.Logf("Tree empty\n") 135 | r.Do(func(r1 *Radix32, i int) { 136 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 137 | }) 138 | k, v := uint32(0x90000000), uint32(2013) 139 | r.Insert(k, bits32, v) 140 | 141 | t.Logf("Tree complete\n") 142 | r.Do(func(r1 *Radix32, i int) { 143 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 144 | }) 145 | t.Logf("Tree after removal of %032b/%d %d (%x %d)\n", k, bits32, v, k, k) 146 | r.Remove(k, bits32) 147 | r.Do(func(r1 *Radix32, i int) { 148 | t.Logf("[%010p %010p] (%2d): %032b/%d -> %d\n", r1.branch[0], r1.branch[1], i, r1.key, r1.bits, r1.Value) 149 | }) 150 | } 151 | 152 | // Test with "real-life" ip addresses 153 | func ipToUint(t *testing.T, n *net.IPNet) (i uint32, mask int) { 154 | ip := n.IP.To4() 155 | fv := reflect.ValueOf(&i).Elem() 156 | fv.SetUint(uint64(uint32(ip[0])<<24 | uint32(ip[1])<<16 | uint32(ip[2])<<8 | uint32(ip[+3]))) 157 | mask, _ = n.Mask.Size() 158 | return 159 | } 160 | 161 | func uintToIP(n uint32) net.IP { 162 | return net.IPv4(byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) 163 | } 164 | 165 | func addRoute(t *testing.T, r *Radix32, s string, asn uint32) { 166 | _, ipnet, _ := net.ParseCIDR(s) 167 | net, mask := ipToUint(t, ipnet) 168 | t.Logf("Route %s (%032b), AS %d\n", s, net, asn) 169 | r.Insert(net, mask, asn) 170 | } 171 | 172 | func findRoute(t *testing.T, r *Radix32, s string) interface{} { 173 | _, ipnet, _ := net.ParseCIDR(s) 174 | net, mask := ipToUint(t, ipnet) 175 | t.Logf("Search %18s %032b/%d\n", s, net, mask) 176 | node := r.Find(net, mask) 177 | if node == nil { 178 | return uint32(0) 179 | } 180 | return node.Value 181 | } 182 | 183 | func TestFindIP(t *testing.T) { 184 | r := New32() 185 | // not a map to have influence on the order 186 | addRoute(t, r, "10.0.0.2/8", 10) 187 | addRoute(t, r, "10.20.0.0/14", 20) 188 | addRoute(t, r, "10.21.0.0/16", 21) 189 | addRoute(t, r, "192.168.0.0/16", 192) 190 | addRoute(t, r, "192.168.2.0/24", 1922) 191 | 192 | addRoute(t, r, "8.0.0.0/9", 3356) 193 | addRoute(t, r, "8.8.8.0/24", 15169) 194 | 195 | r.Do(func(r1 *Radix32, i int) { 196 | t.Logf("(%2d): %032b/%d -> %d\n", i, r1.key, r1.bits, r1.Value) 197 | }) 198 | testips := map[string]uint32{ 199 | "10.20.1.2/32": 20, 200 | "10.22.1.2/32": 20, 201 | "10.19.0.1/32": 10, 202 | "10.21.0.1/32": 21, 203 | "192.168.2.3/32": 1922, 204 | "230.0.0.1/32": 0, 205 | 206 | "8.8.8.8/32": 15169, 207 | "8.8.7.1/32": 3356, 208 | } 209 | 210 | for ip, asn := range testips { 211 | if x := findRoute(t, r, ip); asn != x { 212 | if x == nil && asn == 0 { 213 | continue 214 | } 215 | t.Logf("Expected %d, got %d for %ss\n", asn, x, ip) 216 | t.Fail() 217 | } 218 | } 219 | } 220 | 221 | func TestFindIPShort(t *testing.T) { 222 | r := New32() 223 | // not a map to have influence on the inserting order 224 | // The /14 will overwrite the /10 ... 225 | addRoute(t, r, "10.0.0.2/8", 10) 226 | addRoute(t, r, "10.0.0.0/14", 11) 227 | addRoute(t, r, "10.20.0.0/14", 20) 228 | addRoute(t, r, "210.168.0.0/17", 4694) 229 | addRoute(t, r, "210.168.96.0/19", 2554) 230 | addRoute(t, r, "210.168.192.0/18", 2516) 231 | addRoute(t, r, "210.169.0.0/17", 2516) 232 | addRoute(t, r, "210.168.128.0/18", 4716) 233 | addRoute(t, r, "210.169.128.0/17", 4725) 234 | addRoute(t, r, "210.169.212.0/24", 4725) 235 | addRoute(t, r, "210.16.14.0/24", 4759) 236 | addRoute(t, r, "210.16.0.0/24", 4759) 237 | addRoute(t, r, "210.16.1.0/24", 4759) 238 | addRoute(t, r, "210.16.40.0/24", 4759) 239 | addRoute(t, r, "210.166.0.0/19", 7672) 240 | addRoute(t, r, "210.166.5.0/24", 7668) 241 | addRoute(t, r, "210.167.0.0/19", 7668) 242 | addRoute(t, r, "210.166.0.0/20", 7672) 243 | addRoute(t, r, "210.166.96.0/19", 4693) 244 | addRoute(t, r, "210.167.112.0/20", 4685) 245 | addRoute(t, r, "210.167.128.0/18", 4716) 246 | addRoute(t, r, "210.167.192.0/18", 4716) 247 | addRoute(t, r, "210.167.32.0/19", 7663) 248 | addRoute(t, r, "210.166.209.0/24", 7663) 249 | addRoute(t, r, "210.166.211.0/24", 7663) 250 | 251 | r.Do(func(r1 *Radix32, i int) { t.Logf("(%2d): %032b/%d -> %d\n", i, r1.key, r1.bits, r1.Value) }) 252 | 253 | testips := map[string]uint32{ 254 | "10.20.1.2/32": 20, 255 | "10.19.0.1/32": 0, // because 10.0.0.2/8 isn't there this return 0 256 | "10.0.0.2/32": 11, 257 | "10.1.0.1/32": 11, 258 | "210.169.0.0/17": 2516, 259 | "210.168.96.0/19": 2554, 260 | "210.16.14.0/24": 4759, 261 | "210.16.0.0/24": 4759, 262 | "210.16.1.0/24": 4759, 263 | "210.16.40.0/24": 4759, 264 | "210.166.0.0/19": 7672, 265 | "210.166.0.0/20": 7672, 266 | "210.166.96.0/19": 4693, 267 | "210.167.112.0/20": 4685, 268 | "210.167.128.0/18": 4716, 269 | "210.167.192.0/18": 4716, 270 | "210.167.32.0/19": 7663, 271 | } 272 | 273 | for ip, asn := range testips { 274 | if x := findRoute(t, r, ip); asn != x { 275 | t.Logf("Expected %d, got %d for %s\n", asn, x, ip) 276 | t.Fail() 277 | } 278 | } 279 | } 280 | 281 | func TestFindMySelf(t *testing.T) { 282 | r := New32() 283 | routes := map[string]uint32{ 284 | "210.168.0.0/17": 4694, 285 | "210.168.96.0/19": 2554, 286 | "210.168.192.0/18": 2516, 287 | "210.169.0.0/17": 2516, 288 | "210.168.128.0/18": 4716, 289 | "210.169.128.0/17": 4725, 290 | "210.169.212.0/24": 4725, 291 | "210.16.14.0/24": 4759, 292 | "210.16.0.0/24": 4759, 293 | "210.16.1.0/24": 4759, 294 | "210.16.40.0/24": 4759, 295 | "210.166.0.0/19": 7672, 296 | "210.166.5.0/24": 7668, 297 | "210.167.0.0/19": 7668, 298 | "210.166.0.0/20": 7672, 299 | "210.166.96.0/19": 4693, 300 | "210.167.112.0/20": 4685, 301 | "210.167.128.0/18": 4716, 302 | "210.167.192.0/18": 4716, 303 | "210.167.32.0/19": 7663, 304 | "210.166.209.0/24": 7663, 305 | "210.166.211.0/24": 7663, 306 | "87.71.192.0/18": 1001, 307 | "87.71.128.0/18": 1001, 308 | } 309 | for ip, asn := range routes { 310 | addRoute(t, r, ip, asn) 311 | } 312 | fail := false 313 | for ip, asn := range routes { 314 | if x := findRoute(t, r, ip); asn != x { 315 | t.Logf("Expected %d, got %d for %s\n", asn, x, ip) 316 | fail = true 317 | t.Fail() 318 | } 319 | } 320 | if fail { 321 | r.Do(func(r1 *Radix32, i int) { 322 | t.Logf("(%2d): %032b/%d %s -> %d\n", i, r1.key, r1.bits, uintToIP(r1.key), r1.Value) 323 | }) 324 | } 325 | } 326 | 327 | func TestFindOverwrite(t *testing.T) { 328 | r := New32() 329 | routes := map[string]uint32{ 330 | "1.0.20.0/23": 2518, 331 | "1.0.22.0/23": 2519, 332 | "1.0.24.0/23": 2520, 333 | "1.0.28.0/22": 2517, 334 | "1.0.64.0/18": 18144, 335 | } 336 | for ip, asn := range routes { 337 | addRoute(t, r, ip, asn) 338 | } 339 | r.Do(func(r1 *Radix32, i int) { 340 | t.Logf("(%2d): %032b/%d %s -> %d\n", i, r1.key, r1.bits, uintToIP(r1.key), r1.Value) 341 | }) 342 | 343 | for ip, asn := range routes { 344 | x := findRoute(t, r, ip) 345 | if x == nil { 346 | t.Logf("Expected %d, got nil\n", asn) 347 | t.Fail() 348 | } 349 | if x != asn { 350 | t.Logf("Expected %d, got %d\n", asn, x) 351 | t.Fail() 352 | } 353 | } 354 | } 355 | 356 | func TestBitK32(t *testing.T) { 357 | tests := map[bittest]byte{ 358 | bittest{0x40, 0}: 0, 359 | bittest{0x40, 6}: 1, 360 | } 361 | for test, expected := range tests { 362 | if x := bitK32(test.key, test.bit); x != expected { 363 | t.Logf("Expected %d for %032b (bit #%d), got %d\n", expected, test.key, test.bit, x) 364 | t.Fail() 365 | } 366 | } 367 | } 368 | 369 | func TestQueue(t *testing.T) { 370 | q := make(queue32, 0) 371 | r := New32() 372 | r.Value = 10 373 | 374 | q.Push(&node32{r, -1}) 375 | if r1 := q.Pop(); r1.Value != 10 { 376 | t.Logf("Expected %d, got %d\n", 10, r.Value) 377 | t.Fail() 378 | } 379 | if r1 := q.Pop(); r1 != nil { 380 | t.Logf("Expected nil, got %d\n", r.Value) 381 | t.Fail() 382 | } 383 | } 384 | 385 | func TestQueue2(t *testing.T) { 386 | q := make(queue32, 0) 387 | tests := []uint32{20, 30, 40} 388 | for _, val := range tests { 389 | q.Push(&node32{&Radix32{Value: val}, -1}) 390 | } 391 | for _, val := range tests { 392 | x := q.Pop() 393 | if x == nil { 394 | t.Logf("Expected non-nil, got nil\n") 395 | t.Fail() 396 | continue 397 | } 398 | if x.Radix32.Value != val { 399 | t.Logf("Expected %d, got %d\n", val, x.Radix32.Value) 400 | t.Fail() 401 | } 402 | } 403 | if x := q.Pop(); x != nil { 404 | t.Logf("Expected nil, got %d\n", x.Radix32.Value) 405 | t.Fail() 406 | } 407 | // Push and pop again, see if that works too 408 | for _, val := range tests { 409 | q.Push(&node32{&Radix32{Value: val}, -1}) 410 | } 411 | for _, val := range tests { 412 | x := q.Pop() 413 | if x == nil { 414 | t.Logf("Expected non-nil, got nil after emptying\n") 415 | t.Fail() 416 | continue 417 | } 418 | if x.Radix32.Value != val { 419 | t.Logf("Expected %d, got %d\n", val, x.Radix32.Value) 420 | t.Fail() 421 | } 422 | } 423 | } 424 | 425 | func TestPanic32(t *testing.T) { 426 | r := New32() 427 | var k uint32 428 | for k = 0; k <= 255; k++ { 429 | r.Insert(k, 32, k) 430 | } 431 | } 432 | 433 | func TestPanic64(t *testing.T) { 434 | r := New64() 435 | var k uint64 436 | for k = 0; k <= 255; k++ { 437 | r.Insert(k, 64, k) 438 | } 439 | } 440 | --------------------------------------------------------------------------------