Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First version of turbo cache #2

Open
wants to merge 165 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
165 commits
Select commit Hold shift + click to select a range
32e2517
introduced private set without lock
andectionsharechat Jul 24, 2023
eb82c00
naive batch write implementation
andectionsharechat Jul 24, 2023
18a0729
small cleans
andectionsharechat Jul 24, 2023
1eef94d
fixed writing cache error
andectionsharechat Jul 24, 2023
675daf7
updated go modele name
andectionsharechat Jul 24, 2023
b173153
increased timer interval
andectionsharechat Jul 25, 2023
1638d94
updated parameters a bit
andectionsharechat Jul 25, 2023
cf5459d
tuned contention parameters
andectionsharechat Jul 26, 2023
5f66907
removed useless set
andectionsharechat Jul 27, 2023
250649c
updated package name
andectionsharechat Jul 27, 2023
2b137a7
fixed tests
andectionsharechat Jul 27, 2023
254b7f2
fixed tests
andectionsharechat Jul 27, 2023
2cc0b1b
updated module name
andectionsharechat Jul 27, 2023
28aff5b
fixed big cache panic
andectionsharechat Aug 3, 2023
0b54936
fixed all tests
andectionsharechat Aug 4, 2023
0c369fe
changed bucket to 512
andectionsharechat Aug 4, 2023
75755e0
fixed tests
andectionsharechat Aug 4, 2023
45f5fb1
fixed race condition
andectionsharechat Aug 5, 2023
02823fe
increase go version
andectionsharechat Aug 5, 2023
3d79619
fixed go version in ci
andectionsharechat Aug 5, 2023
5da66c8
fixed test
andectionsharechat Aug 5, 2023
575c5b2
code clean
andectionsharechat Aug 5, 2023
fd775cd
code clean
andectionsharechat Aug 5, 2023
182b934
cleaned code
andectionsharechat Aug 5, 2023
81828ae
fixing tests
andectionsharechat Aug 6, 2023
c745332
code clean
andectionsharechat Aug 6, 2023
3dcc29a
stabilize tests
andectionsharechat Aug 6, 2023
835b2ac
added sync write
andectionsharechat Aug 6, 2023
0808cce
simplifed tests
andectionsharechat Aug 6, 2023
7e2ea4a
drop on high contention
andectionsharechat Aug 8, 2023
f7ed73e
added drop writes stats
andectionsharechat Aug 9, 2023
8d1a9a8
reduced buffer size
andectionsharechat Aug 9, 2023
9f93372
increased buffer size
andectionsharechat Aug 9, 2023
ad4b5db
collect write queue stats
andectionsharechat Aug 10, 2023
4c8deac
increased bucket count
andectionsharechat Aug 10, 2023
d0bf3a3
reduced bucket count
andectionsharechat Aug 10, 2023
dcbd030
make deduplication
andectionsharechat Aug 11, 2023
86699e3
increased init size of buffer
andectionsharechat Aug 11, 2023
b6546b1
huge number of buckets
andectionsharechat Aug 11, 2023
10a73ae
updated bucket count
andectionsharechat Aug 11, 2023
0c37dc8
reduced critical section
andectionsharechat Aug 11, 2023
28daa89
Added naive limiter
andectionsharechat Aug 11, 2023
137c9dd
improved dedup logic
andectionsharechat Aug 15, 2023
b0eb5b5
removed limiter
andectionsharechat Aug 15, 2023
36f55a0
fixed dedup logic
andectionsharechat Aug 15, 2023
5ecf4b9
small optimisation
andectionsharechat Aug 15, 2023
73c032b
intorduced limiter
andectionsharechat Aug 15, 2023
3d75efe
fixed test
andectionsharechat Aug 15, 2023
bb440b1
removed hash and pointer allocation
andectionsharechat Aug 15, 2023
df043b8
rollback idea of smart dedup
andectionsharechat Aug 15, 2023
1689be0
reduced memory allocation
andectionsharechat Aug 15, 2023
c6c650a
fixed limiter
andectionsharechat Aug 15, 2023
a9546ef
increased bucket count
andectionsharechat Aug 15, 2023
cc8bfba
removing limiting
andectionsharechat Aug 16, 2023
a8217bd
bucket count
andectionsharechat Aug 18, 2023
5424c8b
added bucket stats
andectionsharechat Aug 18, 2023
283b56b
bucket count 2048
andectionsharechat Aug 18, 2023
4a267a8
reduced gc allocation in buffering
andectionsharechat Aug 18, 2023
2e19dfb
reduced batch write cpu
andectionsharechat Aug 20, 2023
9aeadf2
fixed bug with batching
andectionsharechat Aug 20, 2023
50d0ed6
fixed out of range exception
andectionsharechat Aug 21, 2023
21df6ee
reduced bucket count
andectionsharechat Aug 21, 2023
131230e
reduced bucket count
andectionsharechat Aug 21, 2023
72a6c0f
key dedup
andectionsharechat Aug 22, 2023
cb654b2
dedup fixes
andectionsharechat Aug 22, 2023
7934c26
code clean
andectionsharechat Aug 22, 2023
cc9feb3
increased buckets
andectionsharechat Aug 22, 2023
54efc59
added different l1 implementation
andectionsharechat Aug 22, 2023
b32bedb
added different l1 implementation
andectionsharechat Aug 22, 2023
d51fb37
fixed race condition
andectionsharechat Aug 23, 2023
9a03788
fixed bug
andectionsharechat Aug 23, 2023
a8b1fdf
not blocking send to channel
andectionsharechat Aug 24, 2023
fd6e721
fixed dropped writes metrics
andectionsharechat Aug 24, 2023
3fdc004
collect proper metrics
andectionsharechat Aug 24, 2023
3b2cfc5
collect proper metrics of dropped writes
andectionsharechat Aug 24, 2023
9843802
Merge remote-tracking branch 'origin/bucket_experiments' into bucket_…
andectionsharechat Aug 24, 2023
33360b7
increased proportion of write buffer
andectionsharechat Aug 25, 2023
7692384
pointer count optimisation
andectionsharechat Aug 27, 2023
bca1d9f
support big values
andectionsharechat Aug 31, 2023
3fd133e
benchmarking
andectionsharechat Aug 31, 2023
7cf377a
optimised batch set
andectionsharechat Sep 1, 2023
35824cd
fixed chunkIdx update
andectionsharechat Sep 1, 2023
36b2a4a
code clean
andectionsharechat Sep 3, 2023
53c2633
added unit tests on new item processing
andectionsharechat Sep 3, 2023
d4908a1
added unit tests on new item processing
andectionsharechat Sep 3, 2023
c07a0b9
incremental change
andectionsharechat Sep 10, 2023
557d5c8
incremental change
andectionsharechat Sep 10, 2023
9335e91
concurrent test
andectionsharechat Sep 10, 2023
260465e
incremental change
andectionsharechat Sep 10, 2023
f2879be
concurrency
andectionsharechat Sep 10, 2023
4a7d041
code clean
andectionsharechat Sep 10, 2023
a7bae81
fixed race condition
andectionsharechat Sep 11, 2023
150addf
code clean
andectionsharechat Sep 11, 2023
607e916
code clean
andectionsharechat Sep 11, 2023
e25ae43
code clean
andectionsharechat Sep 11, 2023
490bb42
code clean
andectionsharechat Sep 11, 2023
532e508
code clean
andectionsharechat Sep 11, 2023
a029f9e
fixed test
andectionsharechat Sep 11, 2023
0d1dc9b
code clean
andectionsharechat Sep 11, 2023
0e0d4ed
rollback sync set
andectionsharechat Sep 11, 2023
c9988a4
code clean
andectionsharechat Sep 11, 2023
a004ac2
code clean
andectionsharechat Sep 11, 2023
8a4a755
code clean
andectionsharechat Sep 11, 2023
79b3bc8
incremental change
andectionsharechat Sep 11, 2023
e96156d
fixed bugs with cleaning
andectionsharechat Sep 11, 2023
81f2989
removed test
andectionsharechat Oct 18, 2023
c47979b
code cleaned
andectionsharechat Oct 18, 2023
29d4b1d
removed unnececary tests
andectionsharechat Oct 23, 2023
0adfd57
code clean
andectionsharechat Oct 23, 2023
e0bc824
code clean
andectionsharechat Oct 23, 2023
eb9f8bb
fixed version
andectionsharechat Oct 23, 2023
d0e80da
fixed tests
andectionsharechat Oct 23, 2023
e7f1716
fixed tests
andectionsharechat Oct 23, 2023
0294c31
code clean
andectionsharechat Oct 23, 2023
37f1fa2
try build fixing
andectionsharechat Oct 23, 2023
3c2d114
stabilise tests
andectionsharechat Oct 23, 2023
23de532
try to fix build
andectionsharechat Oct 23, 2023
9d786ae
fixed the build
andectionsharechat Oct 23, 2023
274f0cc
fixed the build
andectionsharechat Oct 23, 2023
c55330a
fixed the build
andectionsharechat Oct 23, 2023
0abcc63
fixed the build
andectionsharechat Oct 23, 2023
0e24360
code clean
andectionsharechat Oct 23, 2023
19ef6c8
code clean
andectionsharechat Oct 24, 2023
8035011
update chunks atomic pointer before index
andectionsharechat Oct 25, 2023
1d577d4
code clean
andectionsharechat Oct 25, 2023
ed8103c
code clean
andectionsharechat Oct 25, 2023
c0a6697
code clean
andectionsharechat Oct 25, 2023
7248863
added trubo cache vs fast cache benchmark
andectionsharechat Oct 25, 2023
83958fa
code clean
andectionsharechat Oct 30, 2023
f3b9126
renamed refactoring
andectionsharechat Oct 30, 2023
2acd5c2
renoved unused methods
andectionsharechat Oct 30, 2023
b3d97eb
simplified syncronization
andectionsharechat Oct 30, 2023
96edcdc
simplified syncronisation
andectionsharechat Oct 30, 2023
0cb9b01
normalized benchmark
andectionsharechat Oct 30, 2023
22ce66a
code clean
andectionsharechat Nov 1, 2023
45f5e76
code clean
andectionsharechat Nov 1, 2023
81da1f5
code clean
andectionsharechat Nov 1, 2023
eb9dac7
release queued struct faster
andectionsharechat Nov 1, 2023
d036d32
code clean
andectionsharechat Nov 2, 2023
e053095
code clean
andectionsharechat Nov 2, 2023
e6a065f
increment refactoring
andectionsharechat Nov 2, 2023
32261f6
increment refactoring
andectionsharechat Nov 2, 2023
80efe16
increment refactoring
andectionsharechat Nov 2, 2023
292b404
fixed test
andectionsharechat Nov 2, 2023
d695dd8
incremental refactoring
andectionsharechat Nov 2, 2023
512a2a5
stopped dropping writes on flushs overflow
andectionsharechat Nov 2, 2023
61a148b
code clean
andectionsharechat Nov 2, 2023
82e3435
increment refactoring
andectionsharechat Nov 2, 2023
9299153
increment refactoring
andectionsharechat Nov 2, 2023
904350d
increment refactoring
andectionsharechat Nov 2, 2023
a591f0e
remove unnececcary sync primitive
andectionsharechat Nov 2, 2023
d49f268
incremental refactoring
andectionsharechat Nov 2, 2023
c553f92
incremental refactoring
andectionsharechat Nov 2, 2023
fb6ca1a
incremental refactoring
andectionsharechat Nov 2, 2023
2e4d97d
incremental refactoring
andectionsharechat Nov 2, 2023
18d4ca1
incremental refactoring
andectionsharechat Nov 2, 2023
863638c
incremental refactoring
andectionsharechat Nov 2, 2023
48ab725
go mod tidy
andectionsharechat Nov 2, 2023
45a6c80
removed vendor folder
andectionsharechat Nov 2, 2023
4f5f4c7
fixed race condition
andectionsharechat Nov 2, 2023
93b043f
add mutex waits in benchmarks
andectionsharechat Nov 3, 2023
9345432
rename refactoring
andectionsharechat Nov 3, 2023
472b51f
fixed units
andectionsharechat Nov 3, 2023
83b031a
clean code
andectionsharechat Nov 3, 2023
f5afb97
fixed sync write bug
andectionsharechat Nov 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 1 addition & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ jobs:
- name: Setup Go
uses: actions/setup-go@v1
with:
go-version: 1.13
go-version: 1.20
id: go
- name: Code checkout
uses: actions/checkout@v1
- name: Test
run: |
go test -v ./... -coverprofile=coverage.txt -covermode=atomic
go test -v ./... -race
- name: Build
run: |
Expand Down
52 changes: 27 additions & 25 deletions bigcache.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package fastcache
package turbocache

import (
"github.com/cespare/xxhash/v2"
"sync"
"sync/atomic"

xxhash "github.com/cespare/xxhash/v2"
)

// maxSubvalueLen is the maximum size of subvalue chunk.
Expand Down Expand Up @@ -43,26 +42,30 @@ func (c *Cache) SetBig(k, v []byte) {
valueHash := xxhash.Sum64(v)

// Split v into chunks with up to 64Kb each.
subkey := getSubkeyBuf()
var i uint64
for len(v) > 0 {
subkey.B = marshalUint64(subkey.B[:0], valueHash)
subkey.B = marshalUint64(subkey.B, uint64(i))
i++
subvalueLen := maxSubvalueLen
if len(v) < subvalueLen {
subvalueLen = len(v)
subKeyCount := len(v)/maxSubvalueLen + 2
uint64Size := 8
subkeys := make([]byte, 0, subKeyCount*uint64Size*2)
//var i uint64
startValueIndex := 0
endValueIndex := 0
startSubkeyIndex := 0
for i := 0; i <= len(v)/maxSubvalueLen; i++ {
startValueIndex = i * maxSubvalueLen
endValueIndex = (i + 1) * maxSubvalueLen
if endValueIndex > len(v) {
endValueIndex = len(v)
}
subvalue := v[:subvalueLen]
v = v[subvalueLen:]
c.Set(subkey.B, subvalue)
subkeys = marshalUint64(subkeys, valueHash)
subkeys = marshalUint64(subkeys, uint64(i))
bytes := subkeys[startSubkeyIndex:]
startSubkeyIndex = len(subkeys)
c.Set(bytes, v[startValueIndex:endValueIndex])
}

// Write metavalue, which consists of valueHash and valueLen.
subkey.B = marshalUint64(subkey.B[:0], valueHash)
subkey.B = marshalUint64(subkey.B, uint64(valueLen))
c.Set(k, subkey.B)
putSubkeyBuf(subkey)
startSubkeyIndex = len(subkeys)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the pulling object as we don't control lifecycle here anymore

subkeys = marshalUint64(subkeys, valueHash)
subkeys = marshalUint64(subkeys, uint64(valueLen))
c.Set(k, subkeys[startSubkeyIndex:])
}

// GetBig searches for the value for the given k, appends it to dst
Expand Down Expand Up @@ -107,7 +110,7 @@ func (c *Cache) GetBig(dst, k []byte) (r []byte) {
var i uint64
for uint64(len(dst)-dstLen) < valueLen {
subkey.B = marshalUint64(subkey.B[:0], valueHash)
subkey.B = marshalUint64(subkey.B, uint64(i))
subkey.B = marshalUint64(subkey.B, i)
i++
dstNew := c.Get(dst, subkey.B)
if len(dstNew) == len(dst) {
Expand All @@ -133,9 +136,6 @@ func (c *Cache) GetBig(dst, k []byte) (r []byte) {

func getSubkeyBuf() *bytesBuf {
v := subkeyPool.Get()
if v == nil {
return &bytesBuf{}
}
return v.(*bytesBuf)
}

Expand All @@ -144,7 +144,9 @@ func putSubkeyBuf(bb *bytesBuf) {
subkeyPool.Put(bb)
}

var subkeyPool sync.Pool
var subkeyPool = sync.Pool{New: func() any {
return &bytesBuf{}
}}

type bytesBuf struct {
B []byte
Expand Down
9 changes: 5 additions & 4 deletions bigcache_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package fastcache
package turbocache

import (
"bytes"
Expand All @@ -7,7 +7,8 @@ import (
)

func TestSetGetBig(t *testing.T) {
c := New(256 * 1024 * 1024)
c := New(NewConfig(1024*1024*1024, 3000, 1, 1))
defer c.Close()
const valuesCount = 10
for _, valueSize := range []int{1, 100, 1<<16 - 1, 1 << 16, 1<<16 + 1, 1 << 17, 1<<17 + 1, 1<<17 - 1, 1 << 19} {
t.Run(fmt.Sprintf("valueSize_%d", valueSize), func(t *testing.T) {
Expand All @@ -26,13 +27,13 @@ func testSetGetBig(t *testing.T, c *Cache, valueSize, valuesCount, seed int) {
value := createValue(valueSize, seed)
c.SetBig(key, value)
m[string(key)] = value
buf = c.GetBig(buf[:0], key)
buf = c.getBigWithExpectedValue(buf[:0], key, value)
if !bytes.Equal(buf, value) {
t.Fatalf("seed=%d; unexpected value obtained for key=%q; got len(value)=%d; want len(value)=%d", seed, key, len(buf), len(value))
}
}
var s Stats
c.UpdateStats(&s)
c.UpdateStats(&s, true)
if s.SetBigCalls < uint64(valuesCount) {
t.Fatalf("expecting SetBigCalls >= %d; got %d", valuesCount, s.SetBigCalls)
}
Expand Down
47 changes: 44 additions & 3 deletions bigcache_timing_test.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,74 @@
package fastcache
package turbocache

import (
"github.com/ShareChat/turbo-cache/internal/benchmarking"
"github.com/VictoriaMetrics/fastcache"
"testing"
)

func BenchmarkSetBig(b *testing.B) {
key := []byte("key12345")
value := createValue(256*1024, 0)
c := New(1024 * 1024)
c := New(newCacheConfigBenchmarkParams(1024 * 1024))
b.SetBytes(int64(len(value)))
b.ReportAllocs()
b.ResetTimer()
mutexMetrics := benchmarking.NewMutexMetricsCollector()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
key[0]++
c.SetBig(key, value)
}
})
mutexMetrics.Report(b)
}

func BenchmarkGetBig(b *testing.B) {
key := []byte("key12345")
value := createValue(265*1024, 0)
c := New(1024 * 1024)
c := New(newCacheConfigBenchmarkParams(1024 * 1024))
c.SetBig(key, value)
b.SetBytes(int64(len(value)))
b.ReportAllocs()
b.ResetTimer()
mutexMetrics := benchmarking.NewMutexMetricsCollector()
b.RunParallel(func(pb *testing.PB) {
var buf []byte
for pb.Next() {
buf = c.GetBig(buf[:0], key)
}
})
mutexMetrics.Report(b)
}

func BenchmarkFastCacheSetBig(b *testing.B) {
key := []byte("key12345")
value := createValue(256*1024, 0)
c := fastcache.New(1024 * 1024)
b.SetBytes(int64(len(value)))
b.ReportAllocs()
mutexMetrics := benchmarking.NewMutexMetricsCollector()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
c.SetBig(key, value)
}
})
mutexMetrics.Report(b)
}

func BenchmarkFastCacheGetBig(b *testing.B) {
key := []byte("key12345")
value := createValue(265*1024, 0)
c := fastcache.New(1024 * 1024)
c.SetBig(key, value)
b.SetBytes(int64(len(value)))
b.ReportAllocs()
mutexMetrics := benchmarking.NewMutexMetricsCollector()
b.RunParallel(func(pb *testing.PB) {
var buf []byte
for pb.Next() {
buf = c.GetBig(buf[:0], key)
}
})
mutexMetrics.Report(b)
}
Loading
Loading