diff --git a/avlindex/avlindex.go b/avlindex/avlindex.go index 9759641..0ca3586 100644 --- a/avlindex/avlindex.go +++ b/avlindex/avlindex.go @@ -333,14 +333,15 @@ func (avl *Tree) Put(value interface{}) { fsize := getSize(fixed) if fsize == 3 { lefts, rigths := getChildrenSize(fixed) - avl.fixPutHeight(fixed, lefts, rigths) + avl.fix3PutHeight(fixed, lefts, rigths) } return } if cur.size > 9 { ls, rs := cur.children[0].size, cur.children[1].size - if rs >= ls*2 || ls >= rs*2 { + factor := cur.size / 10 // or factor = 1 + if rs >= ls*2+factor || ls >= rs*2+factor { avl.fixPutHeight(cur, ls, rs) } } @@ -499,6 +500,29 @@ func (avl *Tree) Traversal(every func(v interface{}) bool, traversalMethod ...in } } +func (avl *Tree) lrrotate3(cur *Node) { + const l = 1 + const r = 0 + + movparent := cur.children[l] + mov := movparent.children[r] + + mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 + + cur.children[r] = mov + mov.parent = cur + + cur.children[l] = movparent + movparent.children[r] = nil + + cur.children[r] = mov + mov.parent = cur + + // cur.size = 3 + // cur.children[r].size = 1 + cur.children[l].size = 1 +} + func (avl *Tree) lrrotate(cur *Node) { const l = 1 @@ -547,6 +571,29 @@ func (avl *Tree) lrrotate(cur *Node) { // cur.height = getMaxChildrenHeight(cur) + 1 } +func (avl *Tree) rlrotate3(cur *Node) { + const l = 0 + const r = 1 + + movparent := cur.children[l] + mov := movparent.children[r] + + mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 + + cur.children[r] = mov + mov.parent = cur + + cur.children[l] = movparent + movparent.children[r] = nil + + cur.children[r] = mov + mov.parent = cur + + // cur.size = 3 + // cur.children[r].size = 1 + cur.children[l].size = 1 +} + func (avl *Tree) rlrotate(cur *Node) { const l = 0 @@ -585,6 +632,25 @@ func (avl *Tree) rlrotate(cur *Node) { cur.size = getChildrenSumSize(cur) + 1 } +func (avl *Tree) rrotate3(cur *Node) { + const l = 0 + const r = 1 + // 1 right 0 left + mov := cur.children[l] + + mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 + + cur.children[r] = mov + mov.size = 1 + + cur.children[l] = mov.children[l] + cur.children[l].parent = cur + + mov.children[l] = nil + + mov.size = 1 +} + func (avl *Tree) rrotate(cur *Node) { const l = 0 @@ -628,6 +694,25 @@ func (avl *Tree) rrotate(cur *Node) { // cur.height = getMaxChildrenHeight(cur) + 1 } +func (avl *Tree) lrotate3(cur *Node) { + const l = 1 + const r = 0 + // 1 right 0 left + mov := cur.children[l] + + mov.value, cur.value = cur.value, mov.value //交换值达到, 相对位移 + + cur.children[r] = mov + mov.size = 1 + + cur.children[l] = mov.children[l] + cur.children[l].parent = cur + + mov.children[l] = nil + + mov.size = 1 +} + func (avl *Tree) lrotate(cur *Node) { const l = 1 @@ -698,6 +783,26 @@ func (avl *Tree) fixRemoveHeight(cur *Node) { } } +func (avl *Tree) fix3PutHeight(cur *Node, lefts, rigths int) { + if lefts > rigths { + l := cur.children[0] + llsize, lrsize := getChildrenSize(l) + if lrsize > llsize { + avl.rlrotate3(cur) + } else { + avl.rrotate3(cur) + } + } else { + r := cur.children[1] + rlsize, rrsize := getChildrenSize(r) + if rlsize > rrsize { + avl.lrrotate3(cur) + } else { + avl.lrotate3(cur) + } + } +} + func (avl *Tree) fixPutHeight(cur *Node, lefts, rigths int) { if lefts > rigths { l := cur.children[0] diff --git a/avlindex/avlindex_test.go b/avlindex/avlindex_test.go index 8fa7df6..3235ed3 100644 --- a/avlindex/avlindex_test.go +++ b/avlindex/avlindex_test.go @@ -8,6 +8,8 @@ import ( "os" "testing" + "github.com/huandu/skiplist" + "github.com/Pallinder/go-randomdata" "github.com/davecgh/go-spew/spew" "github.com/emirpasic/gods/trees/avltree" @@ -15,7 +17,7 @@ import ( "github.com/emirpasic/gods/utils" ) -const CompartorSize = 100000 +const CompartorSize = 1000000 const NumberMax = 50000000 func TestSave(t *testing.T) { @@ -69,6 +71,7 @@ func TestIterator(t *testing.T) { // } // t.Error(avl.Values()) // t.Error(avl.debugString()) + } func TestGetRange(t *testing.T) { @@ -305,6 +308,70 @@ ALL: } } +func BenchmarkSkipListGet(b *testing.B) { + sl := skiplist.New(skiplist.Int) + l := loadTestData() + b.N = len(l) + + for _, v := range l { + sl.Set(v, v) + } + + b.ResetTimer() + b.StartTimer() + + execCount := 5 + b.N = len(l) * execCount + + for i := 0; i < execCount; i++ { + for _, v := range l { + e := sl.Get(v) + var result [50]interface{} + for i := 0; i < 50 && e != nil; i++ { + result[i] = e.Value + e = e.Next() + } + } + } +} + +func BenchmarkGetRange(b *testing.B) { + tree := New(utils.IntComparator) + l := loadTestData() + b.N = len(l) + + for _, v := range l { + tree.Put(v) + } + + b.ResetTimer() + b.StartTimer() + + execCount := 5 + b.N = len(l) * execCount + + for i := 0; i < execCount; i++ { + for range l { + tree.GetRange(i, i+49) + } + } +} + +func BenchmarkSkipListSet(b *testing.B) { + sl := skiplist.New(skiplist.Int) + l := loadTestData() + + execCount := 50 + b.N = len(l) * execCount + + for i := 0; i < execCount; i++ { + for _, v := range l { + sl.Set(v, v) + } + } + +} + func BenchmarkIterator(b *testing.B) { tree := New(utils.IntComparator) @@ -458,7 +525,7 @@ func BenchmarkPut(b *testing.B) { b.ResetTimer() b.StartTimer() - execCount := 500 + execCount := 50 b.N = len(l) * execCount for i := 0; i < execCount; i++ { avl := New(utils.IntComparator)