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 }