Skip to content

Commit

Permalink
Optimize code to enhance performance.
Browse files Browse the repository at this point in the history
  • Loading branch information
werbenhu committed Dec 31, 2024
1 parent 330d63d commit 4b8940b
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 82 deletions.
12 changes: 5 additions & 7 deletions ranklist.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"sync"
)

var (
const (
// 跳表的最大层数。对于1000万数据量,根据公式 h = log₂(n)/2,
// 大约需要 log₂(10⁷)/2 ≈ 12 层。请根据实际业务需求和数据量大小适当调整该值,以优化性能和空间利用。
// Maximum number of levels in the skip list. For 10 million elements,
Expand Down Expand Up @@ -49,11 +49,11 @@ type Node[K Ordered, V Ordered] struct {

// 每一层对应的前向指针数组
// Array of forward pointers for each level
forward []*Node[K, V]
forward [MaxLevel]*Node[K, V]

// 每一层对应的跨度数组,记录到下一个节点的距离
// Array of spans for each level, recording distance to next node
span []int
span [MaxLevel]int

// 当前节点的层级
// Current level of the node
Expand Down Expand Up @@ -88,10 +88,8 @@ type RankList[K Ordered, V Ordered] struct {
// NewNode creates a new skip list node
func NewNode[K Ordered, V Ordered](key K, value V, level int) *Node[K, V] {
return &Node[K, V]{
data: Entry[K, V]{Key: key, Value: value},
forward: make([]*Node[K, V], level),
span: make([]int, level),
level: level,
data: Entry[K, V]{Key: key, Value: value},
level: level,
}
}

Expand Down
194 changes: 119 additions & 75 deletions ranklist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,11 @@ func TestNew(t *testing.T) {
}
}

func TestSetHighProbability(t *testing.T) {
Probability = 0.7
func TestSet(t *testing.T) {
sl := New[string, int]()
for k := 0; k < 10000; k++ {
sl.Set(strconv.Itoa(k), k)
}
Probability = 0.25
}

func TestSetLowProbability(t *testing.T) {
Probability = 0.05
sl := New[string, int]()
for k := 0; k < 10000; k++ {
sl.Set(strconv.Itoa(k), k)
}
Probability = 0.25
}

func TestSetAndGet(t *testing.T) {
Expand Down Expand Up @@ -203,7 +192,7 @@ func TestLength(t *testing.T) {
}
}

func TestRankList_Range(t *testing.T) {
func TestRankList_Range_SimpleRange(t *testing.T) {
rankList := New[int, int]()

rankList.Set(1, 100)
Expand All @@ -212,67 +201,122 @@ func TestRankList_Range(t *testing.T) {
rankList.Set(4, 180)
rankList.Set(5, 200)

tests := []struct {
start, end int
expected []Entry[int, int]
}{
{
start: 1,
end: 3,
expected: []Entry[int, int]{
{Key: 1, Value: 100},
{Key: 2, Value: 120},
},
},
// Test case: Range that includes all elements
{
start: 0,
end: 5,
expected: []Entry[int, int]{
{Key: 1, Value: 100},
{Key: 2, Value: 120},
{Key: 3, Value: 150},
{Key: 4, Value: 180},
{Key: 5, Value: 200},
},
},
// Test case: Empty range
{
start: 10,
end: 10,
expected: []Entry[int, int]{},
},
// Test case: Invalid range (start > end)
{
start: 3,
end: 1,
expected: []Entry[int, int]{},
},
// Test case: Range with an out-of-bounds end
{
start: 3,
end: 10,
expected: []Entry[int, int]{
{Key: 3, Value: 150},
{Key: 4, Value: 180},
{Key: 5, Value: 200},
},
},
}

for _, tt := range tests {
t.Run("Range Test", func(t *testing.T) {
result := rankList.Range(tt.start, tt.end)
if len(result) != len(tt.expected) {
t.Errorf("expected %d entries, got %d", len(tt.expected), len(result))
}

for i, entry := range result {
if entry.Key != tt.expected[i].Key || entry.Value != tt.expected[i].Value {
t.Errorf("at index %d: expected (%d, %d), got (%d, %d)",
i, tt.expected[i].Key, tt.expected[i].Value, entry.Key, entry.Value)
}
}
})
start := 1
end := 3
expected := []Entry[int, int]{
{Key: 1, Value: 100},
{Key: 2, Value: 120},
}

result := rankList.Range(start, end)
if len(result) != len(expected) {
t.Errorf("expected %d entries, got %d", len(expected), len(result))
}

for i, entry := range result {
if entry.Key != expected[i].Key || entry.Value != expected[i].Value {
t.Errorf("at index %d: expected (%d, %d), got (%d, %d)",
i, expected[i].Key, expected[i].Value, entry.Key, entry.Value)
}
}
}

func TestRankList_Range_FullRange(t *testing.T) {
rankList := New[int, int]()

rankList.Set(1, 100)
rankList.Set(2, 120)
rankList.Set(3, 150)
rankList.Set(4, 180)
rankList.Set(5, 200)

start := 0
end := 5
expected := []Entry[int, int]{
{Key: 1, Value: 100},
{Key: 2, Value: 120},
{Key: 3, Value: 150},
{Key: 4, Value: 180},
{Key: 5, Value: 200},
}

result := rankList.Range(start, end)
if len(result) != len(expected) {
t.Errorf("expected %d entries, got %d", len(expected), len(result))
}

for i, entry := range result {
if entry.Key != expected[i].Key || entry.Value != expected[i].Value {
t.Errorf("at index %d: expected (%d, %d), got (%d, %d)",
i, expected[i].Key, expected[i].Value, entry.Key, entry.Value)
}
}
}

func TestRankList_Range_EmptyRange(t *testing.T) {
rankList := New[int, int]()

rankList.Set(1, 100)
rankList.Set(2, 120)
rankList.Set(3, 150)
rankList.Set(4, 180)
rankList.Set(5, 200)

start := 10
end := 10
expected := []Entry[int, int]{}

result := rankList.Range(start, end)
if len(result) != len(expected) {
t.Errorf("expected %d entries, got %d", len(expected), len(result))
}
}

func TestRankList_Range_InvalidRange(t *testing.T) {
rankList := New[int, int]()

rankList.Set(1, 100)
rankList.Set(2, 120)
rankList.Set(3, 150)
rankList.Set(4, 180)
rankList.Set(5, 200)

start := 3
end := 1
expected := []Entry[int, int]{}

result := rankList.Range(start, end)
if len(result) != len(expected) {
t.Errorf("expected %d entries, got %d", len(expected), len(result))
}
}

func TestRankList_Range_OutOfBoundsEnd(t *testing.T) {
rankList := New[int, int]()

rankList.Set(1, 100)
rankList.Set(2, 120)
rankList.Set(3, 150)
rankList.Set(4, 180)
rankList.Set(5, 200)

start := 3
end := 10
expected := []Entry[int, int]{
{Key: 3, Value: 150},
{Key: 4, Value: 180},
{Key: 5, Value: 200},
}

result := rankList.Range(start, end)
if len(result) != len(expected) {
t.Errorf("expected %d entries, got %d", len(expected), len(result))
}

for i, entry := range result {
if entry.Key != expected[i].Key || entry.Value != expected[i].Value {
t.Errorf("at index %d: expected (%d, %d), got (%d, %d)",
i, expected[i].Key, expected[i].Value, entry.Key, entry.Value)
}
}
}

0 comments on commit 4b8940b

Please sign in to comment.