mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-30 22:47:16 +08:00
mdbx: documenting and checking key and value alignment for MDBX_INTEGERKEY and MDBX_INTEGERDUP.
This resolves https://github.com/leo-yuriev/libmdbx/issues/79. Change-Id: I819a6eca3018361e5896d5ccce7e4c0ca57c8b38
This commit is contained in:
parent
1ee1b269e6
commit
2ce9ace4d3
42
mdbx.h
42
mdbx.h
@ -1285,17 +1285,26 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf,
|
||||
/**** DATABASE FLAGS **********************************************************/
|
||||
/* Use reverse string keys */
|
||||
#define MDBX_REVERSEKEY 0x02u
|
||||
|
||||
/* Use sorted duplicates */
|
||||
#define MDBX_DUPSORT 0x04u
|
||||
|
||||
/* Numeric keys in native byte order, either uint32_t or uint64_t.
|
||||
* The keys must all be of the same size. */
|
||||
* The keys must all be of the same size and must be aligned while passing as
|
||||
* arguments. */
|
||||
#define MDBX_INTEGERKEY 0x08u
|
||||
|
||||
/* With MDBX_DUPSORT, sorted dup items have fixed size */
|
||||
#define MDBX_DUPFIXED 0x10u
|
||||
/* With MDBX_DUPSORT, dups are MDBX_INTEGERKEY-style integers */
|
||||
|
||||
/* With MDBX_DUPSORT, dups are MDBX_INTEGERKEY-style integers.
|
||||
* The data values must all be of the same size and must be aligned while
|
||||
* passing as arguments. */
|
||||
#define MDBX_INTEGERDUP 0x20u
|
||||
|
||||
/* With MDBX_DUPSORT, use reverse string dups */
|
||||
#define MDBX_REVERSEDUP 0x40u
|
||||
|
||||
/* Create DB if not already existing */
|
||||
#define MDBX_CREATE 0x40000u
|
||||
|
||||
@ -1375,51 +1384,73 @@ typedef enum MDBX_cursor_op {
|
||||
|
||||
/* key/data pair already exists */
|
||||
#define MDBX_KEYEXIST (-30799)
|
||||
|
||||
/* key/data pair not found (EOF) */
|
||||
#define MDBX_NOTFOUND (-30798)
|
||||
|
||||
/* Requested page not found - this usually indicates corruption */
|
||||
#define MDBX_PAGE_NOTFOUND (-30797)
|
||||
|
||||
/* Database is corrupted (page was wrong type and so on) */
|
||||
#define MDBX_CORRUPTED (-30796)
|
||||
|
||||
/* Environment had fatal error (i.e. update of meta page failed and so on) */
|
||||
#define MDBX_PANIC (-30795)
|
||||
|
||||
/* DB file version mismatch with libmdbx */
|
||||
#define MDBX_VERSION_MISMATCH (-30794)
|
||||
|
||||
/* File is not a valid MDBX file */
|
||||
#define MDBX_INVALID (-30793)
|
||||
|
||||
/* Environment mapsize reached */
|
||||
#define MDBX_MAP_FULL (-30792)
|
||||
|
||||
/* Environment maxdbs reached */
|
||||
#define MDBX_DBS_FULL (-30791)
|
||||
|
||||
/* Environment maxreaders reached */
|
||||
#define MDBX_READERS_FULL (-30790)
|
||||
|
||||
/* Txn has too many dirty pages */
|
||||
#define MDBX_TXN_FULL (-30788)
|
||||
|
||||
/* Cursor stack too deep - internal error */
|
||||
#define MDBX_CURSOR_FULL (-30787)
|
||||
|
||||
/* Page has not enough space - internal error */
|
||||
#define MDBX_PAGE_FULL (-30786)
|
||||
|
||||
/* Database contents grew beyond environment mapsize */
|
||||
#define MDBX_MAP_RESIZED (-30785)
|
||||
|
||||
/* Operation and DB incompatible, or DB type changed. This can mean:
|
||||
* - The operation expects an MDBX_DUPSORT / MDBX_DUPFIXED database.
|
||||
* - Opening a named DB when the unnamed DB has MDBX_DUPSORT/MDBX_INTEGERKEY.
|
||||
* - Accessing a data record as a database, or vice versa.
|
||||
* - The database was dropped and recreated with different flags. */
|
||||
#define MDBX_INCOMPATIBLE (-30784)
|
||||
|
||||
/* Invalid reuse of reader locktable slot */
|
||||
#define MDBX_BAD_RSLOT (-30783)
|
||||
|
||||
/* Transaction must abort, has a child, or is invalid */
|
||||
#define MDBX_BAD_TXN (-30782)
|
||||
/* Unsupported size of key/DB name/data, or wrong DUPFIXED size */
|
||||
|
||||
/* Unsupported size of key/DB name/data, or wrong DUPFIXED size,
|
||||
* or wrong aligment */
|
||||
#define MDBX_BAD_VALSIZE (-30781)
|
||||
|
||||
/* The specified DBI was changed unexpectedly */
|
||||
#define MDBX_BAD_DBI (-30780)
|
||||
|
||||
/* Unexpected problem - txn should abort */
|
||||
#define MDBX_PROBLEM (-30779)
|
||||
|
||||
/* Another write transaction is running or environment is already used while
|
||||
* opening with MDBX_EXCLUSIVE flag */
|
||||
#define MDBX_BUSY (-30778)
|
||||
|
||||
/* The last defined error code */
|
||||
#define MDBX_LAST_ERRCODE MDBX_BUSY
|
||||
|
||||
@ -2487,7 +2518,7 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b);
|
||||
* - MDBX_INTEGERKEY
|
||||
* Keys are binary integers in native byte order, either uin32_t or
|
||||
* uint64_t, and will be sorted as such. The keys must all be of the
|
||||
* same size.
|
||||
* same size and must be aligned while passing as arguments.
|
||||
* - MDBX_DUPFIXED
|
||||
* This flag may only be used in combination with MDBX_DUPSORT. This
|
||||
* option tells the library that the data items for this database are
|
||||
@ -2497,7 +2528,8 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b);
|
||||
* to retrieve multiple items at once.
|
||||
* - MDBX_INTEGERDUP
|
||||
* This option specifies that duplicate data items are binary integers,
|
||||
* similar to MDBX_INTEGERKEY keys.
|
||||
* similar to MDBX_INTEGERKEY keys. The data values must all be of the
|
||||
* same size and must be aligned while passing as arguments.
|
||||
* - MDBX_REVERSEDUP
|
||||
* This option specifies that duplicate data items should be compared as
|
||||
* strings in reverse order (the comparison is performed in the direction
|
||||
|
@ -9979,8 +9979,7 @@ static MDBX_node *__hot mdbx_node_search(MDBX_cursor *mc, MDBX_val *key,
|
||||
cmp = mc->mc_dbx->md_cmp;
|
||||
|
||||
/* Branch pages have no data, so if using integer keys,
|
||||
* alignment is guaranteed. Use faster mdbx_cmp_int_ai.
|
||||
*/
|
||||
* alignment is guaranteed. Use faster mdbx_cmp_int_align4(). */
|
||||
if (cmp == mdbx_cmp_int_align2 && IS_BRANCH(mp))
|
||||
cmp = mdbx_cmp_int_align4;
|
||||
|
||||
@ -11297,21 +11296,31 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
||||
return MDBX_BAD_VALSIZE;
|
||||
}
|
||||
|
||||
if ((mc->mc_db->md_flags & MDBX_INTEGERKEY) &&
|
||||
unlikely(key->iov_len != sizeof(uint32_t) &&
|
||||
if ((mc->mc_db->md_flags & MDBX_INTEGERKEY)) {
|
||||
if (unlikely(key->iov_len != sizeof(uint32_t) &&
|
||||
key->iov_len != sizeof(uint64_t))) {
|
||||
mdbx_cassert(mc, !"key-size is invalid for MDBX_INTEGERKEY");
|
||||
return MDBX_BAD_VALSIZE;
|
||||
}
|
||||
|
||||
if ((mc->mc_db->md_flags & MDBX_INTEGERDUP) &&
|
||||
unlikely(data->iov_len != sizeof(uint32_t) &&
|
||||
data->iov_len != sizeof(uint64_t))) {
|
||||
mdbx_cassert(mc, !"data-size is invalid MDBX_INTEGERDUP");
|
||||
if (unlikely(3 & (uintptr_t)key->iov_base)) {
|
||||
mdbx_cassert(mc, !"key-alignment is invalid for MDBX_INTEGERKEY");
|
||||
return MDBX_BAD_VALSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((mc->mc_db->md_flags & MDBX_INTEGERDUP)) {
|
||||
if (unlikely(data->iov_len != sizeof(uint32_t) &&
|
||||
data->iov_len != sizeof(uint64_t))) {
|
||||
mdbx_cassert(mc, !"data-size is invalid for MDBX_INTEGERDUP");
|
||||
return MDBX_BAD_VALSIZE;
|
||||
}
|
||||
if (unlikely(3 & (uintptr_t)data->iov_base)) {
|
||||
mdbx_cassert(mc, !"data-alignment is invalid for MDBX_INTEGERDUP");
|
||||
return MDBX_BAD_VALSIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mdbx_debug("==> put db %d key [%s], size %" PRIuPTR
|
||||
", data [%s] size %" PRIuPTR,
|
||||
DDBI(mc), DKEY(key), key->iov_len,
|
||||
|
Loading…
x
Reference in New Issue
Block a user