vendor: github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c

Previously we had to use a replace rule, as later versions of this
module resulted in a panic. This issue was fixed in:
f30034d788

Which means we can remove the replace rule, and update the dependency.
No new release was tagged yet, so sticking to a "commit" for now.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a2d758acc9)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2022-11-18 17:15:42 +01:00
parent 2bc33b4c26
commit cb358e8a19
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
6 changed files with 144 additions and 48 deletions

View file

@ -14,7 +14,7 @@ require (
github.com/Microsoft/go-winio v0.5.2
github.com/Microsoft/hcsshim v0.9.5
github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c
github.com/aws/aws-sdk-go v1.31.6
github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549
github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
@ -167,9 +167,6 @@ require (
)
replace (
// More recent versions result in a panic in libnetwork.
// FIXME(thaJeztah): we need to fix how we use this library or replace it; see https://github.com/moby/moby/issues/43753
github.com/armon/go-radix => github.com/armon/go-radix v0.0.0-20150105235045-e39d623f12e8
// Resolve dependency hell with github.com/cloudflare/cfssl (transitive via
// swarmkit) by pinning the certificate-transparency-go version. Remove once
// module go.etcd.io/etcd/server/v3 has upgraded its dependency on

View file

@ -130,8 +130,9 @@ github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
github.com/armon/go-radix v0.0.0-20150105235045-e39d623f12e8 h1:XGHqlQXxwVly7mpcroyCGuEaGv/yvtS6r4PSHryDgxU=
github.com/armon/go-radix v0.0.0-20150105235045-e39d623f12e8/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c h1:651/eoCRnQ7YtSjAnSzRucrJz+3iGEFt+ysraELS81M=
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/aws/aws-sdk-go v1.31.6 h1:nKjQbpXhdImctBh1e0iLg9iQW/X297LPPuY/9f92R2k=

View file

@ -1,3 +1,6 @@
language: go
arch:
- amd64
- ppc64le
go:
- tip

View file

@ -10,6 +10,8 @@ As a radix tree, it provides the following:
* Minimum / Maximum value lookups
* Ordered iteration
For an immutable variant, see [go-immutable-radix](https://github.com/hashicorp/go-immutable-radix).
Documentation
=============

View file

@ -40,17 +40,23 @@ func (n *node) isLeaf() bool {
}
func (n *node) addEdge(e edge) {
n.edges = append(n.edges, e)
n.edges.Sort()
}
func (n *node) replaceEdge(e edge) {
num := len(n.edges)
idx := sort.Search(num, func(i int) bool {
return n.edges[i].label >= e.label
})
if idx < num && n.edges[idx].label == e.label {
n.edges[idx].node = e.node
n.edges = append(n.edges, edge{})
copy(n.edges[idx+1:], n.edges[idx:])
n.edges[idx] = e
}
func (n *node) updateEdge(label byte, node *node) {
num := len(n.edges)
idx := sort.Search(num, func(i int) bool {
return n.edges[i].label >= label
})
if idx < num && n.edges[idx].label == label {
n.edges[idx].node = node
return
}
panic("replacing missing edge")
@ -67,6 +73,18 @@ func (n *node) getEdge(label byte) *node {
return nil
}
func (n *node) delEdge(label byte) {
num := len(n.edges)
idx := sort.Search(num, func(i int) bool {
return n.edges[i].label >= label
})
if idx < num && n.edges[idx].label == label {
copy(n.edges[idx:], n.edges[idx+1:])
n.edges[len(n.edges)-1] = edge{}
n.edges = n.edges[:len(n.edges)-1]
}
}
type edges []edge
func (e edges) Len() int {
@ -131,7 +149,7 @@ func longestPrefix(k1, k2 string) int {
}
// Insert is used to add a newentry or update
// an existing entry. Returns if updated.
// an existing entry. Returns true if an existing record is updated.
func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
var parent *node
n := t.root
@ -143,14 +161,14 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
old := n.leaf.val
n.leaf.val = v
return old, true
} else {
n.leaf = &leafNode{
key: s,
val: v,
}
t.size++
return nil, false
}
n.leaf = &leafNode{
key: s,
val: v,
}
t.size++
return nil, false
}
// Look for the edge
@ -186,10 +204,7 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
child := &node{
prefix: search[:commonPrefix],
}
parent.replaceEdge(edge{
label: search[0],
node: child,
})
parent.updateEdge(search[0], child)
// Restore the existing node
child.addEdge(edge{
@ -204,7 +219,7 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
val: v,
}
// If the new key is a subset, add to to this node
// If the new key is a subset, add to this node
search = search[commonPrefix:]
if len(search) == 0 {
child.leaf = leaf
@ -221,12 +236,13 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
})
return nil, false
}
return nil, false
}
// Delete is used to delete a key, returning the previous
// value and if it was deleted
func (t *Tree) Delete(s string) (interface{}, bool) {
var parent *node
var label byte
n := t.root
search := s
for {
@ -239,7 +255,9 @@ func (t *Tree) Delete(s string) (interface{}, bool) {
}
// Look for an edge
n = n.getEdge(search[0])
parent = n
label = search[0]
n = n.getEdge(label)
if n == nil {
break
}
@ -259,17 +277,79 @@ DELETE:
n.leaf = nil
t.size--
// Check if we should merge this node
if len(n.edges) == 1 {
e := n.edges[0]
child := e.node
n.prefix = n.prefix + child.prefix
n.leaf = child.leaf
n.edges = child.edges
// Check if we should delete this node from the parent
if parent != nil && len(n.edges) == 0 {
parent.delEdge(label)
}
// Check if we should merge this node
if n != t.root && len(n.edges) == 1 {
n.mergeChild()
}
// Check if we should merge the parent's other child
if parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {
parent.mergeChild()
}
return leaf.val, true
}
// DeletePrefix is used to delete the subtree under a prefix
// Returns how many nodes were deleted
// Use this to delete large subtrees efficiently
func (t *Tree) DeletePrefix(s string) int {
return t.deletePrefix(nil, t.root, s)
}
// delete does a recursive deletion
func (t *Tree) deletePrefix(parent, n *node, prefix string) int {
// Check for key exhaustion
if len(prefix) == 0 {
// Remove the leaf node
subTreeSize := 0
//recursively walk from all edges of the node to be deleted
recursiveWalk(n, func(s string, v interface{}) bool {
subTreeSize++
return false
})
if n.isLeaf() {
n.leaf = nil
}
n.edges = nil // deletes the entire subtree
// Check if we should merge the parent's other child
if parent != nil && parent != t.root && len(parent.edges) == 1 && !parent.isLeaf() {
parent.mergeChild()
}
t.size -= subTreeSize
return subTreeSize
}
// Look for an edge
label := prefix[0]
child := n.getEdge(label)
if child == nil || (!strings.HasPrefix(child.prefix, prefix) && !strings.HasPrefix(prefix, child.prefix)) {
return 0
}
// Consume the search prefix
if len(child.prefix) > len(prefix) {
prefix = prefix[len(prefix):]
} else {
prefix = prefix[len(child.prefix):]
}
return t.deletePrefix(n, child, prefix)
}
func (n *node) mergeChild() {
e := n.edges[0]
child := e.node
n.prefix = n.prefix + child.prefix
n.leaf = child.leaf
n.edges = child.edges
}
// Get is used to lookup a specific key, returning
// the value and if it was found
func (t *Tree) Get(s string) (interface{}, bool) {
@ -362,9 +442,8 @@ func (t *Tree) Maximum() (string, interface{}, bool) {
}
if n.isLeaf() {
return n.leaf.key, n.leaf.val, true
} else {
break
}
break
}
return "", nil, false
}
@ -379,7 +458,7 @@ func (t *Tree) WalkPrefix(prefix string, fn WalkFn) {
n := t.root
search := prefix
for {
// Check for key exhaution
// Check for key exhaustion
if len(search) == 0 {
recursiveWalk(n, fn)
return
@ -388,22 +467,20 @@ func (t *Tree) WalkPrefix(prefix string, fn WalkFn) {
// Look for an edge
n = n.getEdge(search[0])
if n == nil {
break
return
}
// Consume the search prefix
if strings.HasPrefix(search, n.prefix) {
search = search[len(n.prefix):]
} else if strings.HasPrefix(n.prefix, search) {
continue
}
if strings.HasPrefix(n.prefix, search) {
// Child may be under our search prefix
recursiveWalk(n, fn)
return
} else {
break
}
return
}
}
// WalkPath is used to walk the tree, but only visiting nodes
@ -448,10 +525,27 @@ func recursiveWalk(n *node, fn WalkFn) bool {
}
// Recurse on the children
for _, e := range n.edges {
i := 0
k := len(n.edges) // keeps track of number of edges in previous iteration
for i < k {
e := n.edges[i]
if recursiveWalk(e.node, fn) {
return true
}
// It is a possibility that the WalkFn modified the node we are
// iterating on. If there are no more edges, mergeChild happened,
// so the last edge became the current node n, on which we'll
// iterate one last time.
if len(n.edges) == 0 {
return recursiveWalk(n, fn)
}
// If there are now less edges than in the previous iteration,
// then do not increment the loop index, since the current index
// points to a new edge. Otherwise, get to the next index.
if len(n.edges) >= k {
i++
}
k = len(n.edges)
}
return false
}

3
vendor/modules.txt vendored
View file

@ -66,7 +66,7 @@ github.com/armon/circbuf
# github.com/armon/go-metrics v0.4.1
## explicit; go 1.12
github.com/armon/go-metrics
# github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 => github.com/armon/go-radix v0.0.0-20150105235045-e39d623f12e8
# github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c
## explicit
github.com/armon/go-radix
# github.com/aws/aws-sdk-go v1.31.6
@ -1130,6 +1130,5 @@ gotest.tools/v3/internal/format
gotest.tools/v3/internal/source
gotest.tools/v3/poll
gotest.tools/v3/skip
# github.com/armon/go-radix => github.com/armon/go-radix v0.0.0-20150105235045-e39d623f12e8
# github.com/google/certificate-transparency-go => github.com/google/certificate-transparency-go v1.0.20
# github.com/rexray/gocsi => github.com/dperny/gocsi v1.2.3-pre