TUN-528: Move cloudflared into a separate repo

This commit is contained in:
Areg Harutyunyan
2018-05-01 18:45:06 -05:00
parent e8c621a648
commit d06fc520c7
4726 changed files with 1763680 additions and 0 deletions

View File

@@ -0,0 +1,148 @@
package trie
import (
"fmt"
)
type (
Trie struct {
root *node
size int
}
node struct {
key interface{}
value interface{}
next [256]*node
}
iterator struct {
step int
node *node
prev *iterator
}
)
func toBytes(obj interface{}) []byte {
switch o := obj.(type) {
case []byte:
return o
case string:
return []byte(o)
}
return []byte(fmt.Sprint(obj))
}
func New() *Trie {
return &Trie{nil,0}
}
func (this *Trie) Do(handler func(interface{},interface{})bool) {
if this.size > 0 {
this.root.do(handler)
}
}
func (this *Trie) Get(key interface{}) interface{} {
if this.size == 0 {
return nil
}
bs := toBytes(key)
cur := this.root
for i := 0; i < len(bs); i++ {
if cur.next[bs[i]] != nil {
cur = cur.next[bs[i]]
} else {
return nil
}
}
return cur.value
}
func (this *Trie) Has(key interface{}) bool {
return this.Get(key) != nil
}
func (this *Trie) Init() {
this.root = nil
this.size = 0
}
func (this *Trie) Insert(key interface{}, value interface{}) {
if this.size == 0 {
this.root = newNode()
}
bs := toBytes(key)
cur := this.root
for i := 0; i < len(bs); i++ {
if cur.next[bs[i]] != nil {
cur = cur.next[bs[i]]
} else {
cur.next[bs[i]] = newNode()
cur = cur.next[bs[i]]
}
}
if cur.key == nil {
this.size++
}
cur.key = key
cur.value = value
}
func (this *Trie) Len() int {
return this.size
}
func (this *Trie) Remove(key interface{}) interface{} {
if this.size == 0 {
return nil
}
bs := toBytes(key)
cur := this.root
for i := 0; i < len(bs); i++ {
if cur.next[bs[i]] != nil {
cur = cur.next[bs[i]]
} else {
return nil
}
}
// TODO: cleanup dead nodes
val := cur.value
if cur.value != nil {
this.size--
cur.value = nil
cur.key = nil
}
return val
}
func (this *Trie) String() string {
str := "{"
i := 0
this.Do(func(k, v interface{}) bool {
if i > 0 {
str += ", "
}
str += fmt.Sprint(k, ":", v)
i++
return true
})
str += "}"
return str
}
func newNode() *node {
var next [256]*node
return &node{nil,nil,next}
}
func (this *node) do(handler func(interface{}, interface{}) bool) bool {
for i := 0; i < 256; i++ {
if this.next[i] != nil {
if this.next[i].key != nil {
if !handler(this.next[i].key, this.next[i].value) {
return false
}
}
if !this.next[i].do(handler) {
return false
}
}
}
return true
}

View File

@@ -0,0 +1,31 @@
package trie
import (
//"fmt"
"testing"
)
func Test(t *testing.T) {
x := New()
x.Insert(1, 100)
if x.Len() != 1 {
t.Errorf("expected len 1")
}
if x.Get(1).(int) != 100 {
t.Errorf("expected to get 100 for 1")
}
x.Remove(1)
if x.Len() != 0 {
t.Errorf("expected len 0")
}
x.Insert(2, 200)
x.Insert(1, 100)
vs := make([]int, 0)
x.Do(func(k, v interface{}) bool {
vs = append(vs, k.(int))
return true
})
if len(vs) != 2 || vs[0] != 1 || vs[1] != 2 {
t.Errorf("expected in order traversal")
}
}