-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathshardedbackend.go
51 lines (42 loc) · 1.68 KB
/
shardedbackend.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package krakendrate
import (
"context"
"time"
)
// Hasher gets a hash for the received string
type Hasher func(string) uint64
// BackendBuilder is the type for a function that can build a Backend.
// Is is used by the ShardedMemoryBackend to create several backends / shards.
type BackendBuilder func(ctx context.Context, ttl time.Duration, cleanUpRate time.Duration, cleanUpThreads uint64, amount uint64) []Backend
// ShardedMemoryBackend is a memory backend shardering the data in order to avoid mutex contention
type ShardedMemoryBackend struct {
shards []Backend
total uint64
hasher Hasher
}
// NewShardedMemoryBackend returns a ShardedMemoryBackend with 'shards' shards
func NewShardedMemoryBackend(ctx context.Context, shards uint64, ttl time.Duration, h Hasher) *ShardedMemoryBackend {
// to maintain backards compat, we use ttl as the cleanup rate:
return NewShardedBackend(ctx, shards, ttl, ttl, 1, h, MemoryBackendBuilder)
}
func NewShardedBackend(ctx context.Context, shards uint64, ttl time.Duration,
cleanUpRate time.Duration, cleanUpThreads uint64, h Hasher, backendBuilder BackendBuilder,
) *ShardedMemoryBackend {
b := &ShardedMemoryBackend{
shards: backendBuilder(ctx, ttl, cleanUpRate, cleanUpThreads, shards),
total: shards,
hasher: h,
}
return b
}
func (b *ShardedMemoryBackend) shard(key string) uint64 {
return b.hasher(key) % b.total
}
// Load implements the Backend interface
func (b *ShardedMemoryBackend) Load(key string, f func() interface{}) interface{} {
return b.shards[b.shard(key)].Load(key, f)
}
// Store implements the Backend interface
func (b *ShardedMemoryBackend) Store(key string, v interface{}) error {
return b.shards[b.shard(key)].Store(key, v)
}