Improve the iterate seek to O(logN) (#25)

* improve the iterate seek to O(logN)

* add benchmark
diff --git a/btree.go b/btree.go
index 7e4551d..6ff062f 100644
--- a/btree.go
+++ b/btree.go
@@ -500,13 +500,14 @@
 // thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a
 // "greaterThan" or "lessThan" queries.
 func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit bool, iter ItemIterator) (bool, bool) {
-	var ok bool
+	var ok, found bool
+	var index int
 	switch dir {
 	case ascend:
-		for i := 0; i < len(n.items); i++ {
-			if start != nil && n.items[i].Less(start) {
-				continue
-			}
+		if start != nil {
+			index, _ = n.items.find(start)
+		}
+		for i := index; i < len(n.items); i++ {
 			if len(n.children) > 0 {
 				if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {
 					return hit, false
@@ -530,7 +531,15 @@
 			}
 		}
 	case descend:
-		for i := len(n.items) - 1; i >= 0; i-- {
+		if start != nil {
+			index, found = n.items.find(start)
+			if !found {
+				index = index - 1
+			}
+		} else {
+			index = len(n.items) - 1
+		}
+		for i := index; i >= 0; i-- {
 			if start != nil && !n.items[i].Less(start) {
 				if !includeStart || hit || start.Less(n.items[i]) {
 					continue
diff --git a/btree_test.go b/btree_test.go
index 9eeb136..78a90cd 100644
--- a/btree_test.go
+++ b/btree_test.go
@@ -361,6 +361,21 @@
 	}
 }
 
+func BenchmarkSeek(b *testing.B) {
+	b.StopTimer()
+	size := 100000
+	insertP := perm(size)
+	tr := New(*btreeDegree)
+	for _, item := range insertP {
+		tr.ReplaceOrInsert(item)
+	}
+	b.StartTimer()
+
+	for i := 0; i < b.N; i++ {
+		tr.AscendGreaterOrEqual(Int(i%size), func(i Item) bool { return false })
+	}
+}
+
 func BenchmarkDeleteInsert(b *testing.B) {
 	b.StopTimer()
 	insertP := perm(benchmarkTreeSize)