github.com/coocood/badger@v1.5.1-0.20200528065104-c02ac3616d04/y/mmap_windows.go (about) 1 // +build windows 2 3 /* 4 * Copyright 2017 Dgraph Labs, Inc. and Contributors 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package y 20 21 import ( 22 "fmt" 23 "os" 24 "syscall" 25 "unsafe" 26 ) 27 28 func Mmap(fd *os.File, write bool, size int64) ([]byte, error) { 29 protect := syscall.PAGE_READONLY 30 access := syscall.FILE_MAP_READ 31 32 if write { 33 protect = syscall.PAGE_READWRITE 34 access = syscall.FILE_MAP_WRITE 35 } 36 fi, err := fd.Stat() 37 if err != nil { 38 return nil, err 39 } 40 41 // Truncate the database to the size of the mmap. 42 if fi.Size() < size { 43 if err := fd.Truncate(size); err != nil { 44 return nil, fmt.Errorf("truncate: %s", err) 45 } 46 } 47 48 // Open a file mapping handle. 49 sizelo := uint32(size >> 32) 50 sizehi := uint32(size) & 0xffffffff 51 52 handler, err := syscall.CreateFileMapping(syscall.Handle(fd.Fd()), nil, 53 uint32(protect), sizelo, sizehi, nil) 54 if err != nil { 55 return nil, os.NewSyscallError("CreateFileMapping", err) 56 } 57 58 // Create the memory map. 59 addr, err := syscall.MapViewOfFile(handler, uint32(access), 0, 0, uintptr(size)) 60 if addr == 0 { 61 return nil, os.NewSyscallError("MapViewOfFile", err) 62 } 63 64 // Close mapping handle. 65 if err := syscall.CloseHandle(syscall.Handle(handler)); err != nil { 66 return nil, os.NewSyscallError("CloseHandle", err) 67 } 68 69 // Slice memory layout 70 // Copied this snippet from golang/sys package 71 var sl = struct { 72 addr uintptr 73 len int 74 cap int 75 }{addr, int(size), int(size)} 76 77 // Use unsafe to turn sl into a []byte. 78 data := *(*[]byte)(unsafe.Pointer(&sl)) 79 80 return data, nil 81 } 82 83 func Munmap(b []byte) error { 84 return syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&b[0]))) 85 } 86 87 func Madvise(b []byte, readahead bool) error { 88 // Do Nothing. We don’t care about this setting on Windows 89 return nil 90 }