Skip to content

Commit 8614d4a

Browse files
author
huangruofei
committed
feat: enable mmap to alloc on unix-like system
1 parent a2f05d7 commit 8614d4a

File tree

6 files changed

+96
-20
lines changed

6 files changed

+96
-20
lines changed

go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
module github.com/allegro/bigcache/v3
22

3-
go 1.16
3+
go 1.17
4+
5+
require golang.org/x/sys v0.1.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
2+
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

queue/bytes_queue.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,6 @@ func getNeededSize(length int) int {
5757
return length + header
5858
}
5959

60-
// NewBytesQueue initialize new bytes queue.
61-
// capacity is used in bytes array allocation
62-
// When verbose flag is set then information about memory allocation are printed
63-
func NewBytesQueue(capacity int, maxCapacity int, verbose bool) *BytesQueue {
64-
return &BytesQueue{
65-
array: make([]byte, capacity),
66-
capacity: capacity,
67-
maxCapacity: maxCapacity,
68-
headerBuffer: make([]byte, binary.MaxVarintLen32),
69-
tail: leftMarginIndex,
70-
head: leftMarginIndex,
71-
rightMargin: leftMarginIndex,
72-
verbose: verbose,
73-
}
74-
}
75-
7660
// Reset removes all entries from queue
7761
func (q *BytesQueue) Reset() {
7862
// Just reset indexes

queue/bytes_queue_test.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func TestResetFullQueue(t *testing.T) {
9494

9595
// then
9696
assertEqual(t, blob('c', 8), pop(queue))
97-
assertEqual(t, queue.Capacity(), 10)
97+
assertEqual(t, queue.Capacity(), unixOr_int(20, 10))
9898
}
9999

100100
func TestReset(t *testing.T) {
@@ -416,9 +416,9 @@ func TestPushEntryAfterAllocateAdditionMemory(t *testing.T) {
416416
queue.Pop()
417417

418418
// allocate more memory
419-
assertEqual(t, 9, queue.Capacity())
419+
assertEqual(t, unixOr_int(20, 9), queue.Capacity())
420420
queue.Push([]byte("c"))
421-
assertEqual(t, 18, queue.Capacity())
421+
assertEqual(t, unixOr_int(20, 18), queue.Capacity())
422422

423423
// push after allocate
424424
_, err := queue.Push([]byte("d"))
@@ -508,3 +508,12 @@ func objectsAreEqual(expected, actual interface{}) bool {
508508
}
509509
return bytes.Equal(exp, act)
510510
}
511+
512+
func unixOr_int(unix, other int) int {
513+
switch runtime.GOOS {
514+
case "aix", "darwin", "dragonfly", "freebsd", "openbsd", "solaris", "zos", "linux", "netbsd":
515+
return unix
516+
default:
517+
return other
518+
}
519+
}

queue/new_others.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//go:build !aix && !darwin && !dragonfly && !freebsd && !openbsd && !solaris && !zos && !linux && !netbsd
2+
// +build !aix,!darwin,!dragonfly,!freebsd,!openbsd,!solaris,!zos,!linux,!netbsd
3+
4+
package queue
5+
6+
import "encoding/binary"
7+
8+
// NewBytesQueue initialize new bytes queue.
9+
// capacity is used in bytes array allocation
10+
// When verbose flag is set then information about memory allocation are printed
11+
func NewBytesQueue(capacity int, maxCapacity int, verbose bool) *BytesQueue {
12+
return &BytesQueue{
13+
array: make([]byte, capacity),
14+
capacity: capacity,
15+
maxCapacity: maxCapacity,
16+
headerBuffer: make([]byte, binary.MaxVarintLen32),
17+
tail: leftMarginIndex,
18+
head: leftMarginIndex,
19+
rightMargin: leftMarginIndex,
20+
verbose: verbose,
21+
}
22+
}

queue/new_unix.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris || zos || linux || netbsd
2+
// +build aix darwin dragonfly freebsd openbsd solaris zos linux netbsd
3+
4+
// build tags are sync from:
5+
// golang.org/x/[email protected]/unix/mmap_nomremap.go
6+
// golang.org/x/[email protected]/unix/mmap_mremap.go
7+
8+
package queue
9+
10+
import (
11+
"encoding/binary"
12+
13+
"golang.org/x/sys/unix"
14+
)
15+
16+
func pageUpper(in uintptr) uintptr {
17+
const pageMask = ((1 << 12) - 1)
18+
return (in + pageMask) &^ (pageMask)
19+
}
20+
21+
// NewBytesQueue initialize new bytes queue.
22+
// capacity is used in bytes array allocation
23+
// When verbose flag is set then information about memory allocation are printed
24+
func NewBytesQueue(capacity int, maxCapacity int, verbose bool) *BytesQueue {
25+
var array []byte
26+
if maxCapacity != 0 {
27+
var err error
28+
if maxCapacity >= 1<<12 {
29+
array, err = unix.Mmap(
30+
0,
31+
0,
32+
int(pageUpper(uintptr(maxCapacity))),
33+
unix.PROT_READ|unix.PROT_WRITE,
34+
unix.MAP_ANON|unix.MAP_PRIVATE,
35+
)
36+
if err != nil {
37+
panic(err)
38+
}
39+
} else {
40+
array = make([]byte, maxCapacity)
41+
}
42+
capacity = maxCapacity
43+
} else {
44+
array = make([]byte, capacity)
45+
}
46+
47+
return &BytesQueue{
48+
array: array,
49+
capacity: capacity,
50+
maxCapacity: maxCapacity,
51+
headerBuffer: make([]byte, binary.MaxVarintLen32),
52+
tail: leftMarginIndex,
53+
head: leftMarginIndex,
54+
rightMargin: leftMarginIndex,
55+
verbose: verbose,
56+
}
57+
}

0 commit comments

Comments
 (0)