TODO: 完善avl索引
This commit is contained in:
parent
5d99146aec
commit
cd40d47a3c
|
@ -2,28 +2,20 @@ package plist
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/davecgh/go-spew/spew"
|
"github.com/davecgh/go-spew/spew"
|
||||||
|
"github.com/emirpasic/gods/trees/avltree"
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
// PriorityQueue 优先队列 适合数据量不大, 加索引
|
||||||
type PriorityQueue struct {
|
type PriorityQueue struct {
|
||||||
index *Index
|
avlIndex *avltree.Tree
|
||||||
|
|
||||||
indexlimit int
|
indexlimit int
|
||||||
spanlimit int
|
|
||||||
|
|
||||||
node *Node
|
node *Node
|
||||||
size int
|
size int
|
||||||
comparator utils.Comparator
|
comparator utils.Comparator
|
||||||
}
|
}
|
||||||
|
|
||||||
type Index struct {
|
|
||||||
node *Node
|
|
||||||
next *Index
|
|
||||||
|
|
||||||
nlen int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
value interface{}
|
value interface{}
|
||||||
// prev *Node
|
// prev *Node
|
||||||
|
@ -33,13 +25,17 @@ type Node struct {
|
||||||
// NewWithInt compare use int
|
// NewWithInt compare use int
|
||||||
func NewWithInt() *PriorityQueue {
|
func NewWithInt() *PriorityQueue {
|
||||||
p := new(PriorityQueue)
|
p := new(PriorityQueue)
|
||||||
p.indexlimit = 10
|
|
||||||
p.comparator = func(a, b interface{}) int {
|
p.comparator = func(a, b interface{}) int {
|
||||||
if a.(int) > b.(int) {
|
if a.(int) > b.(int) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.indexlimit = 10
|
||||||
|
p.avlIndex = avltree.NewWith(p.comparator)
|
||||||
|
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +131,8 @@ func (pq *PriorityQueue) Push(v interface{}) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; cur.next != nil; i++ {
|
for i := 0; cur.next != nil; i++ {
|
||||||
|
|
||||||
|
// 分裂和整理索引
|
||||||
if i >= pq.indexlimit {
|
if i >= pq.indexlimit {
|
||||||
|
|
||||||
if idx.next != nil && idx.next.nlen < pq.indexlimit {
|
if idx.next != nil && idx.next.nlen < pq.indexlimit {
|
||||||
|
@ -142,7 +140,6 @@ func (pq *PriorityQueue) Push(v interface{}) {
|
||||||
idx.nlen = pq.indexlimit
|
idx.nlen = pq.indexlimit
|
||||||
idx.next.node = cur
|
idx.next.node = cur
|
||||||
idx = idx.next
|
idx = idx.next
|
||||||
i = 0
|
|
||||||
} else {
|
} else {
|
||||||
index := new(Index)
|
index := new(Index)
|
||||||
index.node = cur
|
index.node = cur
|
||||||
|
@ -152,8 +149,9 @@ func (pq *PriorityQueue) Push(v interface{}) {
|
||||||
idx.next = index
|
idx.next = index
|
||||||
idx.nlen = pq.indexlimit
|
idx.nlen = pq.indexlimit
|
||||||
idx = index
|
idx = index
|
||||||
i = 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if pq.comparator(v, cur.next.value) > 0 {
|
if pq.comparator(v, cur.next.value) > 0 {
|
||||||
|
|
|
@ -3,6 +3,8 @@ package plist
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/emirpasic/gods/trees/avltree"
|
||||||
|
|
||||||
"github.com/emirpasic/gods/utils"
|
"github.com/emirpasic/gods/utils"
|
||||||
|
|
||||||
"github.com/Pallinder/go-randomdata"
|
"github.com/Pallinder/go-randomdata"
|
||||||
|
@ -44,7 +46,7 @@ func TestPustPriorityQueue(t *testing.T) {
|
||||||
t.Error(p.String())
|
t.Error(p.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPriorityQueue(b *testing.B) {
|
func BenchmarkPriorityQueuePush(b *testing.B) {
|
||||||
p := NewWithInt()
|
p := NewWithInt()
|
||||||
|
|
||||||
// for i := 0; i < 10000; i++ {
|
// for i := 0; i < 10000; i++ {
|
||||||
|
@ -52,14 +54,61 @@ func BenchmarkPriorityQueue(b *testing.B) {
|
||||||
// // p.Values()
|
// // p.Values()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
b.N = 100000
|
b.N = 10000
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
p.Push(randomdata.Number(0, 100000))
|
p.Push(randomdata.Number(0, 100000))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkPriorityQueueGet(b *testing.B) {
|
||||||
|
p := NewWithInt()
|
||||||
|
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
|
p.Push(randomdata.Number(0, 100000))
|
||||||
|
// p.Values()
|
||||||
|
}
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
b.N = 100000
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
p.Get(randomdata.Number(0, 10000))
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAVL(t *testing.T) {
|
||||||
|
avl := avltree.NewWithIntComparator()
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
v := randomdata.Number(0, 10)
|
||||||
|
avl.Put(v, v)
|
||||||
|
}
|
||||||
|
t.Error(avl.Values())
|
||||||
|
f, ok := avl.Ceiling(100)
|
||||||
|
t.Error(f, ok)
|
||||||
|
t.Error(f.Next().Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAVL(b *testing.B) {
|
||||||
|
avl := avltree.NewWithIntComparator()
|
||||||
|
b.N = 1000000
|
||||||
|
|
||||||
|
b.StartTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
v := randomdata.Number(0, 100000000)
|
||||||
|
avl.Put(v, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
avl.Get(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.StopTimer()
|
||||||
|
}
|
||||||
|
|
||||||
func TestHeap(t *testing.T) {
|
func TestHeap(t *testing.T) {
|
||||||
|
|
||||||
heap := binaryheap.NewWithIntComparator()
|
heap := binaryheap.NewWithIntComparator()
|
||||||
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user