Browse Source

Merge pull request #5597 from gyuho/btree_dep

*: update google/btree dependency
Gyu-Ho Lee 9 years ago
parent
commit
35329a1674

+ 1 - 1
cmd/Godeps/Godeps.json

@@ -88,7 +88,7 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/google/btree",
 			"ImportPath": "github.com/google/btree",
-			"Rev": "cc6329d4279e3f025a53a83c397d2339b5705c45"
+			"Rev": "7d79101e329e5a3adf994758c578dab82b90c017"
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/inconshreveable/mousetrap",
 			"ImportPath": "github.com/inconshreveable/mousetrap",

+ 1 - 1
cmd/vendor/github.com/google/btree/README.md

@@ -2,7 +2,7 @@
 
 
 ![Travis CI Build Status](https://api.travis-ci.org/google/btree.svg?branch=master)
 ![Travis CI Build Status](https://api.travis-ci.org/google/btree.svg?branch=master)
 
 
-This package provides an in-memory B-Tree implementation for Go, useful as a
+This package provides an in-memory B-Tree implementation for Go, useful as
 an ordered, mutable data structure.
 an ordered, mutable data structure.
 
 
 The API is based off of the wonderful
 The API is based off of the wonderful

+ 97 - 19
cmd/vendor/github.com/google/btree/btree.go

@@ -64,6 +64,39 @@ type Item interface {
 	Less(than Item) bool
 	Less(than Item) bool
 }
 }
 
 
+const (
+	DefaultFreeListSize = 32
+)
+
+// FreeList represents a free list of btree nodes. By default each
+// BTree has its own FreeList, but multiple BTrees can share the same
+// FreeList.
+// Two Btrees using the same freelist are not safe for concurrent write access.
+type FreeList struct {
+	freelist []*node
+}
+
+// NewFreeList creates a new free list.
+// size is the maximum size of the returned free list.
+func NewFreeList(size int) *FreeList {
+	return &FreeList{freelist: make([]*node, 0, size)}
+}
+
+func (f *FreeList) newNode() (n *node) {
+	index := len(f.freelist) - 1
+	if index < 0 {
+		return new(node)
+	}
+	f.freelist, n = f.freelist[:index], f.freelist[index]
+	return
+}
+
+func (f *FreeList) freeNode(n *node) {
+	if len(f.freelist) < cap(f.freelist) {
+		f.freelist = append(f.freelist, n)
+	}
+}
+
 // ItemIterator allows callers of Ascend* to iterate in-order over portions of
 // ItemIterator allows callers of Ascend* to iterate in-order over portions of
 // the tree.  When this function returns false, iteration will stop and the
 // the tree.  When this function returns false, iteration will stop and the
 // associated Ascend* function will immediately return.
 // associated Ascend* function will immediately return.
@@ -74,12 +107,17 @@ type ItemIterator func(i Item) bool
 // New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
 // New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
 // and 2-4 children).
 // and 2-4 children).
 func New(degree int) *BTree {
 func New(degree int) *BTree {
+	return NewWithFreeList(degree, NewFreeList(DefaultFreeListSize))
+}
+
+// NewWithFreeList creates a new B-Tree that uses the given node free list.
+func NewWithFreeList(degree int, f *FreeList) *BTree {
 	if degree <= 1 {
 	if degree <= 1 {
 		panic("bad degree")
 		panic("bad degree")
 	}
 	}
 	return &BTree{
 	return &BTree{
 		degree:   degree,
 		degree:   degree,
-		freelist: make([]*node, 0, 32),
+		freelist: f,
 	}
 	}
 }
 }
 
 
@@ -100,6 +138,7 @@ func (s *items) insertAt(index int, item Item) {
 // back.
 // back.
 func (s *items) removeAt(index int) Item {
 func (s *items) removeAt(index int) Item {
 	item := (*s)[index]
 	item := (*s)[index]
+	(*s)[index] = nil
 	copy((*s)[index:], (*s)[index+1:])
 	copy((*s)[index:], (*s)[index+1:])
 	*s = (*s)[:len(*s)-1]
 	*s = (*s)[:len(*s)-1]
 	return item
 	return item
@@ -108,7 +147,9 @@ func (s *items) removeAt(index int) Item {
 // pop removes and returns the last element in the list.
 // pop removes and returns the last element in the list.
 func (s *items) pop() (out Item) {
 func (s *items) pop() (out Item) {
 	index := len(*s) - 1
 	index := len(*s) - 1
-	out, *s = (*s)[index], (*s)[:index]
+	out = (*s)[index]
+	(*s)[index] = nil
+	*s = (*s)[:index]
 	return
 	return
 }
 }
 
 
@@ -142,6 +183,7 @@ func (s *children) insertAt(index int, n *node) {
 // back.
 // back.
 func (s *children) removeAt(index int) *node {
 func (s *children) removeAt(index int) *node {
 	n := (*s)[index]
 	n := (*s)[index]
+	(*s)[index] = nil
 	copy((*s)[index:], (*s)[index+1:])
 	copy((*s)[index:], (*s)[index+1:])
 	*s = (*s)[:len(*s)-1]
 	*s = (*s)[:len(*s)-1]
 	return n
 	return n
@@ -150,7 +192,9 @@ func (s *children) removeAt(index int) *node {
 // pop removes and returns the last element in the list.
 // pop removes and returns the last element in the list.
 func (s *children) pop() (out *node) {
 func (s *children) pop() (out *node) {
 	index := len(*s) - 1
 	index := len(*s) - 1
-	out, *s = (*s)[index], (*s)[:index]
+	out = (*s)[index]
+	(*s)[index] = nil
+	*s = (*s)[:index]
 	return
 	return
 }
 }
 
 
@@ -234,6 +278,34 @@ func (n *node) get(key Item) Item {
 	return nil
 	return nil
 }
 }
 
 
+// min returns the first item in the subtree.
+func min(n *node) Item {
+	if n == nil {
+		return nil
+	}
+	for len(n.children) > 0 {
+		n = n.children[0]
+	}
+	if len(n.items) == 0 {
+		return nil
+	}
+	return n.items[0]
+}
+
+// max returns the last item in the subtree.
+func max(n *node) Item {
+	if n == nil {
+		return nil
+	}
+	for len(n.children) > 0 {
+		n = n.children[len(n.children)-1]
+	}
+	if len(n.items) == 0 {
+		return nil
+	}
+	return n.items[len(n.items)-1]
+}
+
 // toRemove details what item to remove in a node.remove call.
 // toRemove details what item to remove in a node.remove call.
 type toRemove int
 type toRemove int
 
 
@@ -396,7 +468,7 @@ type BTree struct {
 	degree   int
 	degree   int
 	length   int
 	length   int
 	root     *node
 	root     *node
-	freelist []*node
+	freelist *FreeList
 }
 }
 
 
 // maxItems returns the max number of items to allow per node.
 // maxItems returns the max number of items to allow per node.
@@ -411,26 +483,22 @@ func (t *BTree) minItems() int {
 }
 }
 
 
 func (t *BTree) newNode() (n *node) {
 func (t *BTree) newNode() (n *node) {
-	index := len(t.freelist) - 1
-	if index < 0 {
-		return &node{t: t}
-	}
-	t.freelist, n = t.freelist[:index], t.freelist[index]
+	n = t.freelist.newNode()
+	n.t = t
 	return
 	return
 }
 }
 
 
 func (t *BTree) freeNode(n *node) {
 func (t *BTree) freeNode(n *node) {
-	if len(t.freelist) < cap(t.freelist) {
-    for i := range n.items {
-      n.items[i] = nil  // clear to allow GC
-    }
-		n.items = n.items[:0]
-    for i := range n.children {
-      n.children[i] = nil  // clear to allow GC
-    }
-		n.children = n.children[:0]
-		t.freelist = append(t.freelist, n)
+	for i := range n.items {
+		n.items[i] = nil // clear to allow GC
 	}
 	}
+	n.items = n.items[:0]
+	for i := range n.children {
+		n.children[i] = nil // clear to allow GC
+	}
+	n.children = n.children[:0]
+	n.t = nil // clear to allow GC
+	t.freelist.freeNode(n)
 }
 }
 
 
 // ReplaceOrInsert adds the given item to the tree.  If an item in the tree
 // ReplaceOrInsert adds the given item to the tree.  If an item in the tree
@@ -552,6 +620,16 @@ func (t *BTree) Get(key Item) Item {
 	return t.root.get(key)
 	return t.root.get(key)
 }
 }
 
 
+// Min returns the smallest item in the tree, or nil if the tree is empty.
+func (t *BTree) Min() Item {
+	return min(t.root)
+}
+
+// Max returns the largest item in the tree, or nil if the tree is empty.
+func (t *BTree) Max() Item {
+	return max(t.root)
+}
+
 // Has returns true if the given key is in the tree.
 // Has returns true if the given key is in the tree.
 func (t *BTree) Has(key Item) bool {
 func (t *BTree) Has(key Item) bool {
 	return t.Get(key) != nil
 	return t.Get(key) != nil