mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-29 00:39:58 +00:00
TUN-528: Move cloudflared into a separate repo
This commit is contained in:
487
vendor/github.com/golang-collections/collections/splay/splay.go
generated
vendored
Normal file
487
vendor/github.com/golang-collections/collections/splay/splay.go
generated
vendored
Normal file
@@ -0,0 +1,487 @@
|
||||
package splay
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type (
|
||||
Any interface{}
|
||||
LessFunc func(interface{}, interface{}) bool
|
||||
VisitFunc func(interface{}) bool
|
||||
|
||||
node struct {
|
||||
value Any
|
||||
parent, left, right *node
|
||||
}
|
||||
nodei struct {
|
||||
step int
|
||||
node *node
|
||||
prev *nodei
|
||||
}
|
||||
|
||||
SplayTree struct {
|
||||
length int
|
||||
root *node
|
||||
less LessFunc
|
||||
}
|
||||
)
|
||||
|
||||
// Create a new splay tree, using the less function to determine the order.
|
||||
func New(less LessFunc) *SplayTree {
|
||||
return &SplayTree{0, nil, less}
|
||||
}
|
||||
|
||||
// Get the first value from the collection. Returns nil if empty.
|
||||
func (this *SplayTree) First() Any {
|
||||
if this.length == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := this.root
|
||||
for n.left != nil {
|
||||
n = n.left
|
||||
}
|
||||
return n.value
|
||||
}
|
||||
|
||||
// Get the last value from the collection. Returns nil if empty.
|
||||
func (this *SplayTree) Last() Any {
|
||||
if this.length == 0 {
|
||||
return nil
|
||||
}
|
||||
n := this.root
|
||||
for n.right != nil {
|
||||
n = n.right
|
||||
}
|
||||
return n.value
|
||||
}
|
||||
|
||||
// Get an item from the splay tree
|
||||
func (this *SplayTree) Get(item Any) Any {
|
||||
if this.length == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := this.root
|
||||
for n != nil {
|
||||
if this.less(item, n.value) {
|
||||
n = n.left
|
||||
continue
|
||||
}
|
||||
|
||||
if this.less(n.value, item) {
|
||||
n = n.right
|
||||
continue
|
||||
}
|
||||
|
||||
this.splay(n)
|
||||
return n.value
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (this *SplayTree) Has(value Any) bool {
|
||||
return this.Get(value) != nil
|
||||
}
|
||||
func (this *SplayTree) Init() {
|
||||
this.length = 0
|
||||
this.root = nil
|
||||
}
|
||||
func (this *SplayTree) Add(value Any) {
|
||||
if this.length == 0 {
|
||||
this.root = &node{value, nil, nil, nil}
|
||||
this.length = 1
|
||||
return
|
||||
}
|
||||
|
||||
n := this.root
|
||||
for {
|
||||
if this.less(value, n.value) {
|
||||
if n.left == nil {
|
||||
n.left = &node{value, n, nil, nil}
|
||||
this.length++
|
||||
n = n.left
|
||||
break
|
||||
}
|
||||
n = n.left
|
||||
continue
|
||||
}
|
||||
|
||||
if this.less(n.value, value) {
|
||||
if n.right == nil {
|
||||
n.right = &node{value, n, nil, nil}
|
||||
this.length++
|
||||
n = n.right
|
||||
break
|
||||
}
|
||||
n = n.right
|
||||
continue
|
||||
}
|
||||
|
||||
n.value = value
|
||||
break
|
||||
}
|
||||
this.splay(n)
|
||||
}
|
||||
func (this *SplayTree) PreOrder(visit VisitFunc) {
|
||||
if this.length == 1 {
|
||||
return
|
||||
}
|
||||
i := &nodei{0, this.root, nil}
|
||||
for i != nil {
|
||||
switch i.step {
|
||||
// Value
|
||||
case 0:
|
||||
i.step++
|
||||
if !visit(i.node.value) {
|
||||
break
|
||||
}
|
||||
// Left
|
||||
case 1:
|
||||
i.step++
|
||||
if i.node.left != nil {
|
||||
i = &nodei{0, i.node.left, i}
|
||||
}
|
||||
// Right
|
||||
case 2:
|
||||
i.step++
|
||||
if i.node.right != nil {
|
||||
i = &nodei{0, i.node.right, i}
|
||||
}
|
||||
default:
|
||||
i = i.prev
|
||||
}
|
||||
}
|
||||
}
|
||||
func (this *SplayTree) InOrder(visit VisitFunc) {
|
||||
if this.length == 1 {
|
||||
return
|
||||
}
|
||||
i := &nodei{0, this.root, nil}
|
||||
for i != nil {
|
||||
switch i.step {
|
||||
// Left
|
||||
case 0:
|
||||
i.step++
|
||||
if i.node.left != nil {
|
||||
i = &nodei{0, i.node.left, i}
|
||||
}
|
||||
// Value
|
||||
case 1:
|
||||
i.step++
|
||||
if !visit(i.node.value) {
|
||||
break
|
||||
}
|
||||
// Right
|
||||
case 2:
|
||||
i.step++
|
||||
if i.node.right != nil {
|
||||
i = &nodei{0, i.node.right, i}
|
||||
}
|
||||
default:
|
||||
i = i.prev
|
||||
}
|
||||
}
|
||||
}
|
||||
func (this *SplayTree) PostOrder(visit VisitFunc) {
|
||||
if this.length == 1 {
|
||||
return
|
||||
}
|
||||
i := &nodei{0, this.root, nil}
|
||||
for i != nil {
|
||||
switch i.step {
|
||||
// Left
|
||||
case 0:
|
||||
i.step++
|
||||
if i.node.left != nil {
|
||||
i = &nodei{0, i.node.left, i}
|
||||
}
|
||||
// Right
|
||||
case 1:
|
||||
i.step++
|
||||
if i.node.right != nil {
|
||||
i = &nodei{0, i.node.right, i}
|
||||
}
|
||||
// Value
|
||||
case 2:
|
||||
i.step++
|
||||
if !visit(i.node.value) {
|
||||
break
|
||||
}
|
||||
default:
|
||||
i = i.prev
|
||||
}
|
||||
}
|
||||
}
|
||||
func (this *SplayTree) Do(visit VisitFunc) {
|
||||
this.InOrder(visit)
|
||||
}
|
||||
func (this *SplayTree) Len() int {
|
||||
return this.length
|
||||
}
|
||||
func (this *SplayTree) Remove(value Any) {
|
||||
if this.length == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
n := this.root
|
||||
for n != nil {
|
||||
if this.less(value, n.value) {
|
||||
n = n.left
|
||||
continue
|
||||
}
|
||||
if this.less(n.value, value) {
|
||||
n = n.right
|
||||
continue
|
||||
}
|
||||
|
||||
// First splay the parent node
|
||||
if n.parent != nil {
|
||||
this.splay(n.parent)
|
||||
}
|
||||
|
||||
// No children
|
||||
if n.left == nil && n.right == nil {
|
||||
// guess we're the root node
|
||||
if n.parent == nil {
|
||||
this.root = nil
|
||||
break
|
||||
}
|
||||
if n.parent.left == n {
|
||||
n.parent.left = nil
|
||||
} else {
|
||||
n.parent.right = nil
|
||||
}
|
||||
} else if n.left == nil {
|
||||
// root node
|
||||
if n.parent == nil {
|
||||
this.root = n.right
|
||||
break
|
||||
}
|
||||
if n.parent.left == n {
|
||||
n.parent.left = n.right
|
||||
} else {
|
||||
n.parent.right = n.right
|
||||
}
|
||||
} else if n.right == nil {
|
||||
// root node
|
||||
if n.parent == nil {
|
||||
this.root = n.left
|
||||
break
|
||||
}
|
||||
if n.parent.left == n {
|
||||
n.parent.left = n.left
|
||||
} else {
|
||||
n.parent.right = n.left
|
||||
}
|
||||
} else {
|
||||
// find the successor
|
||||
s := n.right
|
||||
for s.left != nil {
|
||||
s = s.left
|
||||
}
|
||||
|
||||
np := n.parent
|
||||
nl := n.left
|
||||
nr := n.right
|
||||
|
||||
sp := s.parent
|
||||
sr := s.right
|
||||
|
||||
// Update parent
|
||||
s.parent = np
|
||||
if np == nil {
|
||||
this.root = s
|
||||
} else {
|
||||
if np.left == n {
|
||||
np.left = s
|
||||
} else {
|
||||
np.right = s
|
||||
}
|
||||
}
|
||||
|
||||
// Update left
|
||||
s.left = nl
|
||||
s.left.parent = s
|
||||
|
||||
// Update right
|
||||
if nr != s {
|
||||
s.right = nr
|
||||
s.right.parent = s
|
||||
}
|
||||
|
||||
// Update successor parent
|
||||
if sp.left == s {
|
||||
sp.left = sr
|
||||
} else {
|
||||
sp.right = sr
|
||||
}
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
if n != nil {
|
||||
this.length--
|
||||
}
|
||||
}
|
||||
func (this *SplayTree) String() string {
|
||||
if this.length == 0 {
|
||||
return "{}"
|
||||
}
|
||||
return this.root.String()
|
||||
}
|
||||
|
||||
// Splay a node in the tree (send it to the top)
|
||||
func (this *SplayTree) splay(n *node) {
|
||||
// Already root, nothing to do
|
||||
if n.parent == nil {
|
||||
this.root = n
|
||||
return
|
||||
}
|
||||
|
||||
p := n.parent
|
||||
g := p.parent
|
||||
|
||||
// Zig
|
||||
if p == this.root {
|
||||
if n == p.left {
|
||||
p.rotateRight()
|
||||
} else {
|
||||
p.rotateLeft()
|
||||
}
|
||||
} else {
|
||||
// Zig-zig
|
||||
if n == p.left && p == g.left {
|
||||
g.rotateRight()
|
||||
p.rotateRight()
|
||||
} else if n == p.right && p == g.right {
|
||||
g.rotateLeft()
|
||||
p.rotateLeft()
|
||||
// Zig-zag
|
||||
} else if n == p.right && p == g.left {
|
||||
p.rotateLeft()
|
||||
g.rotateRight()
|
||||
} else if n == p.left && p == g.right {
|
||||
p.rotateRight()
|
||||
g.rotateLeft()
|
||||
}
|
||||
}
|
||||
this.splay(n)
|
||||
}
|
||||
|
||||
// Swap two nodes in the tree
|
||||
func (this *SplayTree) swap(n1, n2 *node) {
|
||||
p1 := n1.parent
|
||||
l1 := n1.left
|
||||
r1 := n1.right
|
||||
|
||||
p2 := n2.parent
|
||||
l2 := n2.left
|
||||
r2 := n2.right
|
||||
|
||||
// Update node links
|
||||
n1.parent = p2
|
||||
n1.left = l2
|
||||
n1.right = r2
|
||||
|
||||
n2.parent = p1
|
||||
n2.left = l1
|
||||
n2.right = r1
|
||||
|
||||
// Update parent links
|
||||
if p1 != nil {
|
||||
if p1.left == n1 {
|
||||
p1.left = n2
|
||||
} else {
|
||||
p1.right = n2
|
||||
}
|
||||
}
|
||||
if p2 != nil {
|
||||
if p2.left == n2 {
|
||||
p2.left = n1
|
||||
} else {
|
||||
p2.right = n1
|
||||
}
|
||||
}
|
||||
|
||||
if n1 == this.root {
|
||||
this.root = n2
|
||||
} else if n2 == this.root {
|
||||
this.root = n1
|
||||
}
|
||||
}
|
||||
|
||||
// Node methods
|
||||
func (this *node) String() string {
|
||||
str := "{" + fmt.Sprint(this.value) + "|"
|
||||
if this.left != nil {
|
||||
str += this.left.String()
|
||||
}
|
||||
str += "|"
|
||||
if this.right != nil {
|
||||
str += this.right.String()
|
||||
}
|
||||
str += "}"
|
||||
return str
|
||||
}
|
||||
func (this *node) rotateLeft() {
|
||||
parent := this.parent
|
||||
pivot := this.right
|
||||
child := pivot.left
|
||||
|
||||
if pivot == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Update the parent
|
||||
if parent != nil {
|
||||
if parent.left == this {
|
||||
parent.left = pivot
|
||||
} else {
|
||||
parent.right = pivot
|
||||
}
|
||||
}
|
||||
|
||||
// Update the pivot
|
||||
pivot.parent = parent
|
||||
pivot.left = this
|
||||
|
||||
// Update the child
|
||||
if child != nil {
|
||||
child.parent = this
|
||||
}
|
||||
|
||||
// Update this
|
||||
this.parent = pivot
|
||||
this.right = child
|
||||
}
|
||||
func (this *node) rotateRight() {
|
||||
parent := this.parent
|
||||
pivot := this.left
|
||||
child := pivot.right
|
||||
|
||||
if pivot == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Update the parent
|
||||
if parent != nil {
|
||||
if parent.left == this {
|
||||
parent.left = pivot
|
||||
} else {
|
||||
parent.right = pivot
|
||||
}
|
||||
}
|
||||
|
||||
// Update the pivot
|
||||
pivot.parent = parent
|
||||
pivot.right = this
|
||||
|
||||
if child != nil {
|
||||
child.parent = this
|
||||
}
|
||||
|
||||
// Update this
|
||||
this.parent = pivot
|
||||
this.left = child
|
||||
}
|
27
vendor/github.com/golang-collections/collections/splay/splay_test.go
generated
vendored
Normal file
27
vendor/github.com/golang-collections/collections/splay/splay_test.go
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package splay
|
||||
|
||||
import (
|
||||
//"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
tree := New(func(a,b interface{})bool {
|
||||
return a.(string) < b.(string)
|
||||
})
|
||||
|
||||
tree.Insert("d", 4)
|
||||
tree.Insert("b", 2)
|
||||
tree.Insert("a", 1)
|
||||
tree.Insert("c", 3)
|
||||
|
||||
if tree.Len() != 4 {
|
||||
t.Errorf("expecting len 4")
|
||||
}
|
||||
|
||||
tree.Remove("b")
|
||||
|
||||
if tree.Len() != 3 {
|
||||
t.Errorf("expecting len 3")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user