Skip to content

Commit

Permalink
Memcached: preallocate slice used for grouping cache keys by server (#…
Browse files Browse the repository at this point in the history
…286)

Signed-off-by: Nick Pillitteri <nick.pillitteri@grafana.com>
  • Loading branch information
56quarters authored Apr 27, 2023
1 parent 1e1de77 commit 12cd006
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 8 deletions.
2 changes: 1 addition & 1 deletion cache/memcached_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ func (c *memcachedClient) sortKeysByServer(keys []string) []string {
bucketed[addrString] = append(bucketed[addrString], key)
}

var out []string
out := make([]string, 0, len(keys))
for srv := range bucketed {
out = append(out, bucketed[srv]...)
}
Expand Down
78 changes: 71 additions & 7 deletions cache/memcached_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package cache

import (
"context"
"errors"
"fmt"
"hash/crc32"
"net"
"testing"
"time"
Expand Down Expand Up @@ -56,6 +57,50 @@ func TestMemcachedClient_GetMulti(t *testing.T) {
})
}

func BenchmarkMemcachedClient_sortKeysByServer(b *testing.B) {
mockSelector := &mockServerSelector{
servers: []mockServer{
{addr: "127.0.0.1"},
{addr: "127.0.0.2"},
{addr: "127.0.0.3"},
{addr: "127.0.0.4"},
{addr: "127.0.0.5"},
{addr: "127.0.0.6"},
{addr: "127.0.0.7"},
{addr: "127.0.0.8"},
},
}

client, err := newMemcachedClient(
log.NewNopLogger(),
newMockMemcachedClientBackend(),
mockSelector,
MemcachedClientConfig{
Addresses: []string{"localhost"},
MaxAsyncConcurrency: 1,
MaxAsyncBufferSize: 10,
},
prometheus.NewPedanticRegistry(),
"test",
)

if err != nil {
b.Fatal("unexpected error creating memcachedClient", err)
}

const numKeys = 10_000

keys := make([]string, numKeys)
for i := 0; i < numKeys; i++ {
keys[i] = fmt.Sprintf("some-key:%d", i)
}

b.ResetTimer()
for i := 0; i < b.N; i++ {
client.sortKeysByServer(keys)
}
}

type mockMemcachedClientBackend struct {
allocations int
values map[string]*memcache.Item
Expand Down Expand Up @@ -99,17 +144,36 @@ func (m *mockMemcachedClientBackend) Delete(key string) error {

func (m *mockMemcachedClientBackend) Close() {}

type mockServerSelector struct{}
type mockServer struct {
addr string
}

func (m mockServerSelector) SetServers(_ ...string) error {
return nil
func (m mockServer) Network() string {
return "tcp"
}

func (m mockServer) String() string {
return m.addr
}

type mockServerSelector struct {
servers []mockServer
}

func (m mockServerSelector) PickServer(key string) (net.Addr, error) {
return nil, errors.New("mock server selector")
func (s *mockServerSelector) PickServer(key string) (net.Addr, error) {
cs := crc32.ChecksumIEEE([]byte(key))
return s.servers[cs%uint32(len(s.servers))], nil
}
func (s *mockServerSelector) Each(f func(net.Addr) error) error {
for _, srv := range s.servers {
if err := f(srv); err != nil {
return err
}
}

func (m mockServerSelector) Each(f func(net.Addr) error) error {
return nil
}
func (s *mockServerSelector) SetServers(_ ...string) error {
return nil
}

Expand Down

0 comments on commit 12cd006

Please sign in to comment.