diff --git a/src/memory/map.cpp b/src/memory/map.cpp index b1e8b646..d421e9c9 100644 --- a/src/memory/map.cpp +++ b/src/memory/map.cpp @@ -37,6 +37,10 @@ #include #include +#if defined(HAVE_APPLE) +int fallocate(int fd, int, off_t offset, off_t len) NOEXCEPT; +#endif + namespace libbitcoin { namespace database { @@ -554,47 +558,6 @@ bool map::remap_(size_t size) NOEXCEPT return finalize_(size); } -#if defined(HAVE_APPLE) -// ::fallocate is not defined on macOS, so implement. Ignores mode (linux). -int fallocate(int fd, int, size_t offset, size_t len) NOEXCEPT -{ - fstore_t store - { - // Prefer contiguous allocation - .fst_flags = F_ALLOCATECONTIG, - - // Allocate from EOF - .fst_posmode = F_PEOFPOSMODE, - - // Start from current capacity - .fst_offset = offset, - - // Delta size - .fst_length = len, - - // Output: actual bytes allocated - .fst_bytesalloc = 0 - }; - - // Try contiguous allocation. - auto result = ::fcntl(fd, F_PREALLOCATE, &store); - - // Fallback to non-contiguous. - if ((result == fail) && (errno != ENOSPC)) - { - store.fst_flags = F_ALLOCATEALL; - result = ::fcntl(fd, F_PREALLOCATE, &store); - } - - if (result == fail) - return fail; - - // Extend file to new size (required for mmap). This is not required on - // Linux because fallocate(2) automatically extends file's logical size. - return ::ftruncate(fd, offset + len); -} -#endif // HAVE_APPLE - // disk_full: space is set but no code is set with false return. bool map::resize_(size_t size) NOEXCEPT { @@ -681,3 +644,46 @@ BC_POP_WARNING() } // namespace database } // namespace libbitcoin + +#if defined(HAVE_APPLE) +// ::fallocate is not defined on macOS, so implement. Ignores mode (linux). +int fallocate(int fd, int, off_t offset, off_t len) NOEXCEPT +{ + constexpr auto fail = -1; + + fstore_t store + { + // Prefer contiguous allocation + .fst_flags = F_ALLOCATECONTIG, + + // Allocate from EOF + .fst_posmode = F_PEOFPOSMODE, + + // Start from current capacity + .fst_offset = offset, + + // Delta size + .fst_length = len, + + // Output: actual bytes allocated + .fst_bytesalloc = 0 + }; + + // Try contiguous allocation. + auto result = ::fcntl(fd, F_PREALLOCATE, &store); + + // Fallback to non-contiguous. + if ((result == fail) && (errno != ENOSPC)) + { + store.fst_flags = F_ALLOCATEALL; + result = ::fcntl(fd, F_PREALLOCATE, &store); + } + + if (result == fail) + return fail; + + // Extend file to new size (required for mmap). This is not required on + // Linux because fallocate(2) automatically extends file's logical size. + return ::ftruncate(fd, offset + len); +} +#endif // HAVE_APPLE