github.com/leslie-fei/fastcache@v0.0.0-20240520092641-b7a9eb05711f/gomemory/memory.go (about)

     1  package gomemory
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"unsafe"
     7  )
     8  
     9  // Memory based on go memory
    10  type Memory struct {
    11  	mem   []byte
    12  	basep unsafe.Pointer
    13  	bytes uint64
    14  }
    15  
    16  func NewMemory(bytes uint64) *Memory {
    17  	return &Memory{mem: make([]byte, bytes), bytes: bytes}
    18  }
    19  
    20  func (m *Memory) Attach() error {
    21  	if nil == m.basep {
    22  		m.mem[0] = 0
    23  		bh := (*reflect.SliceHeader)(unsafe.Pointer(&m.mem))
    24  		m.basep = unsafe.Pointer(bh.Data)
    25  	}
    26  	return nil
    27  }
    28  
    29  func (m *Memory) Detach() error {
    30  	if nil != m.basep {
    31  		m.basep = unsafe.Pointer(nil)
    32  		m.mem = nil
    33  	}
    34  	return nil
    35  }
    36  
    37  func (m *Memory) Ptr() unsafe.Pointer {
    38  	return m.basep
    39  }
    40  
    41  func (m *Memory) Size() uint64 {
    42  	return m.bytes
    43  }
    44  
    45  func (m *Memory) PtrOffset(offset uint64) unsafe.Pointer {
    46  	if offset >= m.bytes {
    47  		panic(fmt.Errorf("offset overflow: %d > %d", offset, m.bytes))
    48  	}
    49  	return unsafe.Pointer(uintptr(m.basep) + uintptr(offset))
    50  }
    51  
    52  func (m *Memory) Travel(skipOffset uint64, fn func(ptr unsafe.Pointer, size uint64) uint64) {
    53  	for skipOffset < m.bytes {
    54  		if advanceBytes := fn(m.PtrOffset(skipOffset), m.bytes-skipOffset); advanceBytes > 0 {
    55  			skipOffset += advanceBytes
    56  			continue
    57  		}
    58  		break
    59  	}
    60  }