Skip to content

Commit ed9f107

Browse files
authored
perf: saving SendToReplicas results with a bitmap (#55)
Signed-off-by: Rueian <rueiancsie@gmail.com>
1 parent 0b8fa72 commit ed9f107

File tree

3 files changed

+65
-9
lines changed

3 files changed

+65
-9
lines changed

bitmap.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package valkey
2+
3+
type bitmap struct {
4+
bits [3]uint64 // 24 bytes
5+
exts []uint64 // 24 bytes
6+
}
7+
8+
func (b *bitmap) Init(n int) {
9+
if n > 192 {
10+
b.exts = make([]uint64, (n-192+63)/64)
11+
}
12+
}
13+
14+
func (b *bitmap) Set(i int) {
15+
if i < 192 {
16+
b.bits[i/64] |= 1 << (i % 64)
17+
} else {
18+
b.exts[(i-192)/64] |= 1 << (i % 64)
19+
}
20+
}
21+
22+
func (b *bitmap) Get(i int) bool {
23+
if i < 192 {
24+
return b.bits[i/64]&(1<<(i%64)) != 0
25+
}
26+
return b.exts[(i-192)/64]&(1<<(i%64)) != 0
27+
}
28+
29+
func (b *bitmap) Len() int {
30+
return len(b.exts)*64 + 192
31+
}

bitmap_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package valkey
2+
3+
import "testing"
4+
5+
func TestBitmap(t *testing.T) {
6+
var bm bitmap
7+
bm.Init(2953)
8+
if bm.Len() < 2953 {
9+
t.Errorf("bitmap length = %d, expected at least %d", bm.Len(), 2953)
10+
}
11+
for i := 0; i < bm.Len(); i++ {
12+
bm.Set(i)
13+
for j := 0; j < bm.Len(); j++ {
14+
if j <= i {
15+
if !bm.Get(j) {
16+
t.Errorf("bitmap[%d] should be set after iteration %d, but is not", j, i)
17+
}
18+
} else {
19+
if bm.Get(j) {
20+
t.Errorf("bitmap[%d] should not be set after iteration %d, but is", j, i)
21+
}
22+
}
23+
}
24+
}
25+
}

cluster.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -574,24 +574,19 @@ func (c *clusterClient) _pickMulti(multi []Completed) (retries *connretry, init
574574
count := conncountp.Get(len(c.conns), len(c.conns))
575575

576576
if !init && c.rslots != nil && c.opt.SendToReplicas != nil {
577-
var destination []conn
578-
var stackDestination [32]conn
579-
if len(multi) <= len(stackDestination) {
580-
destination = stackDestination[:len(multi)]
581-
} else {
582-
destination = make([]conn, len(multi))
583-
}
577+
var bm bitmap
578+
bm.Init(len(multi))
584579
for i, cmd := range multi {
585580
var cc conn
586581
if c.opt.SendToReplicas(cmd) {
582+
bm.Set(i)
587583
cc = c.rslots[cmd.Slot()]
588584
} else {
589585
cc = c.pslots[cmd.Slot()]
590586
}
591587
if cc == nil {
592588
return nil, false
593589
}
594-
destination[i] = cc
595590
count.m[cc]++
596591
}
597592

@@ -602,7 +597,12 @@ func (c *clusterClient) _pickMulti(multi []Completed) (retries *connretry, init
602597
conncountp.Put(count)
603598

604599
for i, cmd := range multi {
605-
cc := destination[i]
600+
var cc conn
601+
if bm.Get(i) {
602+
cc = c.rslots[cmd.Slot()]
603+
} else {
604+
cc = c.pslots[cmd.Slot()]
605+
}
606606
re := retries.m[cc]
607607
re.commands = append(re.commands, cmd)
608608
re.cIndexes = append(re.cIndexes, i)

0 commit comments

Comments
 (0)