소스 검색

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:
https://github.com/armon/go-radix/commit/f30034d78803af4786015a5a3a265a40b5837a70

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 a2d758acc9a46d6f8a25a5b72950b75f90fe4f06)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Sebastiaan van Stijn 2 년 전
부모
커밋
cb358e8a19
6개의 변경된 파일142개의 추가작업 그리고 46개의 파일을 삭제
  1. 1 4
      vendor.mod
  2. 3 2
      vendor.sum
  3. 3 0
      vendor/github.com/armon/go-radix/.travis.yml
  4. 2 0
      vendor/github.com/armon/go-radix/README.md
  5. 132 38
      vendor/github.com/armon/go-radix/radix.go
  6. 1 2
      vendor/modules.txt

+ 1 - 4
vendor.mod

@@ -14,7 +14,7 @@ require (
 	github.com/Microsoft/go-winio v0.5.2
 	github.com/Microsoft/go-winio v0.5.2
 	github.com/Microsoft/hcsshim v0.9.5
 	github.com/Microsoft/hcsshim v0.9.5
 	github.com/RackSec/srslog v0.0.0-20180709174129-a4725f04ec91
 	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/aws/aws-sdk-go v1.31.6
 	github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549
 	github.com/bsphere/le_go v0.0.0-20170215134836-7a984a84b549
 	github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
 	github.com/cloudflare/cfssl v0.0.0-20180323000720-5d63dbd981b5
@@ -167,9 +167,6 @@ require (
 )
 )
 
 
 replace (
 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
 	// Resolve dependency hell with github.com/cloudflare/cfssl (transitive via
 	// swarmkit) by pinning the certificate-transparency-go version. Remove once
 	// swarmkit) by pinning the certificate-transparency-go version. Remove once
 	// module go.etcd.io/etcd/server/v3 has upgraded its dependency on
 	// module go.etcd.io/etcd/server/v3 has upgraded its dependency on

+ 3 - 2
vendor.sum

@@ -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.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 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA=
 github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
 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/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.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
 github.com/aws/aws-sdk-go v1.31.6 h1:nKjQbpXhdImctBh1e0iLg9iQW/X297LPPuY/9f92R2k=
 github.com/aws/aws-sdk-go v1.31.6 h1:nKjQbpXhdImctBh1e0iLg9iQW/X297LPPuY/9f92R2k=

+ 3 - 0
vendor/github.com/armon/go-radix/.travis.yml

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

+ 2 - 0
vendor/github.com/armon/go-radix/README.md

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

+ 132 - 38
vendor/github.com/armon/go-radix/radix.go

@@ -40,17 +40,23 @@ func (n *node) isLeaf() bool {
 }
 }
 
 
 func (n *node) addEdge(e edge) {
 func (n *node) addEdge(e edge) {
-	n.edges = append(n.edges, e)
-	n.edges.Sort()
+	num := len(n.edges)
+	idx := sort.Search(num, func(i int) bool {
+		return n.edges[i].label >= e.label
+	})
+
+	n.edges = append(n.edges, edge{})
+	copy(n.edges[idx+1:], n.edges[idx:])
+	n.edges[idx] = e
 }
 }
 
 
-func (n *node) replaceEdge(e edge) {
+func (n *node) updateEdge(label byte, node *node) {
 	num := len(n.edges)
 	num := len(n.edges)
 	idx := sort.Search(num, func(i int) bool {
 	idx := sort.Search(num, func(i int) bool {
-		return n.edges[i].label >= e.label
+		return n.edges[i].label >= label
 	})
 	})
-	if idx < num && n.edges[idx].label == e.label {
-		n.edges[idx].node = e.node
+	if idx < num && n.edges[idx].label == label {
+		n.edges[idx].node = node
 		return
 		return
 	}
 	}
 	panic("replacing missing edge")
 	panic("replacing missing edge")
@@ -67,6 +73,18 @@ func (n *node) getEdge(label byte) *node {
 	return nil
 	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
 type edges []edge
 
 
 func (e edges) Len() int {
 func (e edges) Len() int {
@@ -131,7 +149,7 @@ func longestPrefix(k1, k2 string) int {
 }
 }
 
 
 // Insert is used to add a newentry or update
 // 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) {
 func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
 	var parent *node
 	var parent *node
 	n := t.root
 	n := t.root
@@ -143,14 +161,14 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
 				old := n.leaf.val
 				old := n.leaf.val
 				n.leaf.val = v
 				n.leaf.val = v
 				return old, true
 				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
 		// Look for the edge
@@ -186,10 +204,7 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
 		child := &node{
 		child := &node{
 			prefix: search[:commonPrefix],
 			prefix: search[:commonPrefix],
 		}
 		}
-		parent.replaceEdge(edge{
-			label: search[0],
-			node:  child,
-		})
+		parent.updateEdge(search[0], child)
 
 
 		// Restore the existing node
 		// Restore the existing node
 		child.addEdge(edge{
 		child.addEdge(edge{
@@ -204,7 +219,7 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
 			val: v,
 			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:]
 		search = search[commonPrefix:]
 		if len(search) == 0 {
 		if len(search) == 0 {
 			child.leaf = leaf
 			child.leaf = leaf
@@ -221,12 +236,13 @@ func (t *Tree) Insert(s string, v interface{}) (interface{}, bool) {
 		})
 		})
 		return nil, false
 		return nil, false
 	}
 	}
-	return nil, false
 }
 }
 
 
 // Delete is used to delete a key, returning the previous
 // Delete is used to delete a key, returning the previous
 // value and if it was deleted
 // value and if it was deleted
 func (t *Tree) Delete(s string) (interface{}, bool) {
 func (t *Tree) Delete(s string) (interface{}, bool) {
+	var parent *node
+	var label byte
 	n := t.root
 	n := t.root
 	search := s
 	search := s
 	for {
 	for {
@@ -239,7 +255,9 @@ func (t *Tree) Delete(s string) (interface{}, bool) {
 		}
 		}
 
 
 		// Look for an edge
 		// Look for an edge
-		n = n.getEdge(search[0])
+		parent = n
+		label = search[0]
+		n = n.getEdge(label)
 		if n == nil {
 		if n == nil {
 			break
 			break
 		}
 		}
@@ -259,17 +277,79 @@ DELETE:
 	n.leaf = nil
 	n.leaf = nil
 	t.size--
 	t.size--
 
 
+	// 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
 	// 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
+	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
 	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
 // Get is used to lookup a specific key, returning
 // the value and if it was found
 // the value and if it was found
 func (t *Tree) Get(s string) (interface{}, bool) {
 func (t *Tree) Get(s string) (interface{}, bool) {
@@ -362,9 +442,8 @@ func (t *Tree) Maximum() (string, interface{}, bool) {
 		}
 		}
 		if n.isLeaf() {
 		if n.isLeaf() {
 			return n.leaf.key, n.leaf.val, true
 			return n.leaf.key, n.leaf.val, true
-		} else {
-			break
 		}
 		}
+		break
 	}
 	}
 	return "", nil, false
 	return "", nil, false
 }
 }
@@ -379,7 +458,7 @@ func (t *Tree) WalkPrefix(prefix string, fn WalkFn) {
 	n := t.root
 	n := t.root
 	search := prefix
 	search := prefix
 	for {
 	for {
-		// Check for key exhaution
+		// Check for key exhaustion
 		if len(search) == 0 {
 		if len(search) == 0 {
 			recursiveWalk(n, fn)
 			recursiveWalk(n, fn)
 			return
 			return
@@ -388,22 +467,20 @@ func (t *Tree) WalkPrefix(prefix string, fn WalkFn) {
 		// Look for an edge
 		// Look for an edge
 		n = n.getEdge(search[0])
 		n = n.getEdge(search[0])
 		if n == nil {
 		if n == nil {
-			break
+			return
 		}
 		}
 
 
 		// Consume the search prefix
 		// Consume the search prefix
 		if strings.HasPrefix(search, n.prefix) {
 		if strings.HasPrefix(search, n.prefix) {
 			search = search[len(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
 			// Child may be under our search prefix
 			recursiveWalk(n, fn)
 			recursiveWalk(n, fn)
-			return
-		} else {
-			break
 		}
 		}
+		return
 	}
 	}
-
 }
 }
 
 
 // WalkPath is used to walk the tree, but only visiting nodes
 // 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
 	// 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) {
 		if recursiveWalk(e.node, fn) {
 			return true
 			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
 	return false
 }
 }

+ 1 - 2
vendor/modules.txt

@@ -66,7 +66,7 @@ github.com/armon/circbuf
 # github.com/armon/go-metrics v0.4.1
 # github.com/armon/go-metrics v0.4.1
 ## explicit; go 1.12
 ## explicit; go 1.12
 github.com/armon/go-metrics
 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
 ## explicit
 github.com/armon/go-radix
 github.com/armon/go-radix
 # github.com/aws/aws-sdk-go v1.31.6
 # 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/internal/source
 gotest.tools/v3/poll
 gotest.tools/v3/poll
 gotest.tools/v3/skip
 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/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
 # github.com/rexray/gocsi => github.com/dperny/gocsi v1.2.3-pre