diff --git a/src/mdbx.c b/src/mdbx.c index 31e8866e..caefd6aa 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -235,7 +235,7 @@ static void __hot mdbx_pnl_sort(MDBX_PNL pnl) { for (j = l + 1; j <= ir; j++) { a = pnl[j]; for (i = j - 1; i >= 1; i--) { - if (MDBX_PNL_ORDERED(pnl[i], a)) + if (MDBX_PNL_DISORDERED(a, pnl[i])) break; pnl[i + 1] = pnl[i]; } @@ -248,13 +248,13 @@ static void __hot mdbx_pnl_sort(MDBX_PNL pnl) { } else { k = (l + ir) >> 1; /* Choose median of left, center, right */ PNL_SWAP(pnl[k], pnl[l + 1]); - if (MDBX_PNL_DISORDERED(pnl[l], pnl[ir])) + if (MDBX_PNL_ORDERED(pnl[ir], pnl[l])) PNL_SWAP(pnl[l], pnl[ir]); - if (MDBX_PNL_DISORDERED(pnl[l + 1], pnl[ir])) + if (MDBX_PNL_ORDERED(pnl[ir], pnl[l + 1])) PNL_SWAP(pnl[l + 1], pnl[ir]); - if (MDBX_PNL_DISORDERED(pnl[l], pnl[l + 1])) + if (MDBX_PNL_ORDERED(pnl[l + 1], pnl[l])) PNL_SWAP(pnl[l], pnl[l + 1]); i = l + 1; @@ -266,7 +266,7 @@ static void __hot mdbx_pnl_sort(MDBX_PNL pnl) { while (MDBX_PNL_ORDERED(pnl[i], a)); do j--; - while (MDBX_PNL_DISORDERED(pnl[j], a)); + while (MDBX_PNL_ORDERED(a, pnl[j])); if (j < i) break; PNL_SWAP(pnl[i], pnl[j]); @@ -1601,18 +1601,21 @@ static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno, mdbx_mresize(env->me_flags, &env->me_dxb_mmap, size_bytes, limit_bytes); if (rc == MDBX_SUCCESS) { - if (env->me_txn) { - mdbx_tassert(env->me_txn, size_pgno >= env->me_txn->mt_next_pgno); - env->me_txn->mt_end_pgno = size_pgno; - } env->me_dbgeo.now = size_bytes; env->me_dbgeo.upper = limit_bytes; - } else { + } else if (rc != MDBX_RESULT_TRUE) { mdbx_error("failed resize datafile/mapping: " "present %" PRIuPTR " -> %" PRIuPTR ", " "limit %" PRIuPTR " -> %" PRIuPTR ", errcode %d", env->me_dbgeo.now, size_bytes, env->me_dbgeo.upper, limit_bytes, rc); + return rc; + } else { + mdbx_notice("unable resize datafile/mapping: " + "present %" PRIuPTR " -> %" PRIuPTR ", " + "limit %" PRIuPTR " -> %" PRIuPTR ", errcode %d", + env->me_dbgeo.now, size_bytes, env->me_dbgeo.upper, limit_bytes, + rc); } #ifdef USE_VALGRIND @@ -1624,7 +1627,12 @@ static int mdbx_mapresize(MDBX_env *env, const pgno_t size_pgno, VALGRIND_CREATE_BLOCK(env->me_map, env->me_mapsize, "mdbx"); } #endif - return rc; + + if (env->me_txn) { + mdbx_tassert(env->me_txn, size_pgno >= env->me_txn->mt_next_pgno); + env->me_txn->mt_end_pgno = size_pgno; + } + return MDBX_SUCCESS; } /* Allocate page numbers and memory for writing. Maintain me_last_reclaimed, diff --git a/src/osal.c b/src/osal.c index 381594a4..c3b50c92 100644 --- a/src/osal.c +++ b/src/osal.c @@ -892,9 +892,19 @@ int mdbx_mmap(int flags, mdbx_mmap_t *map, size_t must, size_t limit) { map->address = nullptr; return ntstatus2errcode(rc); } - assert(map->address != MAP_FAILED); - map->current = must; + + uint64_t filesize; + rc = mdbx_filesize(map->fd, &filesize); + if (rc != MDBX_SUCCESS) { + NtClose(map->section); + NtUnmapViewOfSection(GetCurrentProcess(), map->address); + map->section = 0; + map->address = nullptr; + return rc; + } + + map->current = (must < filesize) ? must : (size_t)filesize; map->length = ViewSize; return MDBX_SUCCESS; #else @@ -931,8 +941,8 @@ int mdbx_munmap(mdbx_mmap_t *map) { return MDBX_SUCCESS; } -int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t must, size_t limit) { - assert(must <= limit); +int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t atleast, size_t limit) { + assert(atleast <= limit); #if defined(_WIN32) || defined(_WIN64) if (limit < map->length) { /* Windows is unable shrinking a mapped section */ @@ -947,18 +957,34 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t must, size_t limit) { return ntstatus2errcode(rc); map->length = limit; } - if (must < map->current) { + if (atleast < map->current) { /* Windows is unable shrinking a mapped file */ - return MDBX_RESULT_TRUE; + uint8_t *ptr = (uint8_t *)map->address + atleast; + if (!VirtualFree(ptr, map->current - atleast, MEM_DECOMMIT)) + return MDBX_RESULT_TRUE; + + map->current = atleast; + int rc = mdbx_ftruncate(map->fd, atleast); + return (rc != MDBX_SUCCESS) ? MDBX_RESULT_TRUE : rc; } - if (must > map->current) { + if (atleast > map->current) { /* growth */ uint8_t *ptr = (uint8_t *)map->address + map->current; if (ptr != - VirtualAlloc(ptr, must - map->current, MEM_COMMIT, + VirtualAlloc(ptr, atleast - map->current, MEM_COMMIT, (flags & MDBX_WRITEMAP) ? PAGE_READWRITE : PAGE_READONLY)) return GetLastError(); - map->current = must; + map->current = atleast; + } + + uint64_t filesize; + int rc = mdbx_filesize(map->fd, &filesize); + if (rc != MDBX_SUCCESS) + return rc; + if (filesize < atleast) { + rc = mdbx_ftruncate(map->fd, atleast); + if (rc != MDBX_SUCCESS) + return rc; } return MDBX_SUCCESS; #else @@ -970,7 +996,7 @@ int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t must, size_t limit) { map->address = ptr; map->length = limit; } - return mdbx_ftruncate(map->fd, must); + return mdbx_ftruncate(map->fd, atleast); #endif } diff --git a/src/osal.h b/src/osal.h index 8d8d84cb..ec71d127 100644 --- a/src/osal.h +++ b/src/osal.h @@ -352,6 +352,7 @@ int mdbx_asprintf(char **strp, const char *fmt, ...); #endif #ifdef _MSC_VER + #ifndef snprintf #define snprintf(buffer, buffer_size, format, ...) \ _snprintf_s(buffer, buffer_size, _TRUNCATE, format, __VA_ARGS__) @@ -361,6 +362,12 @@ int mdbx_asprintf(char **strp, const char *fmt, ...); #define vsnprintf(buffer, buffer_size, format, args) \ _vsnprintf_s(buffer, buffer_size, _TRUNCATE, format, args) #endif /* vsnprintf */ + +#ifdef _ASSERTE +#undef assert +#define assert _ASSERTE +#endif + #endif /* _MSC_VER */ /*----------------------------------------------------------------------------*/