updated in-source lmdb
This commit is contained in:
parent
ea08c768e2
commit
e6ab2dfdf3
|
@ -1,18 +1,31 @@
|
||||||
LMDB 0.9 Change Log
|
LMDB 0.9 Change Log
|
||||||
|
|
||||||
LMDB 0.9.15 Release Engineering
|
LMDB 0.9.15 Release (2015/06/19)
|
||||||
Fix txn init (ITS#7961,#7987)
|
Fix txn init (ITS#7961,#7987)
|
||||||
Fix MDB_PREV_DUP (ITS#7955,#7671)
|
Fix MDB_PREV_DUP (ITS#7955,#7671)
|
||||||
Fix compact of empty env (ITS#7956)
|
Fix compact of empty env (ITS#7956)
|
||||||
|
Fix mdb_copy file mode
|
||||||
|
Fix mdb_env_close() after failed mdb_env_open()
|
||||||
|
Fix mdb_rebalance collapsing root (ITS#8062)
|
||||||
Fix mdb_load with large values (ITS#8066)
|
Fix mdb_load with large values (ITS#8066)
|
||||||
|
Fix to retry writes on EINTR (ITS#8106)
|
||||||
|
Fix mdb_cursor_del on empty DB (ITS#8109)
|
||||||
|
Fix MDB_INTEGERDUP key compare (ITS#8117)
|
||||||
|
Fix error handling (ITS#7959,#8157,etc.)
|
||||||
|
Fix race conditions (ITS#7969,7970)
|
||||||
Added workaround for fdatasync bug in ext3fs
|
Added workaround for fdatasync bug in ext3fs
|
||||||
Build
|
Build
|
||||||
Don't use -fPIC for static lib
|
Don't use -fPIC for static lib
|
||||||
Update .gitignore (ITS#7952,#7953)
|
Update .gitignore (ITS#7952,#7953)
|
||||||
Cleanup for "make test" (ITS#7841)
|
Cleanup for "make test" (ITS#7841), "make clean", mtest*.c
|
||||||
Misc. Android/Windows cleanup
|
Misc. Android/Windows cleanup
|
||||||
Documentation
|
Documentation
|
||||||
Fix MDB_APPEND doc
|
Fix MDB_APPEND doc
|
||||||
|
Fix MDB_MAXKEYSIZE doc (ITS#8156)
|
||||||
|
Fix mdb_cursor_put,mdb_cursor_del EACCES description
|
||||||
|
Fix mdb_env_sync(MDB_RDONLY env) doc (ITS#8021)
|
||||||
|
Clarify MDB_WRITEMAP doc (ITS#8021)
|
||||||
|
Clarify mdb_env_open doc
|
||||||
Clarify mdb_dbi_open doc
|
Clarify mdb_dbi_open doc
|
||||||
|
|
||||||
LMDB 0.9.14 Release (2014/09/20)
|
LMDB 0.9.14 Release (2014/09/20)
|
||||||
|
|
|
@ -184,7 +184,7 @@ typedef int mdb_filehandle_t;
|
||||||
/** Library minor version */
|
/** Library minor version */
|
||||||
#define MDB_VERSION_MINOR 9
|
#define MDB_VERSION_MINOR 9
|
||||||
/** Library patch version */
|
/** Library patch version */
|
||||||
#define MDB_VERSION_PATCH 14
|
#define MDB_VERSION_PATCH 15
|
||||||
|
|
||||||
/** Combine args a,b,c into a single integer for easy version comparisons */
|
/** Combine args a,b,c into a single integer for easy version comparisons */
|
||||||
#define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c))
|
#define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c))
|
||||||
|
@ -194,7 +194,7 @@ typedef int mdb_filehandle_t;
|
||||||
MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH)
|
MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH)
|
||||||
|
|
||||||
/** The release date of this library version */
|
/** The release date of this library version */
|
||||||
#define MDB_VERSION_DATE "September 20, 2014"
|
#define MDB_VERSION_DATE "June 19, 2015"
|
||||||
|
|
||||||
/** A stringifier for the version info */
|
/** A stringifier for the version info */
|
||||||
#define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"
|
#define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"
|
||||||
|
@ -296,12 +296,12 @@ typedef void (MDB_rel_func)(MDB_val *item, void *oldptr, void *newptr, void *rel
|
||||||
#define MDB_REVERSEKEY 0x02
|
#define MDB_REVERSEKEY 0x02
|
||||||
/** use sorted duplicates */
|
/** use sorted duplicates */
|
||||||
#define MDB_DUPSORT 0x04
|
#define MDB_DUPSORT 0x04
|
||||||
/** numeric keys in native byte order.
|
/** numeric keys in native byte order: either unsigned int or size_t.
|
||||||
* The keys must all be of the same size. */
|
* The keys must all be of the same size. */
|
||||||
#define MDB_INTEGERKEY 0x08
|
#define MDB_INTEGERKEY 0x08
|
||||||
/** with #MDB_DUPSORT, sorted dup items have fixed size */
|
/** with #MDB_DUPSORT, sorted dup items have fixed size */
|
||||||
#define MDB_DUPFIXED 0x10
|
#define MDB_DUPFIXED 0x10
|
||||||
/** with #MDB_DUPSORT, dups are numeric in native byte order */
|
/** with #MDB_DUPSORT, dups are #MDB_INTEGERKEY-style integers */
|
||||||
#define MDB_INTEGERDUP 0x20
|
#define MDB_INTEGERDUP 0x20
|
||||||
/** with #MDB_DUPSORT, use reverse string dups */
|
/** with #MDB_DUPSORT, use reverse string dups */
|
||||||
#define MDB_REVERSEDUP 0x40
|
#define MDB_REVERSEDUP 0x40
|
||||||
|
@ -588,8 +588,8 @@ int mdb_env_create(MDB_env **env);
|
||||||
* reserved in that case.
|
* reserved in that case.
|
||||||
* This flag may be changed at any time using #mdb_env_set_flags().
|
* This flag may be changed at any time using #mdb_env_set_flags().
|
||||||
* </ul>
|
* </ul>
|
||||||
* @param[in] mode The UNIX permissions to set on created files. This parameter
|
* @param[in] mode The UNIX permissions to set on created files and semaphores.
|
||||||
* is ignored on Windows.
|
* This parameter is ignored on Windows.
|
||||||
* @return A non-zero error value on failure and 0 on success. Some possible
|
* @return A non-zero error value on failure and 0 on success. Some possible
|
||||||
* errors are:
|
* errors are:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
@ -1021,14 +1021,16 @@ int mdb_txn_renew(MDB_txn *txn);
|
||||||
* The database handle may be discarded by calling #mdb_dbi_close().
|
* The database handle may be discarded by calling #mdb_dbi_close().
|
||||||
* The old database handle is returned if the database was already open.
|
* The old database handle is returned if the database was already open.
|
||||||
* The handle may only be closed once.
|
* The handle may only be closed once.
|
||||||
|
*
|
||||||
* The database handle will be private to the current transaction until
|
* The database handle will be private to the current transaction until
|
||||||
* the transaction is successfully committed. If the transaction is
|
* the transaction is successfully committed. If the transaction is
|
||||||
* aborted the handle will be closed automatically.
|
* aborted the handle will be closed automatically.
|
||||||
* After a successful commit the
|
* After a successful commit the handle will reside in the shared
|
||||||
* handle will reside in the shared environment, and may be used
|
* environment, and may be used by other transactions.
|
||||||
* by other transactions. This function must not be called from
|
*
|
||||||
* multiple concurrent transactions in the same process. A transaction
|
* This function must not be called from multiple concurrent
|
||||||
* that uses this function must finish (either commit or abort) before
|
* transactions in the same process. A transaction that uses
|
||||||
|
* this function must finish (either commit or abort) before
|
||||||
* any other transaction in the process may use this function.
|
* any other transaction in the process may use this function.
|
||||||
*
|
*
|
||||||
* To use named databases (with name != NULL), #mdb_env_set_maxdbs()
|
* To use named databases (with name != NULL), #mdb_env_set_maxdbs()
|
||||||
|
@ -1050,9 +1052,9 @@ int mdb_txn_renew(MDB_txn *txn);
|
||||||
* keys may have multiple data items, stored in sorted order.) By default
|
* keys may have multiple data items, stored in sorted order.) By default
|
||||||
* keys must be unique and may have only a single data item.
|
* keys must be unique and may have only a single data item.
|
||||||
* <li>#MDB_INTEGERKEY
|
* <li>#MDB_INTEGERKEY
|
||||||
* Keys are binary integers in native byte order. Setting this option
|
* Keys are binary integers in native byte order, either unsigned int
|
||||||
* requires all keys to be the same size, typically sizeof(int)
|
* or size_t, and will be sorted as such.
|
||||||
* or sizeof(size_t).
|
* The keys must all be of the same size.
|
||||||
* <li>#MDB_DUPFIXED
|
* <li>#MDB_DUPFIXED
|
||||||
* This flag may only be used in combination with #MDB_DUPSORT. This option
|
* This flag may only be used in combination with #MDB_DUPSORT. This option
|
||||||
* tells the library that the data items for this database are all the same
|
* tells the library that the data items for this database are all the same
|
||||||
|
@ -1060,8 +1062,8 @@ int mdb_txn_renew(MDB_txn *txn);
|
||||||
* all data items are the same size, the #MDB_GET_MULTIPLE and #MDB_NEXT_MULTIPLE
|
* all data items are the same size, the #MDB_GET_MULTIPLE and #MDB_NEXT_MULTIPLE
|
||||||
* cursor operations may be used to retrieve multiple items at once.
|
* cursor operations may be used to retrieve multiple items at once.
|
||||||
* <li>#MDB_INTEGERDUP
|
* <li>#MDB_INTEGERDUP
|
||||||
* This option specifies that duplicate data items are also integers, and
|
* This option specifies that duplicate data items are binary integers,
|
||||||
* should be sorted as such.
|
* similar to #MDB_INTEGERKEY keys.
|
||||||
* <li>#MDB_REVERSEDUP
|
* <li>#MDB_REVERSEDUP
|
||||||
* This option specifies that duplicate data items should be compared as
|
* This option specifies that duplicate data items should be compared as
|
||||||
* strings in reverse order.
|
* strings in reverse order.
|
||||||
|
@ -1450,7 +1452,7 @@ int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>#MDB_MAP_FULL - the database is full, see #mdb_env_set_mapsize().
|
* <li>#MDB_MAP_FULL - the database is full, see #mdb_env_set_mapsize().
|
||||||
* <li>#MDB_TXN_FULL - the transaction has too many dirty pages.
|
* <li>#MDB_TXN_FULL - the transaction has too many dirty pages.
|
||||||
* <li>EACCES - an attempt was made to modify a read-only database.
|
* <li>EACCES - an attempt was made to write in a read-only transaction.
|
||||||
* <li>EINVAL - an invalid parameter was specified.
|
* <li>EINVAL - an invalid parameter was specified.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
|
@ -1470,7 +1472,7 @@ int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data,
|
||||||
* @return A non-zero error value on failure and 0 on success. Some possible
|
* @return A non-zero error value on failure and 0 on success. Some possible
|
||||||
* errors are:
|
* errors are:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>EACCES - an attempt was made to modify a read-only database.
|
* <li>EACCES - an attempt was made to write in a read-only transaction.
|
||||||
* <li>EINVAL - an invalid parameter was specified.
|
* <li>EINVAL - an invalid parameter was specified.
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -446,12 +446,17 @@ static txnid_t mdb_debug_start;
|
||||||
/** The version number for a database's lockfile format. */
|
/** The version number for a database's lockfile format. */
|
||||||
#define MDB_LOCK_VERSION 1
|
#define MDB_LOCK_VERSION 1
|
||||||
|
|
||||||
/** @brief The max size of a key we can write, or 0 for dynamic max.
|
/** @brief The max size of a key we can write, or 0 for computed max.
|
||||||
*
|
*
|
||||||
* Define this as 0 to compute the max from the page size. 511
|
* This macro should normally be left alone or set to 0.
|
||||||
* is default for backwards compat: liblmdb <= 0.9.10 can break
|
* Note that a database with big keys or dupsort data cannot be
|
||||||
* when modifying a DB with keys/dupsort data bigger than its max.
|
* reliably modified by a liblmdb which uses a smaller max.
|
||||||
* #MDB_DEVEL sets the default to 0.
|
* The default is 511 for backwards compat, or 0 when #MDB_DEVEL.
|
||||||
|
*
|
||||||
|
* Other values are allowed, for backwards compat. However:
|
||||||
|
* A value bigger than the computed max can break if you do not
|
||||||
|
* know what you are doing, and liblmdb <= 0.9.10 can break when
|
||||||
|
* modifying a DB with keys/dupsort data bigger than its max.
|
||||||
*
|
*
|
||||||
* Data items in an #MDB_DUPSORT database are also limited to
|
* Data items in an #MDB_DUPSORT database are also limited to
|
||||||
* this size, since they're actually keys of a sub-DB. Keys and
|
* this size, since they're actually keys of a sub-DB. Keys and
|
||||||
|
@ -1245,6 +1250,13 @@ static void mdb_default_cmp(MDB_txn *txn, MDB_dbi dbi);
|
||||||
static MDB_cmp_func mdb_cmp_memn, mdb_cmp_memnr, mdb_cmp_int, mdb_cmp_cint, mdb_cmp_long;
|
static MDB_cmp_func mdb_cmp_memn, mdb_cmp_memnr, mdb_cmp_int, mdb_cmp_cint, mdb_cmp_long;
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
|
|
||||||
|
/** Compare two items pointing at size_t's of unknown alignment. */
|
||||||
|
#ifdef MISALIGNED_OK
|
||||||
|
# define mdb_cmp_clong mdb_cmp_long
|
||||||
|
#else
|
||||||
|
# define mdb_cmp_clong mdb_cmp_cint
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static SECURITY_DESCRIPTOR mdb_null_sd;
|
static SECURITY_DESCRIPTOR mdb_null_sd;
|
||||||
static SECURITY_ATTRIBUTES mdb_all_sa;
|
static SECURITY_ATTRIBUTES mdb_all_sa;
|
||||||
|
@ -1558,7 +1570,12 @@ mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
|
||||||
int
|
int
|
||||||
mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
|
mdb_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b)
|
||||||
{
|
{
|
||||||
return txn->mt_dbxs[dbi].md_dcmp(a, b);
|
MDB_cmp_func *dcmp = txn->mt_dbxs[dbi].md_dcmp;
|
||||||
|
#if UINT_MAX < SIZE_MAX
|
||||||
|
if (dcmp == mdb_cmp_int && a->mv_size == sizeof(size_t))
|
||||||
|
dcmp = mdb_cmp_clong;
|
||||||
|
#endif
|
||||||
|
return dcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Allocate memory for a page.
|
/** Allocate memory for a page.
|
||||||
|
@ -2486,14 +2503,11 @@ mdb_txn_renew0(MDB_txn *txn)
|
||||||
MDB_env *env = txn->mt_env;
|
MDB_env *env = txn->mt_env;
|
||||||
MDB_txninfo *ti = env->me_txns;
|
MDB_txninfo *ti = env->me_txns;
|
||||||
MDB_meta *meta;
|
MDB_meta *meta;
|
||||||
unsigned int i, nr;
|
unsigned int i, nr, flags = txn->mt_flags;
|
||||||
uint16_t x;
|
uint16_t x;
|
||||||
int rc, new_notls = 0;
|
int rc, new_notls = 0;
|
||||||
|
|
||||||
if (txn->mt_flags & MDB_TXN_RDONLY) {
|
if ((flags &= MDB_TXN_RDONLY) != 0) {
|
||||||
/* Setup db info */
|
|
||||||
txn->mt_numdbs = env->me_numdbs;
|
|
||||||
txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */
|
|
||||||
if (!ti) {
|
if (!ti) {
|
||||||
meta = env->me_metas[ mdb_env_pick_meta(env) ];
|
meta = env->me_metas[ mdb_env_pick_meta(env) ];
|
||||||
txn->mt_txnid = meta->mm_txnid;
|
txn->mt_txnid = meta->mm_txnid;
|
||||||
|
@ -2546,6 +2560,7 @@ mdb_txn_renew0(MDB_txn *txn)
|
||||||
txn->mt_u.reader = r;
|
txn->mt_u.reader = r;
|
||||||
meta = env->me_metas[txn->mt_txnid & 1];
|
meta = env->me_metas[txn->mt_txnid & 1];
|
||||||
}
|
}
|
||||||
|
txn->mt_dbxs = env->me_dbxs; /* mostly static anyway */
|
||||||
} else {
|
} else {
|
||||||
if (ti) {
|
if (ti) {
|
||||||
LOCK_MUTEX_W(env);
|
LOCK_MUTEX_W(env);
|
||||||
|
@ -2556,14 +2571,11 @@ mdb_txn_renew0(MDB_txn *txn)
|
||||||
meta = env->me_metas[ mdb_env_pick_meta(env) ];
|
meta = env->me_metas[ mdb_env_pick_meta(env) ];
|
||||||
txn->mt_txnid = meta->mm_txnid;
|
txn->mt_txnid = meta->mm_txnid;
|
||||||
}
|
}
|
||||||
/* Setup db info */
|
|
||||||
txn->mt_numdbs = env->me_numdbs;
|
|
||||||
txn->mt_txnid++;
|
txn->mt_txnid++;
|
||||||
#if MDB_DEBUG
|
#if MDB_DEBUG
|
||||||
if (txn->mt_txnid == mdb_debug_start)
|
if (txn->mt_txnid == mdb_debug_start)
|
||||||
mdb_debug = 1;
|
mdb_debug = 1;
|
||||||
#endif
|
#endif
|
||||||
txn->mt_flags = 0;
|
|
||||||
txn->mt_child = NULL;
|
txn->mt_child = NULL;
|
||||||
txn->mt_loose_pgs = NULL;
|
txn->mt_loose_pgs = NULL;
|
||||||
txn->mt_loose_count = 0;
|
txn->mt_loose_count = 0;
|
||||||
|
@ -2583,6 +2595,10 @@ 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;
|
||||||
|
|
||||||
|
txn->mt_flags = flags;
|
||||||
|
|
||||||
|
/* Setup db info */
|
||||||
|
txn->mt_numdbs = env->me_numdbs;
|
||||||
for (i=2; i<txn->mt_numdbs; i++) {
|
for (i=2; i<txn->mt_numdbs; i++) {
|
||||||
x = env->me_dbflags[i];
|
x = env->me_dbflags[i];
|
||||||
txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS;
|
txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS;
|
||||||
|
@ -3132,6 +3148,7 @@ mdb_page_flush(MDB_txn *txn, int keep)
|
||||||
/* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
|
/* Write up to MDB_COMMIT_PAGES dirty pages at a time. */
|
||||||
if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) {
|
if (pos!=next_pos || n==MDB_COMMIT_PAGES || wsize+size>MAX_WRITE) {
|
||||||
if (n) {
|
if (n) {
|
||||||
|
retry_write:
|
||||||
/* Write previous page(s) */
|
/* Write previous page(s) */
|
||||||
#ifdef MDB_USE_PWRITEV
|
#ifdef MDB_USE_PWRITEV
|
||||||
wres = pwritev(env->me_fd, iov, n, wpos);
|
wres = pwritev(env->me_fd, iov, n, wpos);
|
||||||
|
@ -3139,8 +3156,11 @@ mdb_page_flush(MDB_txn *txn, int keep)
|
||||||
if (n == 1) {
|
if (n == 1) {
|
||||||
wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos);
|
wres = pwrite(env->me_fd, iov[0].iov_base, wsize, wpos);
|
||||||
} else {
|
} else {
|
||||||
|
retry_seek:
|
||||||
if (lseek(env->me_fd, wpos, SEEK_SET) == -1) {
|
if (lseek(env->me_fd, wpos, SEEK_SET) == -1) {
|
||||||
rc = ErrCode();
|
rc = ErrCode();
|
||||||
|
if (rc == EINTR)
|
||||||
|
goto retry_seek;
|
||||||
DPRINTF(("lseek: %s", strerror(rc)));
|
DPRINTF(("lseek: %s", strerror(rc)));
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -3150,6 +3170,8 @@ mdb_page_flush(MDB_txn *txn, int keep)
|
||||||
if (wres != wsize) {
|
if (wres != wsize) {
|
||||||
if (wres < 0) {
|
if (wres < 0) {
|
||||||
rc = ErrCode();
|
rc = ErrCode();
|
||||||
|
if (rc == EINTR)
|
||||||
|
goto retry_write;
|
||||||
DPRINTF(("Write error: %s", strerror(rc)));
|
DPRINTF(("Write error: %s", strerror(rc)));
|
||||||
} else {
|
} else {
|
||||||
rc = EIO; /* TODO: Use which error code? */
|
rc = EIO; /* TODO: Use which error code? */
|
||||||
|
@ -3519,7 +3541,8 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
|
||||||
int len;
|
int len;
|
||||||
#define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \
|
#define DO_PWRITE(rc, fd, ptr, size, len, pos) do { \
|
||||||
len = pwrite(fd, ptr, size, pos); \
|
len = pwrite(fd, ptr, size, pos); \
|
||||||
rc = (len >= 0); } while(0)
|
if (len == -1 && ErrCode() == EINTR) continue; \
|
||||||
|
rc = (len >= 0); break; } while(1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DPUTS("writing new meta page");
|
DPUTS("writing new meta page");
|
||||||
|
@ -3624,6 +3647,7 @@ mdb_env_write_meta(MDB_txn *txn)
|
||||||
/* Write to the SYNC fd */
|
/* Write to the SYNC fd */
|
||||||
mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
|
mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
|
||||||
env->me_fd : env->me_mfd;
|
env->me_fd : env->me_mfd;
|
||||||
|
retry_write:
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
{
|
{
|
||||||
memset(&ov, 0, sizeof(ov));
|
memset(&ov, 0, sizeof(ov));
|
||||||
|
@ -3636,6 +3660,8 @@ mdb_env_write_meta(MDB_txn *txn)
|
||||||
#endif
|
#endif
|
||||||
if (rc != len) {
|
if (rc != len) {
|
||||||
rc = rc < 0 ? ErrCode() : EIO;
|
rc = rc < 0 ? ErrCode() : EIO;
|
||||||
|
if (rc == EINTR)
|
||||||
|
goto retry_write;
|
||||||
DPUTS("write failed, disk error?");
|
DPUTS("write failed, disk error?");
|
||||||
/* On a failure, the pagecache still contains the new data.
|
/* On a failure, the pagecache still contains the new data.
|
||||||
* Write some old data back, to prevent it from being used.
|
* Write some old data back, to prevent it from being used.
|
||||||
|
@ -4761,7 +4787,11 @@ mdb_cmp_long(const MDB_val *a, const MDB_val *b)
|
||||||
*(size_t *)a->mv_data > *(size_t *)b->mv_data;
|
*(size_t *)a->mv_data > *(size_t *)b->mv_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compare two items pointing at aligned unsigned int's */
|
/** Compare two items pointing at aligned unsigned int's.
|
||||||
|
*
|
||||||
|
* This is also set as #MDB_INTEGERDUP|#MDB_DUPFIXED's #MDB_dbx.%md_dcmp,
|
||||||
|
* but #mdb_cmp_clong() is called instead if the data type is size_t.
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
mdb_cmp_int(const MDB_val *a, const MDB_val *b)
|
mdb_cmp_int(const MDB_val *a, const MDB_val *b)
|
||||||
{
|
{
|
||||||
|
@ -4799,13 +4829,6 @@ mdb_cmp_cint(const MDB_val *a, const MDB_val *b)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compare two items pointing at size_t's of unknown alignment. */
|
|
||||||
#ifdef MISALIGNED_OK
|
|
||||||
# define mdb_cmp_clong mdb_cmp_long
|
|
||||||
#else
|
|
||||||
# define mdb_cmp_clong mdb_cmp_cint
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Compare two items lexically */
|
/** Compare two items lexically */
|
||||||
static int
|
static int
|
||||||
mdb_cmp_memn(const MDB_val *a, const MDB_val *b)
|
mdb_cmp_memn(const MDB_val *a, const MDB_val *b)
|
||||||
|
@ -5741,15 +5764,21 @@ set1:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else if (op == MDB_GET_BOTH || op == MDB_GET_BOTH_RANGE) {
|
} else if (op == MDB_GET_BOTH || op == MDB_GET_BOTH_RANGE) {
|
||||||
MDB_val d2;
|
MDB_val olddata;
|
||||||
if ((rc = mdb_node_read(mc->mc_txn, leaf, &d2)) != MDB_SUCCESS)
|
MDB_cmp_func *dcmp;
|
||||||
|
if ((rc = mdb_node_read(mc->mc_txn, leaf, &olddata)) != MDB_SUCCESS)
|
||||||
return rc;
|
return rc;
|
||||||
rc = mc->mc_dbx->md_dcmp(data, &d2);
|
dcmp = mc->mc_dbx->md_dcmp;
|
||||||
|
#if UINT_MAX < SIZE_MAX
|
||||||
|
if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
|
||||||
|
dcmp = mdb_cmp_clong;
|
||||||
|
#endif
|
||||||
|
rc = dcmp(data, &olddata);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
if (op == MDB_GET_BOTH || rc > 0)
|
if (op == MDB_GET_BOTH || rc > 0)
|
||||||
return MDB_NOTFOUND;
|
return MDB_NOTFOUND;
|
||||||
rc = 0;
|
rc = 0;
|
||||||
*data = d2;
|
*data = olddata;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -6259,16 +6288,17 @@ more:
|
||||||
|
|
||||||
/* Was a single item before, must convert now */
|
/* Was a single item before, must convert now */
|
||||||
if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
|
if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
|
||||||
|
MDB_cmp_func *dcmp;
|
||||||
/* Just overwrite the current item */
|
/* Just overwrite the current item */
|
||||||
if (flags == MDB_CURRENT)
|
if (flags == MDB_CURRENT)
|
||||||
goto current;
|
goto current;
|
||||||
|
dcmp = mc->mc_dbx->md_dcmp;
|
||||||
#if UINT_MAX < SIZE_MAX
|
#if UINT_MAX < SIZE_MAX
|
||||||
if (mc->mc_dbx->md_dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
|
if (dcmp == mdb_cmp_int && olddata.mv_size == sizeof(size_t))
|
||||||
mc->mc_dbx->md_dcmp = mdb_cmp_clong;
|
dcmp = mdb_cmp_clong;
|
||||||
#endif
|
#endif
|
||||||
/* does data match? */
|
/* does data match? */
|
||||||
if (!mc->mc_dbx->md_dcmp(data, &olddata)) {
|
if (!dcmp(data, &olddata)) {
|
||||||
if (flags & MDB_NODUPDATA)
|
if (flags & MDB_NODUPDATA)
|
||||||
return MDB_KEYEXIST;
|
return MDB_KEYEXIST;
|
||||||
/* overwrite it */
|
/* overwrite it */
|
||||||
|
@ -7088,6 +7118,7 @@ mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx)
|
||||||
mc->mc_snum = 0;
|
mc->mc_snum = 0;
|
||||||
mc->mc_top = 0;
|
mc->mc_top = 0;
|
||||||
mc->mc_pg[0] = 0;
|
mc->mc_pg[0] = 0;
|
||||||
|
mc->mc_ki[0] = 0;
|
||||||
mc->mc_flags = 0;
|
mc->mc_flags = 0;
|
||||||
if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
|
if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
|
||||||
mdb_tassert(txn, mx != NULL);
|
mdb_tassert(txn, mx != NULL);
|
||||||
|
@ -7717,12 +7748,12 @@ mdb_rebalance(MDB_cursor *mc)
|
||||||
m3 = m2;
|
m3 = m2;
|
||||||
if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
|
if (m3 == mc || m3->mc_snum < mc->mc_snum) continue;
|
||||||
if (m3->mc_pg[0] == mp) {
|
if (m3->mc_pg[0] == mp) {
|
||||||
m3->mc_snum--;
|
|
||||||
m3->mc_top--;
|
|
||||||
for (i=0; i<m3->mc_snum; i++) {
|
for (i=0; i<m3->mc_snum; i++) {
|
||||||
m3->mc_pg[i] = m3->mc_pg[i+1];
|
m3->mc_pg[i] = m3->mc_pg[i+1];
|
||||||
m3->mc_ki[i] = m3->mc_ki[i+1];
|
m3->mc_ki[i] = m3->mc_ki[i+1];
|
||||||
}
|
}
|
||||||
|
m3->mc_snum--;
|
||||||
|
m3->mc_top--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7790,9 +7821,23 @@ mdb_rebalance(MDB_cursor *mc)
|
||||||
if (mc->mc_ki[ptop] == 0) {
|
if (mc->mc_ki[ptop] == 0) {
|
||||||
rc = mdb_page_merge(&mn, mc);
|
rc = mdb_page_merge(&mn, mc);
|
||||||
} else {
|
} else {
|
||||||
|
MDB_cursor dummy;
|
||||||
oldki += NUMKEYS(mn.mc_pg[mn.mc_top]);
|
oldki += NUMKEYS(mn.mc_pg[mn.mc_top]);
|
||||||
mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1;
|
mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1;
|
||||||
|
/* We want mdb_rebalance to find mn when doing fixups */
|
||||||
|
if (mc->mc_flags & C_SUB) {
|
||||||
|
dummy.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi];
|
||||||
|
mc->mc_txn->mt_cursors[mc->mc_dbi] = &dummy;
|
||||||
|
dummy.mc_xcursor = (MDB_xcursor *)&mn;
|
||||||
|
} else {
|
||||||
|
mn.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi];
|
||||||
|
mc->mc_txn->mt_cursors[mc->mc_dbi] = &mn;
|
||||||
|
}
|
||||||
rc = mdb_page_merge(mc, &mn);
|
rc = mdb_page_merge(mc, &mn);
|
||||||
|
if (mc->mc_flags & C_SUB)
|
||||||
|
mc->mc_txn->mt_cursors[mc->mc_dbi] = dummy.mc_next;
|
||||||
|
else
|
||||||
|
mc->mc_txn->mt_cursors[mc->mc_dbi] = mn.mc_next;
|
||||||
mdb_cursor_copy(&mn, mc);
|
mdb_cursor_copy(&mn, mc);
|
||||||
}
|
}
|
||||||
mc->mc_flags &= ~C_EOF;
|
mc->mc_flags &= ~C_EOF;
|
||||||
|
@ -7819,6 +7864,13 @@ mdb_cursor_del0(MDB_cursor *mc)
|
||||||
MDB_cursor *m2, *m3;
|
MDB_cursor *m2, *m3;
|
||||||
MDB_dbi dbi = mc->mc_dbi;
|
MDB_dbi dbi = mc->mc_dbi;
|
||||||
|
|
||||||
|
/* DB is totally empty now, just bail out.
|
||||||
|
* Other cursors adjustments were already done
|
||||||
|
* by mdb_rebalance and aren't needed here.
|
||||||
|
*/
|
||||||
|
if (!mc->mc_snum)
|
||||||
|
return rc;
|
||||||
|
|
||||||
mp = mc->mc_pg[mc->mc_top];
|
mp = mc->mc_pg[mc->mc_top];
|
||||||
nkeys = NUMKEYS(mp);
|
nkeys = NUMKEYS(mp);
|
||||||
|
|
||||||
|
|
|
@ -45,19 +45,22 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
E(mdb_env_create(&env));
|
E(mdb_env_create(&env));
|
||||||
|
E(mdb_env_set_maxreaders(env, 1));
|
||||||
E(mdb_env_set_mapsize(env, 10485760));
|
E(mdb_env_set_mapsize(env, 10485760));
|
||||||
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));
|
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 0, &txn));
|
E(mdb_txn_begin(env, NULL, 0, &txn));
|
||||||
E(mdb_open(txn, NULL, 0, &dbi));
|
E(mdb_dbi_open(txn, NULL, 0, &dbi));
|
||||||
|
|
||||||
key.mv_size = sizeof(int);
|
key.mv_size = sizeof(int);
|
||||||
key.mv_data = sval;
|
key.mv_data = sval;
|
||||||
data.mv_size = sizeof(sval);
|
|
||||||
data.mv_data = sval;
|
|
||||||
|
|
||||||
printf("Adding %d values\n", count);
|
printf("Adding %d values\n", count);
|
||||||
for (i=0;i<count;i++) {
|
for (i=0;i<count;i++) {
|
||||||
sprintf(sval, "%03x %d foo bar", values[i], values[i]);
|
sprintf(sval, "%03x %d foo bar", values[i], values[i]);
|
||||||
|
/* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */
|
||||||
|
data.mv_size = sizeof(sval);
|
||||||
|
data.mv_data = sval;
|
||||||
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {
|
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {
|
||||||
j++;
|
j++;
|
||||||
data.mv_size = sizeof(sval);
|
data.mv_size = sizeof(sval);
|
||||||
|
@ -68,7 +71,7 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_txn_commit(txn));
|
E(mdb_txn_commit(txn));
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
printf("key: %p %.*s, data: %p %.*s\n",
|
printf("key: %p %.*s, data: %p %.*s\n",
|
||||||
|
@ -97,7 +100,7 @@ int main(int argc,char * argv[])
|
||||||
printf("Deleted %d values\n", j);
|
printf("Deleted %d values\n", j);
|
||||||
|
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
printf("Cursor next\n");
|
printf("Cursor next\n");
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
|
@ -128,6 +131,7 @@ int main(int argc,char * argv[])
|
||||||
(int) key.mv_size, (char *) key.mv_data,
|
(int) key.mv_size, (char *) key.mv_data,
|
||||||
(int) data.mv_size, (char *) data.mv_data);
|
(int) data.mv_size, (char *) data.mv_data);
|
||||||
|
|
||||||
|
mdb_cursor_close(cursor);
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
|
||||||
printf("Deleting with cursor\n");
|
printf("Deleting with cursor\n");
|
||||||
|
@ -164,9 +168,9 @@ int main(int argc,char * argv[])
|
||||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data);
|
data.mv_data, (int) data.mv_size, (char *) data.mv_data);
|
||||||
}
|
}
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_close(env, dbi);
|
|
||||||
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi);
|
||||||
mdb_env_close(env);
|
mdb_env_close(env);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -47,20 +47,22 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
E(mdb_env_create(&env));
|
E(mdb_env_create(&env));
|
||||||
|
E(mdb_env_set_maxreaders(env, 1));
|
||||||
E(mdb_env_set_mapsize(env, 10485760));
|
E(mdb_env_set_mapsize(env, 10485760));
|
||||||
E(mdb_env_set_maxdbs(env, 4));
|
E(mdb_env_set_maxdbs(env, 4));
|
||||||
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 0, &txn));
|
E(mdb_txn_begin(env, NULL, 0, &txn));
|
||||||
E(mdb_open(txn, "id1", MDB_CREATE, &dbi));
|
E(mdb_dbi_open(txn, "id1", MDB_CREATE, &dbi));
|
||||||
|
|
||||||
key.mv_size = sizeof(int);
|
key.mv_size = sizeof(int);
|
||||||
key.mv_data = sval;
|
key.mv_data = sval;
|
||||||
data.mv_size = sizeof(sval);
|
|
||||||
data.mv_data = sval;
|
|
||||||
|
|
||||||
printf("Adding %d values\n", count);
|
printf("Adding %d values\n", count);
|
||||||
for (i=0;i<count;i++) {
|
for (i=0;i<count;i++) {
|
||||||
sprintf(sval, "%03x %d foo bar", values[i], values[i]);
|
sprintf(sval, "%03x %d foo bar", values[i], values[i]);
|
||||||
|
data.mv_size = sizeof(sval);
|
||||||
|
data.mv_data = sval;
|
||||||
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE)))
|
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE)))
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +70,7 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_txn_commit(txn));
|
E(mdb_txn_commit(txn));
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
printf("key: %p %.*s, data: %p %.*s\n",
|
printf("key: %p %.*s, data: %p %.*s\n",
|
||||||
|
@ -97,7 +99,7 @@ int main(int argc,char * argv[])
|
||||||
printf("Deleted %d values\n", j);
|
printf("Deleted %d values\n", j);
|
||||||
|
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
printf("Cursor next\n");
|
printf("Cursor next\n");
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
|
@ -114,10 +116,9 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_close(env, dbi);
|
|
||||||
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
mdb_env_close(env);
|
|
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi);
|
||||||
|
mdb_env_close(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,9 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_env_set_mapsize(env, 10485760));
|
E(mdb_env_set_mapsize(env, 10485760));
|
||||||
E(mdb_env_set_maxdbs(env, 4));
|
E(mdb_env_set_maxdbs(env, 4));
|
||||||
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 0, &txn));
|
E(mdb_txn_begin(env, NULL, 0, &txn));
|
||||||
E(mdb_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
|
E(mdb_dbi_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
|
||||||
|
|
||||||
key.mv_size = sizeof(int);
|
key.mv_size = sizeof(int);
|
||||||
key.mv_data = kval;
|
key.mv_data = kval;
|
||||||
|
@ -73,7 +74,7 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_txn_commit(txn));
|
E(mdb_txn_commit(txn));
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
printf("key: %p %.*s, data: %p %.*s\n",
|
printf("key: %p %.*s, data: %p %.*s\n",
|
||||||
|
@ -107,7 +108,7 @@ int main(int argc,char * argv[])
|
||||||
printf("Deleted %d values\n", j);
|
printf("Deleted %d values\n", j);
|
||||||
|
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
printf("Cursor next\n");
|
printf("Cursor next\n");
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
|
@ -124,10 +125,9 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_close(env, dbi);
|
|
||||||
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
mdb_env_close(env);
|
|
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi);
|
||||||
|
mdb_env_close(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,8 +51,9 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_env_set_mapsize(env, 10485760));
|
E(mdb_env_set_mapsize(env, 10485760));
|
||||||
E(mdb_env_set_maxdbs(env, 4));
|
E(mdb_env_set_maxdbs(env, 4));
|
||||||
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 0, &txn));
|
E(mdb_txn_begin(env, NULL, 0, &txn));
|
||||||
E(mdb_open(txn, "id4", MDB_CREATE|MDB_DUPSORT|MDB_DUPFIXED, &dbi));
|
E(mdb_dbi_open(txn, "id4", MDB_CREATE|MDB_DUPSORT|MDB_DUPFIXED, &dbi));
|
||||||
|
|
||||||
key.mv_size = sizeof(int);
|
key.mv_size = sizeof(int);
|
||||||
key.mv_data = kval;
|
key.mv_data = kval;
|
||||||
|
@ -72,7 +73,7 @@ int main(int argc,char * argv[])
|
||||||
|
|
||||||
/* there should be one full page of dups now.
|
/* there should be one full page of dups now.
|
||||||
*/
|
*/
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
printf("key: %p %.*s, data: %p %.*s\n",
|
printf("key: %p %.*s, data: %p %.*s\n",
|
||||||
|
@ -142,7 +143,7 @@ int main(int argc,char * argv[])
|
||||||
printf("Deleted %d values\n", j);
|
printf("Deleted %d values\n", j);
|
||||||
|
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
printf("Cursor next\n");
|
printf("Cursor next\n");
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
|
@ -159,10 +160,9 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_close(env, dbi);
|
|
||||||
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
mdb_env_close(env);
|
|
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi);
|
||||||
|
mdb_env_close(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,9 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_env_set_mapsize(env, 10485760));
|
E(mdb_env_set_mapsize(env, 10485760));
|
||||||
E(mdb_env_set_maxdbs(env, 4));
|
E(mdb_env_set_maxdbs(env, 4));
|
||||||
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 0, &txn));
|
E(mdb_txn_begin(env, NULL, 0, &txn));
|
||||||
E(mdb_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
|
E(mdb_dbi_open(txn, "id2", MDB_CREATE|MDB_DUPSORT, &dbi));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
|
|
||||||
key.mv_size = sizeof(int);
|
key.mv_size = sizeof(int);
|
||||||
|
@ -75,7 +76,7 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_txn_commit(txn));
|
E(mdb_txn_commit(txn));
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
printf("key: %p %.*s, data: %p %.*s\n",
|
printf("key: %p %.*s, data: %p %.*s\n",
|
||||||
|
@ -109,7 +110,7 @@ int main(int argc,char * argv[])
|
||||||
printf("Deleted %d values\n", j);
|
printf("Deleted %d values\n", j);
|
||||||
|
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
printf("Cursor next\n");
|
printf("Cursor next\n");
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
|
@ -126,10 +127,9 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_close(env, dbi);
|
|
||||||
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
mdb_env_close(env);
|
|
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi);
|
||||||
|
mdb_env_close(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ int main(int argc,char * argv[])
|
||||||
int i = 0, j = 0, rc;
|
int i = 0, j = 0, rc;
|
||||||
MDB_env *env;
|
MDB_env *env;
|
||||||
MDB_dbi dbi;
|
MDB_dbi dbi;
|
||||||
MDB_val key, data;
|
MDB_val key, data, sdata;
|
||||||
MDB_txn *txn;
|
MDB_txn *txn;
|
||||||
MDB_stat mst;
|
MDB_stat mst;
|
||||||
MDB_cursor *cursor;
|
MDB_cursor *cursor;
|
||||||
|
@ -46,33 +46,37 @@ int main(int argc,char * argv[])
|
||||||
E(mdb_env_set_mapsize(env, 10485760));
|
E(mdb_env_set_mapsize(env, 10485760));
|
||||||
E(mdb_env_set_maxdbs(env, 4));
|
E(mdb_env_set_maxdbs(env, 4));
|
||||||
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP|MDB_NOSYNC, 0664));
|
||||||
|
|
||||||
E(mdb_txn_begin(env, NULL, 0, &txn));
|
E(mdb_txn_begin(env, NULL, 0, &txn));
|
||||||
E(mdb_open(txn, "id6", MDB_CREATE|MDB_INTEGERKEY, &dbi));
|
E(mdb_dbi_open(txn, "id6", MDB_CREATE|MDB_INTEGERKEY, &dbi));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
E(mdb_stat(txn, dbi, &mst));
|
E(mdb_stat(txn, dbi, &mst));
|
||||||
|
|
||||||
sval = calloc(1, mst.ms_psize / 4);
|
sval = calloc(1, mst.ms_psize / 4);
|
||||||
key.mv_size = sizeof(long);
|
key.mv_size = sizeof(long);
|
||||||
key.mv_data = &kval;
|
key.mv_data = &kval;
|
||||||
data.mv_size = mst.ms_psize / 4 - 30;
|
sdata.mv_size = mst.ms_psize / 4 - 30;
|
||||||
data.mv_data = sval;
|
sdata.mv_data = sval;
|
||||||
|
|
||||||
printf("Adding 12 values, should yield 3 splits\n");
|
printf("Adding 12 values, should yield 3 splits\n");
|
||||||
for (i=0;i<12;i++) {
|
for (i=0;i<12;i++) {
|
||||||
kval = i*5;
|
kval = i*5;
|
||||||
sprintf(sval, "%08x", kval);
|
sprintf(sval, "%08x", kval);
|
||||||
|
data = sdata;
|
||||||
(void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
|
(void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
|
||||||
}
|
}
|
||||||
printf("Adding 12 more values, should yield 3 splits\n");
|
printf("Adding 12 more values, should yield 3 splits\n");
|
||||||
for (i=0;i<12;i++) {
|
for (i=0;i<12;i++) {
|
||||||
kval = i*5+4;
|
kval = i*5+4;
|
||||||
sprintf(sval, "%08x", kval);
|
sprintf(sval, "%08x", kval);
|
||||||
|
data = sdata;
|
||||||
(void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
|
(void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
|
||||||
}
|
}
|
||||||
printf("Adding 12 more values, should yield 3 splits\n");
|
printf("Adding 12 more values, should yield 3 splits\n");
|
||||||
for (i=0;i<12;i++) {
|
for (i=0;i<12;i++) {
|
||||||
kval = i*5+1;
|
kval = i*5+1;
|
||||||
sprintf(sval, "%08x", kval);
|
sprintf(sval, "%08x", kval);
|
||||||
|
data = sdata;
|
||||||
(void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
|
(void)RES(MDB_KEYEXIST, mdb_cursor_put(cursor, &key, &data, MDB_NOOVERWRITE));
|
||||||
}
|
}
|
||||||
E(mdb_cursor_get(cursor, &key, &data, MDB_FIRST));
|
E(mdb_cursor_get(cursor, &key, &data, MDB_FIRST));
|
||||||
|
@ -110,7 +114,7 @@ int main(int argc,char * argv[])
|
||||||
printf("Deleted %d values\n", j);
|
printf("Deleted %d values\n", j);
|
||||||
|
|
||||||
E(mdb_env_stat(env, &mst));
|
E(mdb_env_stat(env, &mst));
|
||||||
E(mdb_txn_begin(env, NULL, 1, &txn));
|
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
|
||||||
E(mdb_cursor_open(txn, dbi, &cursor));
|
E(mdb_cursor_open(txn, dbi, &cursor));
|
||||||
printf("Cursor next\n");
|
printf("Cursor next\n");
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
|
||||||
|
@ -127,9 +131,9 @@ int main(int argc,char * argv[])
|
||||||
}
|
}
|
||||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_close(env, dbi);
|
|
||||||
|
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
|
||||||
|
mdb_dbi_close(env, dbi);
|
||||||
#endif
|
#endif
|
||||||
mdb_env_close(env);
|
mdb_env_close(env);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ int main(int argc,char * argv[])
|
||||||
rc = mdb_env_create(&env);
|
rc = mdb_env_create(&env);
|
||||||
rc = mdb_env_open(env, "./testdb", 0, 0664);
|
rc = mdb_env_open(env, "./testdb", 0, 0664);
|
||||||
rc = mdb_txn_begin(env, NULL, 0, &txn);
|
rc = mdb_txn_begin(env, NULL, 0, &txn);
|
||||||
rc = mdb_open(txn, NULL, 0, &dbi);
|
rc = mdb_dbi_open(txn, NULL, 0, &dbi);
|
||||||
|
|
||||||
key.mv_size = sizeof(int);
|
key.mv_size = sizeof(int);
|
||||||
key.mv_data = sval;
|
key.mv_data = sval;
|
||||||
|
@ -56,7 +56,7 @@ int main(int argc,char * argv[])
|
||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
leave:
|
leave:
|
||||||
mdb_close(env, dbi);
|
mdb_dbi_close(env, dbi);
|
||||||
mdb_env_close(env);
|
mdb_env_close(env);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue