Add new MDB_RPAGE_CACHE def

Separate 32/64 dependency from rpage buffer mechanism
mdb.master3
Howard Chu 8 years ago
parent 775be5e50f
commit ac047d1eff
  1. 4
      libraries/liblmdb/lmdb.h
  2. 74
      libraries/liblmdb/mdb.c
  3. 4
      libraries/liblmdb/midl.c
  4. 4
      libraries/liblmdb/midl.h

@ -187,6 +187,10 @@ typedef mode_t mdb_mode_t;
# define MDB_FMT_Z "z" /**< printf/scanf format modifier for size_t */ # define MDB_FMT_Z "z" /**< printf/scanf format modifier for size_t */
#endif #endif
#if !defined(MDB_RPAGE_CACHE) || (defined(MDB_VL32) && !(MDB_RPAGE_CACHE))
#define MDB_RPAGE_CACHE 1
#endif
#ifndef MDB_VL32 #ifndef MDB_VL32
/** Unsigned type used for mapsize, entry counts and page/transaction IDs. /** Unsigned type used for mapsize, entry counts and page/transaction IDs.
* *

@ -1246,7 +1246,7 @@ struct MDB_txn {
/** Nested txn under this txn, set together with flag #MDB_TXN_HAS_CHILD */ /** Nested txn under this txn, set together with flag #MDB_TXN_HAS_CHILD */
MDB_txn *mt_child; MDB_txn *mt_child;
pgno_t mt_next_pgno; /**< next unallocated page */ pgno_t mt_next_pgno; /**< next unallocated page */
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
pgno_t mt_last_pgno; /**< last written page */ pgno_t mt_last_pgno; /**< last written page */
#endif #endif
/** The ID of this transaction. IDs are integers incrementing from 1. /** The ID of this transaction. IDs are integers incrementing from 1.
@ -1296,7 +1296,7 @@ struct MDB_txn {
MDB_cursor **mt_cursors; MDB_cursor **mt_cursors;
/** Array of flags for each DB */ /** Array of flags for each DB */
unsigned char *mt_dbflags; unsigned char *mt_dbflags;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
/** List of read-only pages (actually chunks) */ /** List of read-only pages (actually chunks) */
MDB_ID3L mt_rpages; MDB_ID3L mt_rpages;
/** We map chunks of 16 pages. Even though Windows uses 4KB pages, all /** We map chunks of 16 pages. Even though Windows uses 4KB pages, all
@ -1398,7 +1398,7 @@ struct MDB_cursor {
unsigned int mc_flags; /**< @ref mdb_cursor */ unsigned int mc_flags; /**< @ref mdb_cursor */
MDB_page *mc_pg[CURSOR_STACK]; /**< stack of pushed pages */ MDB_page *mc_pg[CURSOR_STACK]; /**< stack of pushed pages */
indx_t mc_ki[CURSOR_STACK]; /**< stack of page indices */ indx_t mc_ki[CURSOR_STACK]; /**< stack of page indices */
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
MDB_page *mc_ovpg; /**< a referenced overflow page */ MDB_page *mc_ovpg; /**< a referenced overflow page */
# define MC_OVPG(mc) ((mc)->mc_ovpg) # define MC_OVPG(mc) ((mc)->mc_ovpg)
# define MC_SET_OVPG(mc, pg) ((mc)->mc_ovpg = (pg)) # define MC_SET_OVPG(mc, pg) ((mc)->mc_ovpg = (pg))
@ -1450,7 +1450,7 @@ struct MDB_env {
HANDLE me_fd; /**< The main data file */ HANDLE me_fd; /**< The main data file */
HANDLE me_lfd; /**< The lock file */ HANDLE me_lfd; /**< The lock file */
HANDLE me_mfd; /**< For writing and syncing the meta pages */ HANDLE me_mfd; /**< For writing and syncing the meta pages */
#if defined(MDB_VL32) && defined(_WIN32) #if MDB_RPAGE_CACHE && defined(_WIN32)
HANDLE me_fmh; /**< File Mapping handle */ HANDLE me_fmh; /**< File Mapping handle */
#endif #endif
/** Failed to update the meta page. Probably an I/O error. */ /** Failed to update the meta page. Probably an I/O error. */
@ -1515,7 +1515,7 @@ struct MDB_env {
char me_mutexname[sizeof(MUTEXNAME_PREFIX) + 11]; char me_mutexname[sizeof(MUTEXNAME_PREFIX) + 11];
# endif # endif
#endif #endif
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
MDB_ID3L me_rpages; /**< like #mt_rpages, but global to env */ MDB_ID3L me_rpages; /**< like #mt_rpages, but global to env */
pthread_mutex_t me_rpmutex; /**< control access to #me_rpages */ pthread_mutex_t me_rpmutex; /**< control access to #me_rpages */
#define MDB_ERPAGE_SIZE 16384 #define MDB_ERPAGE_SIZE 16384
@ -2050,7 +2050,7 @@ mdb_dlist_free(MDB_txn *txn)
dl[0].mid = 0; dl[0].mid = 0;
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
static void static void
mdb_page_unref(MDB_txn *txn, MDB_page *mp) mdb_page_unref(MDB_txn *txn, MDB_page *mp)
{ {
@ -2095,7 +2095,7 @@ mdb_cursor_unref(MDB_cursor *mc)
#else #else
#define MDB_PAGE_UNREF(txn, mp) #define MDB_PAGE_UNREF(txn, mp)
#define MDB_CURSOR_UNREF(mc, force) ((void)0) #define MDB_CURSOR_UNREF(mc, force) ((void)0)
#endif /* MDB_VL32 */ #endif /* MDB_RPAGE_CACHE */
/** Loosen or free a single page. /** Loosen or free a single page.
* Saves single pages to a list for future reuse * Saves single pages to a list for future reuse
@ -2554,7 +2554,7 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp)
rc = MDB_MAP_FULL; rc = MDB_MAP_FULL;
goto fail; goto fail;
} }
#if defined(_WIN32) && !defined(MDB_VL32) #if defined(_WIN32) && !MDB_RPAGE_CACHE
if (!(env->me_flags & MDB_RDONLY)) { if (!(env->me_flags & MDB_RDONLY)) {
void *p; void *p;
p = (MDB_page *)(env->me_map + env->me_psize * pgno); p = (MDB_page *)(env->me_map + env->me_psize * pgno);
@ -3067,7 +3067,7 @@ mdb_txn_renew0(MDB_txn *txn)
/* Moved to here to avoid a data race in read TXNs */ /* Moved to here to avoid a data race in read TXNs */
txn->mt_next_pgno = meta->mm_last_pg+1; txn->mt_next_pgno = meta->mm_last_pg+1;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
txn->mt_last_pgno = txn->mt_next_pgno - 1; txn->mt_last_pgno = txn->mt_next_pgno - 1;
#endif #endif
@ -3148,7 +3148,7 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
DPRINTF(("calloc: %s", strerror(errno))); DPRINTF(("calloc: %s", strerror(errno)));
return ENOMEM; return ENOMEM;
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
if (!parent) { if (!parent) {
txn->mt_rpages = malloc(MDB_TRPAGE_SIZE * sizeof(MDB_ID3)); txn->mt_rpages = malloc(MDB_TRPAGE_SIZE * sizeof(MDB_ID3));
if (!txn->mt_rpages) { if (!txn->mt_rpages) {
@ -3186,7 +3186,7 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
parent->mt_child = txn; parent->mt_child = txn;
txn->mt_parent = parent; txn->mt_parent = parent;
txn->mt_numdbs = parent->mt_numdbs; txn->mt_numdbs = parent->mt_numdbs;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
txn->mt_rpages = parent->mt_rpages; txn->mt_rpages = parent->mt_rpages;
#endif #endif
memcpy(txn->mt_dbs, parent->mt_dbs, txn->mt_numdbs * sizeof(MDB_db)); memcpy(txn->mt_dbs, parent->mt_dbs, txn->mt_numdbs * sizeof(MDB_db));
@ -3215,7 +3215,7 @@ renew:
} }
if (rc) { if (rc) {
if (txn != env->me_txn0) { if (txn != env->me_txn0) {
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
free(txn->mt_rpages); free(txn->mt_rpages);
#endif #endif
free(txn); free(txn);
@ -3344,7 +3344,7 @@ mdb_txn_end(MDB_txn *txn, unsigned mode)
mdb_midl_free(pghead); mdb_midl_free(pghead);
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
if (!txn->mt_parent) { if (!txn->mt_parent) {
MDB_ID3L el = env->me_rpages, tl = txn->mt_rpages; MDB_ID3L el = env->me_rpages, tl = txn->mt_rpages;
unsigned i, x, n = tl[0].mid; unsigned i, x, n = tl[0].mid;
@ -3721,7 +3721,7 @@ retry_seek:
n++; n++;
#endif /* _WIN32 */ #endif /* _WIN32 */
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
if (pgno > txn->mt_last_pgno) if (pgno > txn->mt_last_pgno)
txn->mt_last_pgno = pgno; txn->mt_last_pgno = pgno;
#endif #endif
@ -4327,11 +4327,11 @@ mdb_env_map(MDB_env *env, void *addr)
if (rc) if (rc)
return mdb_nt2win32(rc); return mdb_nt2win32(rc);
map = addr; map = addr;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
msize = NUM_METAS * env->me_psize; msize = NUM_METAS * env->me_psize;
#endif #endif
rc = NtMapViewOfSection(mh, GetCurrentProcess(), &map, 0, 0, NULL, &msize, ViewUnmap, alloctype, pageprot); rc = NtMapViewOfSection(mh, GetCurrentProcess(), &map, 0, 0, NULL, &msize, ViewUnmap, alloctype, pageprot);
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
env->me_fmh = mh; env->me_fmh = mh;
#else #else
NtClose(mh); NtClose(mh);
@ -4340,7 +4340,7 @@ mdb_env_map(MDB_env *env, void *addr)
return mdb_nt2win32(rc); return mdb_nt2win32(rc);
env->me_map = map; env->me_map = map;
#else #else
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
(void) flags; (void) flags;
env->me_map = mmap(addr, NUM_METAS * env->me_psize, PROT_READ, MAP_SHARED, env->me_map = mmap(addr, NUM_METAS * env->me_psize, PROT_READ, MAP_SHARED,
env->me_fd, 0); env->me_fd, 0);
@ -4398,7 +4398,7 @@ mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
*/ */
if (env->me_map) { if (env->me_map) {
MDB_meta *meta; MDB_meta *meta;
#ifndef MDB_VL32 #if !MDB_RPAGE_CACHE
void *old; void *old;
int rc; int rc;
#endif #endif
@ -4413,8 +4413,8 @@ mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
if (size < minsize) if (size < minsize)
size = minsize; size = minsize;
} }
#ifndef MDB_VL32 #if !MDB_RPAGE_CACHE
/* For MDB_VL32 this bit is a noop since we dynamically remap /* For MDB_RPAGE_CACHE this bit is a noop since we dynamically remap
* chunks of the DB anyway. * chunks of the DB anyway.
*/ */
munmap(env->me_map, env->me_mapsize); munmap(env->me_map, env->me_mapsize);
@ -4423,7 +4423,7 @@ mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
rc = mdb_env_map(env, old); rc = mdb_env_map(env, old);
if (rc) if (rc)
return rc; return rc;
#endif /* !MDB_VL32 */ #endif /* !MDB_RPAGE_CACHE */
} }
env->me_mapsize = size; env->me_mapsize = size;
if (env->me_psize) if (env->me_psize)
@ -5347,9 +5347,9 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS))) if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS)))
return EINVAL; return EINVAL;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
if (flags & MDB_WRITEMAP) { if (flags & MDB_WRITEMAP) {
/* silently ignore WRITEMAP in 32 bit mode */ /* silently ignore WRITEMAP with RPAGE_CACHE */
flags ^= MDB_WRITEMAP; flags ^= MDB_WRITEMAP;
} }
if (flags & MDB_FIXEDMAP) { if (flags & MDB_FIXEDMAP) {
@ -5363,7 +5363,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
if (rc) if (rc)
return rc; return rc;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
#ifdef _WIN32 #ifdef _WIN32
env->me_rpmutex = CreateMutex(NULL, FALSE, NULL); env->me_rpmutex = CreateMutex(NULL, FALSE, NULL);
if (!env->me_rpmutex) { if (!env->me_rpmutex) {
@ -5391,7 +5391,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
if (rc) if (rc)
goto leave; goto leave;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
{ {
env->me_rpages = malloc(MDB_ERPAGE_SIZE * sizeof(MDB_ID3)); env->me_rpages = malloc(MDB_ERPAGE_SIZE * sizeof(MDB_ID3));
if (!env->me_rpages) { if (!env->me_rpages) {
@ -5459,7 +5459,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs); txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs);
txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs); txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs);
txn->mt_env = env; txn->mt_env = env;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
txn->mt_rpages = malloc(MDB_TRPAGE_SIZE * sizeof(MDB_ID3)); txn->mt_rpages = malloc(MDB_TRPAGE_SIZE * sizeof(MDB_ID3));
if (!txn->mt_rpages) { if (!txn->mt_rpages) {
free(txn); free(txn);
@ -5507,7 +5507,7 @@ mdb_env_close0(MDB_env *env, int excl)
free(env->me_dbflags); free(env->me_dbflags);
free(env->me_path); free(env->me_path);
free(env->me_dirty_list); free(env->me_dirty_list);
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
if (env->me_txn0 && env->me_txn0->mt_rpages) if (env->me_txn0 && env->me_txn0->mt_rpages)
free(env->me_txn0->mt_rpages); free(env->me_txn0->mt_rpages);
if (env->me_rpages) { if (env->me_rpages) {
@ -5535,7 +5535,7 @@ mdb_env_close0(MDB_env *env, int excl)
} }
if (env->me_map) { if (env->me_map) {
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
munmap(env->me_map, NUM_METAS*env->me_psize); munmap(env->me_map, NUM_METAS*env->me_psize);
#else #else
munmap(env->me_map, env->me_mapsize); munmap(env->me_map, env->me_mapsize);
@ -5604,7 +5604,7 @@ mdb_env_close0(MDB_env *env, int excl)
#endif #endif
(void) close(env->me_lfd); (void) close(env->me_lfd);
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
#ifdef _WIN32 #ifdef _WIN32
if (env->me_fmh) CloseHandle(env->me_fmh); if (env->me_fmh) CloseHandle(env->me_fmh);
if (env->me_rpmutex) CloseHandle(env->me_rpmutex); if (env->me_rpmutex) CloseHandle(env->me_rpmutex);
@ -5880,7 +5880,7 @@ mdb_cursor_push(MDB_cursor *mc, MDB_page *mp)
return MDB_SUCCESS; return MDB_SUCCESS;
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
/** Map a read-only page. /** Map a read-only page.
* There are two levels of tracking in use, a per-txn list and a per-env list. * There are two levels of tracking in use, a per-txn list and a per-env list.
* ref'ing and unref'ing the per-txn list is faster since it requires no * ref'ing and unref'ing the per-txn list is faster since it requires no
@ -6222,7 +6222,7 @@ mdb_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **ret, int *lvl)
mapped: mapped:
{ {
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
int rc = mdb_rpage_get(txn, pgno, &p); int rc = mdb_rpage_get(txn, pgno, &p);
if (rc) { if (rc) {
txn->mt_flags |= MDB_TXN_ERROR; txn->mt_flags |= MDB_TXN_ERROR;
@ -6413,7 +6413,7 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags)
mdb_cassert(mc, root > 1); mdb_cassert(mc, root > 1);
if (!mc->mc_pg[0] || mc->mc_pg[0]->mp_pgno != root) { if (!mc->mc_pg[0] || mc->mc_pg[0]->mp_pgno != root) {
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
if (mc->mc_pg[0]) if (mc->mc_pg[0])
MDB_PAGE_UNREF(mc->mc_txn, mc->mc_pg[0]); MDB_PAGE_UNREF(mc->mc_txn, mc->mc_pg[0]);
#endif #endif
@ -6421,7 +6421,7 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags)
return rc; return rc;
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
{ {
int i; int i;
for (i=1; i<mc->mc_snum; i++) for (i=1; i<mc->mc_snum; i++)
@ -6577,7 +6577,7 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi,
mdb_cursor_init(&mc, txn, dbi, &mx); mdb_cursor_init(&mc, txn, dbi, &mx);
rc = mdb_cursor_set(&mc, key, data, MDB_SET, &exact); rc = mdb_cursor_set(&mc, key, data, MDB_SET, &exact);
/* unref all the pages when MDB_VL32 - caller must copy the data /* unref all the pages when MDB_RPAGE_CACHE - caller must copy the data
* before doing anything else * before doing anything else
*/ */
MDB_CURSOR_UNREF(&mc, 1); MDB_CURSOR_UNREF(&mc, 1);
@ -6598,7 +6598,7 @@ mdb_cursor_sibling(MDB_cursor *mc, int move_right)
int rc; int rc;
MDB_node *indx; MDB_node *indx;
MDB_page *mp; MDB_page *mp;
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
MDB_page *op; MDB_page *op;
#endif #endif
@ -6606,7 +6606,7 @@ mdb_cursor_sibling(MDB_cursor *mc, int move_right)
return MDB_NOTFOUND; /* root has no siblings */ return MDB_NOTFOUND; /* root has no siblings */
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
op = mc->mc_pg[mc->mc_top]; op = mc->mc_pg[mc->mc_top];
#endif #endif
mdb_cursor_pop(mc); mdb_cursor_pop(mc);
@ -10723,7 +10723,7 @@ mdb_drop0(MDB_cursor *mc, int subs)
mdb_cursor_pop(mc); mdb_cursor_pop(mc);
mdb_cursor_copy(mc, &mx); mdb_cursor_copy(mc, &mx);
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
/* bump refcount for mx's pages */ /* bump refcount for mx's pages */
for (i=0; i<mc->mc_snum; i++) for (i=0; i<mc->mc_snum; i++)
mdb_page_get(&mx, mc->mc_pg[i]->mp_pgno, &mx.mc_pg[i], NULL); mdb_page_get(&mx, mc->mc_pg[i]->mp_pgno, &mx.mc_pg[i], NULL);

@ -355,7 +355,7 @@ int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id )
return 0; return 0;
} }
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
unsigned mdb_mid3l_search( MDB_ID3L ids, MDB_ID id ) unsigned mdb_mid3l_search( MDB_ID3L ids, MDB_ID id )
{ {
/* /*
@ -415,7 +415,7 @@ int mdb_mid3l_insert( MDB_ID3L ids, MDB_ID3 *id )
return 0; return 0;
} }
#endif /* MDB_VL32 */ #endif /* MDB_RPAGE_CACHE */
/** @} */ /** @} */
/** @} */ /** @} */

@ -178,7 +178,7 @@ int mdb_mid2l_insert( MDB_ID2L ids, MDB_ID2 *id );
*/ */
int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id ); int mdb_mid2l_append( MDB_ID2L ids, MDB_ID2 *id );
#ifdef MDB_VL32 #if MDB_RPAGE_CACHE
typedef struct MDB_ID3 { typedef struct MDB_ID3 {
MDB_ID mid; /**< The ID */ MDB_ID mid; /**< The ID */
void *mptr; /**< The pointer */ void *mptr; /**< The pointer */
@ -191,7 +191,7 @@ typedef MDB_ID3 *MDB_ID3L;
unsigned mdb_mid3l_search( MDB_ID3L ids, MDB_ID id ); unsigned mdb_mid3l_search( MDB_ID3L ids, MDB_ID id );
int mdb_mid3l_insert( MDB_ID3L ids, MDB_ID3 *id ); int mdb_mid3l_insert( MDB_ID3L ids, MDB_ID3 *id );
#endif /* MDB_VL32 */ #endif /* MDB_RPAGE_CACHE */
/** @} */ /** @} */
/** @} */ /** @} */
#ifdef __cplusplus #ifdef __cplusplus

Loading…
Cancel
Save