mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-11-10 18:25:17 +00:00
58 lines
1.5 KiB
Go
58 lines
1.5 KiB
Go
// Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use
|
|
// of this source code is governed by a BSD-style license that can be found in
|
|
// the LICENSE file.
|
|
|
|
//go:build (!invariants && !tracing) || race
|
|
// +build !invariants,!tracing race
|
|
|
|
package cache
|
|
|
|
import (
|
|
"unsafe"
|
|
|
|
"github.com/cockroachdb/pebble/internal/manual"
|
|
)
|
|
|
|
const valueSize = int(unsafe.Sizeof(Value{}))
|
|
|
|
func newValue(n int) *Value {
|
|
if n == 0 {
|
|
return nil
|
|
}
|
|
|
|
if !cgoEnabled {
|
|
// If Cgo is disabled then all memory is allocated from the Go heap and we
|
|
// can't play the trick below to combine the Value and buffer allocation.
|
|
v := &Value{buf: make([]byte, n)}
|
|
v.ref.init(1)
|
|
return v
|
|
}
|
|
|
|
// When we're not performing leak detection, the lifetime of the returned
|
|
// Value is exactly the lifetime of the backing buffer and we can manually
|
|
// allocate both.
|
|
//
|
|
// TODO(peter): It may be better to separate the allocation of the value and
|
|
// the buffer in order to reduce internal fragmentation in malloc. If the
|
|
// buffer is right at a power of 2, adding valueSize might push the
|
|
// allocation over into the next larger size.
|
|
b := manual.New(valueSize + n)
|
|
v := (*Value)(unsafe.Pointer(&b[0]))
|
|
v.buf = b[valueSize:]
|
|
v.ref.init(1)
|
|
return v
|
|
}
|
|
|
|
func (v *Value) free() {
|
|
if !cgoEnabled {
|
|
return
|
|
}
|
|
|
|
// When we're not performing leak detection, the Value and buffer were
|
|
// allocated contiguously.
|
|
n := valueSize + cap(v.buf)
|
|
buf := (*[manual.MaxArrayLen]byte)(unsafe.Pointer(v))[:n:n]
|
|
v.buf = nil
|
|
manual.Free(buf)
|
|
}
|