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 1eea1f42..016ea107 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ -module github.com/allegro/bigcache/v3 +module github.com/tecty/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..328ce632 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,39 @@ 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 { + var err error + 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 { + array = make([]byte, capacity) + } + return &BytesQueue{ - array: make([]byte, capacity), + array: array, capacity: capacity, maxCapacity: maxCapacity, headerBuffer: make([]byte, binary.MaxVarintLen32), @@ -91,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")) 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)