mdbx: MADV_REMOVE for unallocated space.

Change-Id: I14db843cf6e0dc713e2f302dc5ad86dc405c8d62
This commit is contained in:
Leo Yuriev 2016-04-27 01:52:38 +03:00
parent 745bdd346a
commit 477932e2b3

35
mdb.c
View File

@ -4319,7 +4319,7 @@ mdb_env_create(MDB_env **env)
} }
static int __cold static int __cold
mdb_env_map(MDB_env *env, void *addr) mdb_env_map(MDB_env *env, void *addr, size_t usedsize)
{ {
unsigned flags = env->me_flags; unsigned flags = env->me_flags;
@ -4346,7 +4346,7 @@ mdb_env_map(MDB_env *env, void *addr)
return EBUSY; /* TODO: Make a new MDB_* error code? */ return EBUSY; /* TODO: Make a new MDB_* error code? */
} }
if (madvise(env->me_map, env->me_mapsize, MADV_DONTFORK) < 0) if (madvise(env->me_map, env->me_mapsize, MADV_DONTFORK))
return errno; return errno;
#ifdef MADV_NOHUGEPAGE #ifdef MADV_NOHUGEPAGE
@ -4359,14 +4359,16 @@ mdb_env_map(MDB_env *env, void *addr)
} }
#endif #endif
if (madvise(env->me_map, env->me_mapsize, MADV_WILLNEED) < 0) #ifdef MADV_REMOVE
return errno; if (flags & MDB_WRITEMAP) {
assert(used_edge < env->me_mapsize);
if (flags & MDB_NORDAHEAD) { (void) madvise(env->me_map + usedsize, env->me_mapsize - usedsize, MADV_REMOVE);
/* Turn off readahead. It's harmful when the DB is larger than RAM. */
if (madvise(env->me_map, env->me_mapsize, MADV_RANDOM) < 0)
return errno;
} }
#endif
/* Turn on/off readahead. It's harmful when the DB is larger than RAM. */
if (madvise(env->me_map, env->me_mapsize, (flags & MDB_NORDAHEAD) ? MADV_RANDOM : MADV_WILLNEED))
return errno;
/* Lock meta pages to avoid unexpected write, /* Lock meta pages to avoid unexpected write,
* before the data pages would be synchronized. */ * before the data pages would be synchronized. */
@ -4405,12 +4407,10 @@ mdb_env_set_mapsize(MDB_env *env, size_t size)
meta = mdb_meta_head_w(env); meta = mdb_meta_head_w(env);
if (!size) if (!size)
size = meta->mm_mapsize; size = meta->mm_mapsize;
{ /* Silently round up to minimum if the size is too small */
/* Silently round up to minimum if the size is too small */ const size_t usedsize = (meta->mm_last_pg + 1) * env->me_psize;
size_t minsize = (meta->mm_last_pg + 1) * env->me_psize; if (size < usedsize)
if (size < minsize) size = usedsize;
size = minsize;
}
munmap(env->me_map, env->me_mapsize); munmap(env->me_map, env->me_mapsize);
#ifdef USE_VALGRIND #ifdef USE_VALGRIND
VALGRIND_DISCARD(env->me_valgrind_handle); VALGRIND_DISCARD(env->me_valgrind_handle);
@ -4418,7 +4418,7 @@ mdb_env_set_mapsize(MDB_env *env, size_t size)
#endif #endif
env->me_mapsize = size; env->me_mapsize = size;
old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL; old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL;
rc = mdb_env_map(env, old); rc = mdb_env_map(env, old, usedsize);
if (rc) if (rc)
return rc; return rc;
} }
@ -4536,7 +4536,8 @@ mdb_env_open2(MDB_env *env, MDB_meta *meta)
newenv = 0; newenv = 0;
} }
rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta->mm_address : NULL); const size_t usedsize = (meta->mm_last_pg + 1) * env->me_psize;
rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta->mm_address : NULL, usedsize);
if (rc) if (rc)
return rc; return rc;