2015-11-25 20:06:07 +00:00
|
|
|
package tsm1
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
2015-12-03 18:13:48 +00:00
|
|
|
"syscall"
|
|
|
|
"unsafe"
|
|
|
|
"reflect"
|
2015-11-25 20:06:07 +00:00
|
|
|
)
|
|
|
|
|
2015-12-03 18:13:48 +00:00
|
|
|
// maxMapSize represents the largest mmap size supported by Bolt.
|
|
|
|
const maxMapSize = 0xFFFFFFFFFFFF // 256TB
|
|
|
|
|
|
|
|
// mmap implementation for Windows
|
|
|
|
// Based on: https://github.com/edsrzf/mmap-go
|
|
|
|
// Based on: https://github.com/boltdb/bolt/bolt_windows.go
|
|
|
|
// Ref: https://groups.google.com/forum/#!topic/golang-nuts/g0nLwQI9www
|
|
|
|
func mmap(f *os.File, offset int64, length int) (out []byte,err error) {
|
|
|
|
// Open a file mapping handle.
|
|
|
|
sizelo := uint32(length >> 32)
|
|
|
|
sizehi := uint32(length) & 0xffffffff
|
|
|
|
h, errno := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, sizelo, sizehi, nil)
|
|
|
|
if h == 0 {
|
|
|
|
return nil, os.NewSyscallError("CreateFileMapping", errno)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the memory map.
|
|
|
|
addr, errno := syscall.MapViewOfFile(h, syscall.FILE_MAP_READ, 0, 0, uintptr(length))
|
|
|
|
if addr == 0 {
|
|
|
|
return nil, os.NewSyscallError("MapViewOfFile", errno)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close mapping handle.
|
|
|
|
if err := syscall.CloseHandle(syscall.Handle(h)); err != nil {
|
|
|
|
return nil, os.NewSyscallError("CloseHandle", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Convert to a byte array.
|
|
|
|
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&out))
|
|
|
|
hdr.Data = uintptr(unsafe.Pointer(addr))
|
|
|
|
hdr.Len = length
|
|
|
|
hdr.Cap = length
|
|
|
|
|
|
|
|
return
|
2015-11-25 20:06:07 +00:00
|
|
|
}
|
|
|
|
|
2015-12-03 18:13:48 +00:00
|
|
|
// munmap Windows implementation
|
|
|
|
// Based on: https://github.com/edsrzf/mmap-go
|
|
|
|
// Based on: https://github.com/boltdb/bolt/bolt_windows.go
|
2015-11-25 20:06:07 +00:00
|
|
|
func munmap(b []byte) (err error) {
|
2015-12-03 18:13:48 +00:00
|
|
|
|
|
|
|
addr := (uintptr)(unsafe.Pointer(&b[0]))
|
|
|
|
if err := syscall.UnmapViewOfFile(addr); err != nil {
|
|
|
|
return os.NewSyscallError("UnmapViewOfFile", err)
|
|
|
|
}
|
|
|
|
return nil
|
2015-11-25 20:06:07 +00:00
|
|
|
}
|