From b93824753ba1ee1f67014bf3fd8e86add2b7ab5a Mon Sep 17 00:00:00 2001 From: huangruofei Date: Tue, 25 Jun 2024 17:29:08 +0800 Subject: [PATCH 1/3] feat: use mmap to alloc memeory needed --- go.mod | 2 ++ go.sum | 2 ++ queue/bytes_queue.go | 26 +++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1eea1f42..6e1a99a1 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/allegro/bigcache/v3 go 1.16 + +require golang.org/x/sys v0.21.0 diff --git a/go.sum b/go.sum index e69de29b..ac7fb31a 100644 --- a/go.sum +++ b/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= diff --git a/queue/bytes_queue.go b/queue/bytes_queue.go index c4fe2c08..b5cca394 100644 --- a/queue/bytes_queue.go +++ b/queue/bytes_queue.go @@ -4,6 +4,8 @@ import ( "encoding/binary" "log" "time" + + "golang.org/x/sys/unix" ) const ( @@ -56,13 +58,35 @@ func getNeededSize(length int) int { return length + header } +func pageUpper(in uintptr) uintptr { + const pageMask = ((1 << 12) - 1) + return (in + pageMask) &^ (pageMask) +} // NewBytesQueue initialize new bytes queue. // capacity is used in bytes array allocation // When verbose flag is set then information about memory allocation are printed func NewBytesQueue(capacity int, maxCapacity int, verbose bool) *BytesQueue { + var array []byte + if maxCapacity != 0 && maxCapacity >= 1<<12 { + var err error + array, err = unix.Mmap( + 0, + 0, + int(pageUpper(uintptr(maxCapacity))), + unix.PROT_READ|unix.PROT_WRITE, + unix.MAP_ANON|unix.MAP_PRIVATE, + ) + if err != nil { + panic(err) + } + capacity = maxCapacity + } else { + array = make([]byte, capacity) + } + return &BytesQueue{ - array: make([]byte, capacity), + array: array, capacity: capacity, maxCapacity: maxCapacity, headerBuffer: make([]byte, binary.MaxVarintLen32), From ac9bcad4aa361d914a433cd40acf0717dfd5a1d5 Mon Sep 17 00:00:00 2001 From: huangruofei Date: Thu, 27 Jun 2024 10:55:17 +0800 Subject: [PATCH 2/3] feat: use mmap to alloc memeory needed --- queue/bytes_queue.go | 26 +++++++++++++++----------- queue/bytes_queue_test.go | 6 +++--- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/queue/bytes_queue.go b/queue/bytes_queue.go index b5cca394..328ce632 100644 --- a/queue/bytes_queue.go +++ b/queue/bytes_queue.go @@ -68,17 +68,21 @@ func pageUpper(in uintptr) uintptr { // When verbose flag is set then information about memory allocation are printed func NewBytesQueue(capacity int, maxCapacity int, verbose bool) *BytesQueue { var array []byte - if maxCapacity != 0 && maxCapacity >= 1<<12 { + if maxCapacity != 0 { var err error - array, err = unix.Mmap( - 0, - 0, - int(pageUpper(uintptr(maxCapacity))), - unix.PROT_READ|unix.PROT_WRITE, - unix.MAP_ANON|unix.MAP_PRIVATE, - ) - if err != nil { - panic(err) + if maxCapacity >= 1<<12 { + array, err = unix.Mmap( + 0, + 0, + int(pageUpper(uintptr(maxCapacity))), + unix.PROT_READ|unix.PROT_WRITE, + unix.MAP_ANON|unix.MAP_PRIVATE, + ) + if err != nil { + panic(err) + } + } else { + array = make([]byte, maxCapacity) } capacity = maxCapacity } else { @@ -115,7 +119,7 @@ func (q *BytesQueue) Push(data []byte) (int, error) { if !q.canInsertAfterTail(neededSize) { if q.canInsertBeforeHead(neededSize) { q.tail = leftMarginIndex - } else if q.capacity+neededSize >= q.maxCapacity && q.maxCapacity > 0 { + } else if q.maxCapacity > 0 { return -1, &queueError{"Full queue. Maximum size limit reached."} } else { q.allocateAdditionalMemory(neededSize) diff --git a/queue/bytes_queue_test.go b/queue/bytes_queue_test.go index 81dd1078..5115a4bc 100644 --- a/queue/bytes_queue_test.go +++ b/queue/bytes_queue_test.go @@ -94,7 +94,7 @@ func TestResetFullQueue(t *testing.T) { // then assertEqual(t, blob('c', 8), pop(queue)) - assertEqual(t, queue.Capacity(), 10) + assertEqual(t, queue.Capacity(), 20) } func TestReset(t *testing.T) { @@ -416,9 +416,9 @@ func TestPushEntryAfterAllocateAdditionMemory(t *testing.T) { queue.Pop() // allocate more memory - assertEqual(t, 9, queue.Capacity()) + assertEqual(t, 20, queue.Capacity()) queue.Push([]byte("c")) - assertEqual(t, 18, queue.Capacity()) + assertEqual(t, 20, queue.Capacity()) // push after allocate _, err := queue.Push([]byte("d")) From 5fc06b7051a5767c85e89926574c761895e7df44 Mon Sep 17 00:00:00 2001 From: huangruofei Date: Thu, 27 Jun 2024 11:24:50 +0800 Subject: [PATCH 3/3] feat: replace mod name --- README.md | 10 +++++----- examples_test.go | 2 +- go.mod | 2 +- server/server.go | 2 +- server/server_test.go | 2 +- shard.go | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index badf71a1..7957ecdc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# BigCache [![Build Status](https://github.com/allegro/bigcache/workflows/build/badge.svg)](https://github.com/allegro/bigcache/actions?query=workflow%3Abuild) [![Coverage Status](https://coveralls.io/repos/github/allegro/bigcache/badge.svg?branch=main)](https://coveralls.io/github/allegro/bigcache?branch=main) [![GoDoc](https://godoc.org/github.com/allegro/bigcache/v3?status.svg)](https://godoc.org/github.com/allegro/bigcache/v3) [![Go Report Card](https://goreportcard.com/badge/github.com/allegro/bigcache/v3)](https://goreportcard.com/report/github.com/allegro/bigcache/v3) +# BigCache [![Build Status](https://github.com/allegro/bigcache/workflows/build/badge.svg)](https://github.com/allegro/bigcache/actions?query=workflow%3Abuild) [![Coverage Status](https://coveralls.io/repos/github/allegro/bigcache/badge.svg?branch=main)](https://coveralls.io/github/allegro/bigcache?branch=main) [![GoDoc](https://godoc.org/github.com/tecty/bigcache/v3?status.svg)](https://godoc.org/github.com/tecty/bigcache/v3) [![Go Report Card](https://goreportcard.com/badge/github.com/tecty/bigcache/v3)](https://goreportcard.com/report/github.com/tecty/bigcache/v3) Fast, concurrent, evicting in-memory cache written to keep big number of entries without impact on performance. BigCache keeps entries on heap but omits GC for them. To achieve that, operations on byte slices take place, @@ -14,7 +14,7 @@ Requires Go 1.12 or newer. import ( "fmt" "context" - "github.com/allegro/bigcache/v3" + "github.com/tecty/bigcache/v3" ) cache, _ := bigcache.New(context.Background(), bigcache.DefaultConfig(10 * time.Minute)) @@ -34,7 +34,7 @@ allocation can be avoided in that way. import ( "log" - "github.com/allegro/bigcache/v3" + "github.com/tecty/bigcache/v3" ) config := bigcache.Config { @@ -110,7 +110,7 @@ go version go1.13 linux/amd64 go test -bench=. -benchmem -benchtime=4s ./... -timeout 30m goos: linux goarch: amd64 -pkg: github.com/allegro/bigcache/v3/caches_bench +pkg: github.com/tecty/bigcache/v3/caches_bench BenchmarkMapSet-8 12999889 376 ns/op 199 B/op 3 allocs/op BenchmarkConcurrentMapSet-8 4355726 1275 ns/op 337 B/op 8 allocs/op BenchmarkFreeCacheSet-8 11068976 703 ns/op 328 B/op 2 allocs/op @@ -126,7 +126,7 @@ BenchmarkBigCacheGetParallel-8 60547064 86.1 ns/op 152 B/op BenchmarkFreeCacheGetParallel-8 50701280 147 ns/op 136 B/op 3 allocs/op BenchmarkConcurrentMapGetParallel-8 27353288 175 ns/op 24 B/op 2 allocs/op PASS -ok github.com/allegro/bigcache/v3/caches_bench 256.257s +ok github.com/tecty/bigcache/v3/caches_bench 256.257s ``` Writes and reads in bigcache are faster than in freecache. diff --git a/examples_test.go b/examples_test.go index 36fc76c6..94f616f2 100644 --- a/examples_test.go +++ b/examples_test.go @@ -6,7 +6,7 @@ import ( "log" "time" - "github.com/allegro/bigcache/v3" + "github.com/tecty/bigcache/v3" ) func Example() { diff --git a/go.mod b/go.mod index 6e1a99a1..016ea107 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/allegro/bigcache/v3 +module github.com/tecty/bigcache/v3 go 1.16 diff --git a/server/server.go b/server/server.go index a8f88601..55d1c017 100644 --- a/server/server.go +++ b/server/server.go @@ -9,7 +9,7 @@ import ( "os" "strconv" - "github.com/allegro/bigcache/v3" + "github.com/tecty/bigcache/v3" ) const ( diff --git a/server/server_test.go b/server/server_test.go index 266afef7..8e4cc326 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/allegro/bigcache/v3" + "github.com/tecty/bigcache/v3" ) const ( diff --git a/shard.go b/shard.go index 4f03b53e..7a5b981d 100644 --- a/shard.go +++ b/shard.go @@ -5,7 +5,7 @@ import ( "sync" "sync/atomic" - "github.com/allegro/bigcache/v3/queue" + "github.com/tecty/bigcache/v3/queue" ) type onRemoveCallback func(wrappedEntry []byte, reason RemoveReason)