clean up the implementation of the new memfiles.resize

This commit is contained in:
Araq 2018-12-12 12:10:17 +01:00
commit f828e5da49

View file

@ -282,34 +282,34 @@ proc flush*(f: var MemFile; attempts: Natural = 3) =
if lastErr != EBUSY.OSErrorCode: if lastErr != EBUSY.OSErrorCode:
raiseOSError(lastErr, "error flushing mapping") raiseOSError(lastErr, "error flushing mapping")
proc resize*(f: var MemFile, newFileSize: int) = when defined(posix) or defined(nimdoc):
## resize and re-map the file underlying an ``allowRemap MemFile``. NOTE: proc resize*(f: var MemFile, newFileSize: int) {.raises: [IOError, OSError].} =
## this assumes the entire file is mapped read-write at offset zero. Also, ## resize and re-map the file underlying an ``allowRemap MemFile``.
## the value of ``.mem`` will probably change. ## **Note**: this assumes the entire file is mapped read-write at offset zero.
when defined(windows): ## Also, the value of ``.mem`` will probably change.
discard #TODO This needs to be implemented. ## **Note**: This is not (yet) avaiable on Windows.
else: when defined(posix):
if f.handle == -1: if f.handle == -1:
raise newException(IOError, raise newException(IOError,
"Cannot resize MemFile opened with allowRemap=false") "Cannot resize MemFile opened with allowRemap=false")
if ftruncate(f.handle, newFileSize) == -1: if ftruncate(f.handle, newFileSize) == -1:
raiseOSError(osLastError())
when defined(linux): #Maybe NetBSD, too?
#On Linux this can be over 100 times faster than a munmap,mmap cycle.
proc mremap(old: pointer; oldSize,newSize: csize; flags: cint): pointer {.
importc: "mremap", header: "<sys/mman.h>" .}
let newAddr = mremap(f.mem, csize(f.size), csize(newFileSize), cint(1))
if newAddr == cast[pointer](MAP_FAILED):
raiseOSError(osLastError()) raiseOSError(osLastError())
else: when defined(linux): #Maybe NetBSD, too?
if munmap(f.mem, f.size) != 0: #On Linux this can be over 100 times faster than a munmap,mmap cycle.
raiseOSError(osLastError()) proc mremap(old: pointer; oldSize,newSize: csize; flags: cint): pointer {.
let newAddr = mmap(nil, newFileSize, PROT_READ or PROT_WRITE, importc: "mremap", header: "<sys/mman.h>" .}
MAP_SHARED or MAP_POPULATE, f.handle, 0) let newAddr = mremap(f.mem, csize(f.size), csize(newFileSize), cint(1))
if newAddr == cast[pointer](MAP_FAILED): if newAddr == cast[pointer](MAP_FAILED):
raiseOSError(osLastError()) raiseOSError(osLastError())
f.mem = newAddr else:
f.size = newFileSize if munmap(f.mem, f.size) != 0:
raiseOSError(osLastError())
let newAddr = mmap(nil, newFileSize, PROT_READ or PROT_WRITE,
MAP_SHARED or MAP_POPULATE, f.handle, 0)
if newAddr == cast[pointer](MAP_FAILED):
raiseOSError(osLastError())
f.mem = newAddr
f.size = newFileSize
proc close*(f: var MemFile) = proc close*(f: var MemFile) =
## closes the memory mapped file `f`. All changes are written back to the ## closes the memory mapped file `f`. All changes are written back to the