diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..ec78f66 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module sortedset/m + +go 1.15 diff --git a/sortedset.go b/sortedset.go index 9220857..214d317 100644 --- a/sortedset.go +++ b/sortedset.go @@ -41,6 +41,11 @@ type SortedSet struct { dict map[string]*SortedSetNode } +func (this *SortedSet) Print() { + if this.header != nil { + this.header.Print() + } +} func createNode(level int, score SCORE, key string, value interface{}) *SortedSetNode { node := SortedSetNode{ score: score, @@ -96,6 +101,7 @@ func (this *SortedSet) insertNode(score SCORE, key string, value interface{}) *S * if the element is already inside or not. */ level := randomLevel() + //level := this.level + 1 if level > this.level { // add a new level for i := this.level; i < level; i++ { rank[i] = 0 diff --git a/sortedset_test.go b/sortedset_test.go index 233292c..90a713f 100644 --- a/sortedset_test.go +++ b/sortedset_test.go @@ -1,7 +1,10 @@ package sortedset import ( + "fmt" + "math/rand" "testing" + "time" ) func checkOrder(t *testing.T, nodes []*SortedSetNode, expectedOrder []string) { @@ -20,16 +23,23 @@ func TestCase1(t *testing.T) { sortedset := New() sortedset.AddOrUpdate("a", 89, "Kelly") + sortedset.Print() sortedset.AddOrUpdate("b", 100, "Staley") + sortedset.Print() sortedset.AddOrUpdate("c", 100, "Jordon") + sortedset.Print() sortedset.AddOrUpdate("d", -321, "Park") + sortedset.Print() sortedset.AddOrUpdate("e", 101, "Albert") + sortedset.Print() sortedset.AddOrUpdate("f", 99, "Lyman") + sortedset.Print() sortedset.AddOrUpdate("g", 99, "Singleton") + sortedset.Print() sortedset.AddOrUpdate("h", 70, "Audrey") - + sortedset.Print() sortedset.AddOrUpdate("e", 99, "ntrnrt") - + sortedset.Print() sortedset.Remove("b") node := sortedset.GetByRank(3, false) @@ -162,3 +172,36 @@ func TestCase2(t *testing.T) { nodes = sortedset.GetByScoreRange(500, -500, nil) checkOrder(t, nodes, []string{"g", "f", "e", "a", "h"}) } +func TestCase3(t *testing.T) { + sortedset := New() + testSet := make(map[string]int64) + rand.Seed(0) + count := 100000 + for len(testSet) < count { + k := rand.Int63() + ks := fmt.Sprintf("%d", k) + if _, ok := testSet[ks]; !ok { + testSet[ks] = k + } + } + + startts := time.Now() + + for k, v := range testSet { + sortedset.AddOrUpdate(k, SCORE(v), v) + } + + dur := time.Since(startts) + t.Logf("insert cost %v ", dur/time.Duration(count)) + + startts = time.Now() + for { + min := sortedset.PopMin() + if min == nil { + break + } + } + dur = time.Since(startts) + t.Logf("pop cost %v ", dur/time.Duration(count)) + +} diff --git a/sortedsetnode.go b/sortedsetnode.go index b060191..1ddad8c 100644 --- a/sortedsetnode.go +++ b/sortedsetnode.go @@ -24,6 +24,8 @@ package sortedset +import "fmt" + type SortedSetLevel struct { forward *SortedSetNode span int64 @@ -47,3 +49,17 @@ func (this *SortedSetNode) Key() string { func (this *SortedSetNode) Score() SCORE { return this.score } +func (this *SortedSetNode) Print() { + for i, _ := range this.level { + x := this.level[i].forward + if x == nil { + continue + } + fmt.Printf("No %d", i) + for x != nil { + fmt.Printf(" %d:%p:[%d]->", x.score, x, x.level[i].span) + x = x.level[i].forward + } + fmt.Printf("nil\n") + } +}