Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
wangjia184 committed May 19, 2016
1 parent 9549ad3 commit f38b08d
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 46 deletions.
58 changes: 12 additions & 46 deletions sortedset.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,8 @@ import (

type SCORE float64 // the type of score

const ZSKIPLIST_MAXLEVEL = 32 /* Should be enough for 2^32 elements */
const ZSKIPLIST_P = 0.25 /* Skiplist P = 1/4 */

type SortedSetLevel struct {
forward *SortedSetNode
span int64
}

// Node in skip list
type SortedSetNode struct {
key string // unique key of this node
Value interface{} // value associated with this node
score SCORE // score to determine the order of this node
backward *SortedSetNode
level []SortedSetLevel
}

func (this *SortedSetNode) Key() string {
return this.key
}
func (this *SortedSetNode) Score() SCORE {
return this.score
}
const SKIPLIST_MAXLEVEL = 32 /* Should be enough for 2^32 elements */
const SKIPLIST_P = 0.25 /* Skiplist P = 1/4 */

type SortedSet struct {
header *SortedSetNode
Expand All @@ -62,19 +41,6 @@ type SortedSet struct {
dict map[string]*SortedSetNode
}

type ScoreRange struct {
min SCORE
max SCORE
excludeMin bool
excludeMax bool
}

type Item struct {
key string
value interface{}
score SCORE
}

func createNode(level int, score SCORE, key string, value interface{}) *SortedSetNode {
node := SortedSetNode{
score: score,
Expand All @@ -86,24 +52,24 @@ func createNode(level int, score SCORE, key string, value interface{}) *SortedSe
}

// Returns a random level for the new skiplist node we are going to create.
// The return value of this function is between 1 and ZSKIPLIST_MAXLEVEL
// The return value of this function is between 1 and SKIPLIST_MAXLEVEL
// (both inclusive), with a powerlaw-alike distribution where higher
// levels are less likely to be returned.
func randomLevel() int {
level := 1
for SCORE(rand.Int31()&0xFFFF) < (ZSKIPLIST_P * SCORE(0xFFFF)) {
for SCORE(rand.Int31()&0xFFFF) < (SKIPLIST_P * SCORE(0xFFFF)) {
level += 1
}
if level < ZSKIPLIST_MAXLEVEL {
if level < SKIPLIST_MAXLEVEL {
return level
}

return ZSKIPLIST_MAXLEVEL
return SKIPLIST_MAXLEVEL
}

func (this *SortedSet) insertNode(score SCORE, key string, value interface{}) *SortedSetNode {
var update [ZSKIPLIST_MAXLEVEL]*SortedSetNode
var rank [ZSKIPLIST_MAXLEVEL]int64
var update [SKIPLIST_MAXLEVEL]*SortedSetNode
var rank [SKIPLIST_MAXLEVEL]int64

x := this.header
for i := this.level - 1; i >= 0; i-- {
Expand Down Expand Up @@ -169,7 +135,7 @@ func (this *SortedSet) insertNode(score SCORE, key string, value interface{}) *S
}

/* Internal function used by delete, DeleteByScore and DeleteByRank */
func (this *SortedSet) deleteNode(x *SortedSetNode, update [ZSKIPLIST_MAXLEVEL]*SortedSetNode) {
func (this *SortedSet) deleteNode(x *SortedSetNode, update [SKIPLIST_MAXLEVEL]*SortedSetNode) {
for i := 0; i < this.level; i++ {
if update[i].level[i].forward == x {
update[i].level[i].span += x.level[i].span - 1
Expand All @@ -192,7 +158,7 @@ func (this *SortedSet) deleteNode(x *SortedSetNode, update [ZSKIPLIST_MAXLEVEL]*

/* Delete an element with matching score/key from the skiplist. */
func (this *SortedSet) delete(score SCORE, key string) bool {
var update [ZSKIPLIST_MAXLEVEL]*SortedSetNode
var update [SKIPLIST_MAXLEVEL]*SortedSetNode

x := this.header
for i := this.level - 1; i >= 0; i-- {
Expand Down Expand Up @@ -221,7 +187,7 @@ func New() *SortedSet {
level: 1,
dict: make(map[string]*SortedSetNode),
}
sortedSet.header = createNode(ZSKIPLIST_MAXLEVEL, 0, "", nil)
sortedSet.header = createNode(SKIPLIST_MAXLEVEL, 0, "", nil)
return &sortedSet
}

Expand Down Expand Up @@ -445,7 +411,7 @@ func (this *SortedSet) GetByRankRange(start int, end int, remove bool) []*Sorted
start, end = end, start
}

var update [ZSKIPLIST_MAXLEVEL]*SortedSetNode
var update [SKIPLIST_MAXLEVEL]*SortedSetNode
var nodes []*SortedSetNode
var traversed int = 0

Expand Down
5 changes: 5 additions & 0 deletions sortedset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,11 @@ func TestCase1(t *testing.T) {
}

func TestCase2(t *testing.T) {

// create a new set
sortedset := New()

// fill in new node
sortedset.AddOrUpdate("a", 89, "Kelly")
sortedset.AddOrUpdate("b", 100, "Staley")
sortedset.AddOrUpdate("c", 100, "Jordon")
Expand All @@ -74,8 +77,10 @@ func TestCase2(t *testing.T) {
sortedset.AddOrUpdate("g", 99, "Singleton")
sortedset.AddOrUpdate("h", 70, "Audrey")

// update an existing node
sortedset.AddOrUpdate("e", 99, "ntrnrt")

// remove node
sortedset.Remove("b")

nodes := sortedset.GetByScoreRange(-500, 500, nil)
Expand Down
46 changes: 46 additions & 0 deletions sortedsetnode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2016, Jerry.Wang
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package sortedset

type SortedSetLevel struct {
forward *SortedSetNode
span int64
}

// Node in skip list
type SortedSetNode struct {
key string // unique key of this node
Value interface{} // associated data
score SCORE // score to determine the order of this node in the set
backward *SortedSetNode
level []SortedSetLevel
}

func (this *SortedSetNode) Key() string {
return this.key
}
func (this *SortedSetNode) Score() SCORE {
return this.score
}

0 comments on commit f38b08d

Please sign in to comment.