mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-03-13 14:27:59 +08:00
Merge remote-tracking branch 'origin/mdb.master'
This commit is contained in:
commit
8442047d2d
@ -1,3 +1,34 @@
|
|||||||
|
# Makefile for liblmdb (Lightning memory-mapped database library).
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# Configuration. The compiler options must enable threaded compilation.
|
||||||
|
#
|
||||||
|
# Preprocessor macros (for CPPFLAGS) of interest:
|
||||||
|
#
|
||||||
|
# To compile successfully if the default does not:
|
||||||
|
# - MDB_USE_POSIX_SEM (enabled by default on BSD, Apple)
|
||||||
|
# Define if shared mutexes are unsupported. Note that Posix
|
||||||
|
# semaphores and shared mutexes have different behaviors and
|
||||||
|
# different problems, see the Caveats section in lmdb.h.
|
||||||
|
#
|
||||||
|
# For best performence or to compile successfully:
|
||||||
|
# - MDB_DSYNC = "O_DSYNC" (default) or "O_SYNC" (less efficient)
|
||||||
|
# If O_DSYNC is undefined but exists in /usr/include,
|
||||||
|
# preferably set some compiler flag to get the definition.
|
||||||
|
# - MDB_FDATASYNC = "fdatasync" or "fsync"
|
||||||
|
# Function for flushing the data of a file. Define this to
|
||||||
|
# "fsync" if fdatasync() is not supported. fdatasync is
|
||||||
|
# default except on BSD, Apple, Android which use fsync.
|
||||||
|
# - MDB_USE_PWRITEV
|
||||||
|
# Define if the pwritev() function is supported.
|
||||||
|
#
|
||||||
|
# Data format:
|
||||||
|
# - MDB_MAXKEYSIZE
|
||||||
|
# Controls data packing and limits, see mdb.c.
|
||||||
|
#
|
||||||
|
# Debugging:
|
||||||
|
# - MDB_DEBUG, MDB_PARANOID.
|
||||||
|
#
|
||||||
CC = gcc
|
CC = gcc
|
||||||
W = -W -Wall -Wno-unused-parameter -Wbad-function-cast
|
W = -W -Wall -Wno-unused-parameter -Wbad-function-cast
|
||||||
OPT = -O2 -g
|
OPT = -O2 -g
|
||||||
@ -6,6 +37,8 @@ LDLIBS =
|
|||||||
SOLIBS =
|
SOLIBS =
|
||||||
prefix = /usr/local
|
prefix = /usr/local
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
|
||||||
IHDRS = lmdb.h
|
IHDRS = lmdb.h
|
||||||
ILIBS = liblmdb.a liblmdb.so
|
ILIBS = liblmdb.a liblmdb.so
|
||||||
IPROGS = mdb_stat mdb_copy
|
IPROGS = mdb_stat mdb_copy
|
||||||
|
@ -144,6 +144,16 @@ typedef int mdb_mode_t;
|
|||||||
typedef mode_t mdb_mode_t;
|
typedef mode_t mdb_mode_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** An abstraction for a file handle.
|
||||||
|
* On POSIX systems file handles are small integers. On Windows
|
||||||
|
* they're opaque pointers.
|
||||||
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
typedef void *mdb_filehandle_t;
|
||||||
|
#else
|
||||||
|
typedef int mdb_filehandle_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @defgroup mdb MDB API
|
/** @defgroup mdb MDB API
|
||||||
* @{
|
* @{
|
||||||
* @brief OpenLDAP Lightning Memory-Mapped Database Manager
|
* @brief OpenLDAP Lightning Memory-Mapped Database Manager
|
||||||
@ -325,13 +335,11 @@ typedef enum MDB_cursor_op {
|
|||||||
Only for #MDB_DUPSORT */
|
Only for #MDB_DUPSORT */
|
||||||
MDB_NEXT_MULTIPLE, /**< Return all duplicate data items at the next
|
MDB_NEXT_MULTIPLE, /**< Return all duplicate data items at the next
|
||||||
cursor position. Only for #MDB_DUPFIXED */
|
cursor position. Only for #MDB_DUPFIXED */
|
||||||
MDB_NEXT_NODUP, /**< Position at first data item of next key.
|
MDB_NEXT_NODUP, /**< Position at first data item of next key */
|
||||||
Only for #MDB_DUPSORT */
|
|
||||||
MDB_PREV, /**< Position at previous data item */
|
MDB_PREV, /**< Position at previous data item */
|
||||||
MDB_PREV_DUP, /**< Position at previous data item of current key.
|
MDB_PREV_DUP, /**< Position at previous data item of current key.
|
||||||
Only for #MDB_DUPSORT */
|
Only for #MDB_DUPSORT */
|
||||||
MDB_PREV_NODUP, /**< Position at last data item of previous key.
|
MDB_PREV_NODUP, /**< Position at last data item of previous key */
|
||||||
Only for #MDB_DUPSORT */
|
|
||||||
MDB_SET, /**< Position at specified key */
|
MDB_SET, /**< Position at specified key */
|
||||||
MDB_SET_KEY, /**< Position at specified key, return key + data */
|
MDB_SET_KEY, /**< Position at specified key, return key + data */
|
||||||
MDB_SET_RANGE /**< Position at first key greater than or equal to specified key. */
|
MDB_SET_RANGE /**< Position at first key greater than or equal to specified key. */
|
||||||
@ -535,6 +543,17 @@ int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t
|
|||||||
*/
|
*/
|
||||||
int mdb_env_copy(MDB_env *env, const char *path);
|
int mdb_env_copy(MDB_env *env, const char *path);
|
||||||
|
|
||||||
|
/** @brief Copy an MDB environment to the specified file descriptor.
|
||||||
|
*
|
||||||
|
* This function may be used to make a backup of an existing environment.
|
||||||
|
* @param[in] env An environment handle returned by #mdb_env_create(). It
|
||||||
|
* must have already been opened successfully.
|
||||||
|
* @param[in] fd The filedescriptor to write the copy to. It must
|
||||||
|
* have already been opened for Write access.
|
||||||
|
* @return A non-zero error value on failure and 0 on success.
|
||||||
|
*/
|
||||||
|
int mdb_env_copyfd(MDB_env *env, mdb_filehandle_t fd);
|
||||||
|
|
||||||
/** @brief Return statistics about the MDB environment.
|
/** @brief Return statistics about the MDB environment.
|
||||||
*
|
*
|
||||||
* @param[in] env An environment handle returned by #mdb_env_create()
|
* @param[in] env An environment handle returned by #mdb_env_create()
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -5,12 +5,19 @@
|
|||||||
mdb_copy \- LMDB environment copy tool
|
mdb_copy \- LMDB environment copy tool
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B mdb_copy
|
.B mdb_copy
|
||||||
.I srcpath\ dstpath
|
.I srcpath\ [dstpath]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
The
|
The
|
||||||
.B mdb_copy
|
.B mdb_copy
|
||||||
utility copies an LMDB environment. The environment can
|
utility copies an LMDB environment. The environment can
|
||||||
be copied regardless of whether it is currently in use.
|
be copied regardless of whether it is currently in use.
|
||||||
|
|
||||||
|
If
|
||||||
|
.I dstpath
|
||||||
|
is specified it must be the path of an empty directory
|
||||||
|
for storing the backup. Otherwise, the backup will be
|
||||||
|
written to stdout.
|
||||||
|
|
||||||
.SH DIAGNOSTICS
|
.SH DIAGNOSTICS
|
||||||
Exit status is zero if no errors occur.
|
Exit status is zero if no errors occur.
|
||||||
Errors result in a non-zero exit status and
|
Errors result in a non-zero exit status and
|
||||||
|
@ -11,28 +11,52 @@
|
|||||||
* top-level directory of the distribution or, alternatively, at
|
* top-level directory of the distribution or, alternatively, at
|
||||||
* <http://www.OpenLDAP.org/license.html>.
|
* <http://www.OpenLDAP.org/license.html>.
|
||||||
*/
|
*/
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#define MDB_STDOUT GetStdHandle(STD_OUTPUT_HANDLE)
|
||||||
|
#else
|
||||||
|
#define MDB_STDOUT 1
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <signal.h>
|
||||||
#include "lmdb.h"
|
#include "lmdb.h"
|
||||||
|
|
||||||
|
static void
|
||||||
|
sighandle(int sig)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc,char * argv[])
|
int main(int argc,char * argv[])
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
MDB_env *env;
|
MDB_env *env;
|
||||||
char *envname = argv[1];
|
char *envname = argv[1];
|
||||||
|
|
||||||
if (argc != 3) {
|
if (argc<2 || argc>3) {
|
||||||
fprintf(stderr, "usage: %s srcpath dstpath\n", argv[0]);
|
fprintf(stderr, "usage: %s srcpath [dstpath]\n", argv[0]);
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SIGPIPE
|
||||||
|
signal(SIGPIPE, sighandle);
|
||||||
|
#endif
|
||||||
|
#ifdef SIGHUP
|
||||||
|
signal(SIGHUP, sighandle);
|
||||||
|
#endif
|
||||||
|
signal(SIGINT, sighandle);
|
||||||
|
signal(SIGTERM, sighandle);
|
||||||
|
|
||||||
rc = mdb_env_create(&env);
|
rc = mdb_env_create(&env);
|
||||||
|
|
||||||
rc = mdb_env_open(env, envname, MDB_RDONLY, 0);
|
rc = mdb_env_open(env, envname, MDB_RDONLY, 0);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printf("mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
printf("mdb_env_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||||
} else {
|
} else {
|
||||||
rc = mdb_env_copy(env, argv[2]);
|
if (argc == 2)
|
||||||
|
rc = mdb_env_copyfd(env, MDB_STDOUT);
|
||||||
|
else
|
||||||
|
rc = mdb_env_copy(env, argv[2]);
|
||||||
if (rc)
|
if (rc)
|
||||||
printf("mdb_env_copy failed, error %d %s\n", rc, mdb_strerror(rc));
|
printf("mdb_env_copy failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||||
}
|
}
|
||||||
|
@ -193,9 +193,12 @@ int main(int argc, char *argv[])
|
|||||||
printf("mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
printf("mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
|
||||||
goto txn_abort;
|
goto txn_abort;
|
||||||
}
|
}
|
||||||
while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT)) == 0) {
|
while ((rc = mdb_cursor_get(cursor, &key, NULL, MDB_NEXT_NODUP)) == 0) {
|
||||||
char *str = malloc(key.mv_size+1);
|
char *str;
|
||||||
MDB_dbi db2;
|
MDB_dbi db2;
|
||||||
|
if (memchr(key.mv_data, '\0', key.mv_size))
|
||||||
|
continue;
|
||||||
|
str = malloc(key.mv_size+1);
|
||||||
memcpy(str, key.mv_data, key.mv_size);
|
memcpy(str, key.mv_data, key.mv_size);
|
||||||
str[key.mv_size] = '\0';
|
str[key.mv_size] = '\0';
|
||||||
rc = mdb_open(txn, str, 0, &db2);
|
rc = mdb_open(txn, str, 0, &db2);
|
||||||
@ -214,6 +217,9 @@ int main(int argc, char *argv[])
|
|||||||
mdb_cursor_close(cursor);
|
mdb_cursor_close(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rc == MDB_NOTFOUND)
|
||||||
|
rc = MDB_SUCCESS;
|
||||||
|
|
||||||
mdb_close(env, dbi);
|
mdb_close(env, dbi);
|
||||||
txn_abort:
|
txn_abort:
|
||||||
mdb_txn_abort(txn);
|
mdb_txn_abort(txn);
|
||||||
|
@ -71,17 +71,6 @@ int mdb_midl_insert( MDB_IDL ids, MDB_ID id )
|
|||||||
{
|
{
|
||||||
unsigned x, i;
|
unsigned x, i;
|
||||||
|
|
||||||
if (MDB_IDL_IS_RANGE( ids )) {
|
|
||||||
/* if already in range, treat as a dup */
|
|
||||||
if (id >= MDB_IDL_RANGE_FIRST(ids) && id <= MDB_IDL_RANGE_LAST(ids))
|
|
||||||
return -1;
|
|
||||||
if (id < MDB_IDL_RANGE_FIRST(ids))
|
|
||||||
ids[1] = id;
|
|
||||||
else if (id > MDB_IDL_RANGE_LAST(ids))
|
|
||||||
ids[2] = id;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
x = mdb_midl_search( ids, id );
|
x = mdb_midl_search( ids, id );
|
||||||
assert( x > 0 );
|
assert( x > 0 );
|
||||||
|
|
||||||
@ -97,15 +86,9 @@ int mdb_midl_insert( MDB_IDL ids, MDB_ID id )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ++ids[0] >= MDB_IDL_DB_MAX ) {
|
if ( ++ids[0] >= MDB_IDL_DB_MAX ) {
|
||||||
if( id < ids[1] ) {
|
/* no room */
|
||||||
ids[1] = id;
|
--ids[0];
|
||||||
ids[2] = ids[ids[0]-1];
|
return -2;
|
||||||
} else if ( ids[ids[0]-1] < id ) {
|
|
||||||
ids[2] = id;
|
|
||||||
} else {
|
|
||||||
ids[2] = ids[ids[0]-1];
|
|
||||||
}
|
|
||||||
ids[0] = MDB_NOID;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* insert id */
|
/* insert id */
|
||||||
@ -121,8 +104,10 @@ int mdb_midl_insert( MDB_IDL ids, MDB_ID id )
|
|||||||
MDB_IDL mdb_midl_alloc(int num)
|
MDB_IDL mdb_midl_alloc(int num)
|
||||||
{
|
{
|
||||||
MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID));
|
MDB_IDL ids = malloc((num+2) * sizeof(MDB_ID));
|
||||||
if (ids)
|
if (ids) {
|
||||||
*ids++ = num;
|
*ids++ = num;
|
||||||
|
*ids = 0;
|
||||||
|
}
|
||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +120,9 @@ void mdb_midl_free(MDB_IDL ids)
|
|||||||
int mdb_midl_shrink( MDB_IDL *idp )
|
int mdb_midl_shrink( MDB_IDL *idp )
|
||||||
{
|
{
|
||||||
MDB_IDL ids = *idp;
|
MDB_IDL ids = *idp;
|
||||||
if (*(--ids) > MDB_IDL_UM_MAX) {
|
if (*(--ids) > MDB_IDL_UM_MAX &&
|
||||||
ids = realloc(ids, (MDB_IDL_UM_MAX+1) * sizeof(MDB_ID));
|
(ids = realloc(ids, (MDB_IDL_UM_MAX+1) * sizeof(MDB_ID))))
|
||||||
|
{
|
||||||
*ids++ = MDB_IDL_UM_MAX;
|
*ids++ = MDB_IDL_UM_MAX;
|
||||||
*idp = ids;
|
*idp = ids;
|
||||||
return 1;
|
return 1;
|
||||||
@ -144,7 +130,7 @@ int mdb_midl_shrink( MDB_IDL *idp )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mdb_midl_grow( MDB_IDL *idp, int num )
|
static int mdb_midl_grow( MDB_IDL *idp, int num )
|
||||||
{
|
{
|
||||||
MDB_IDL idn = *idp-1;
|
MDB_IDL idn = *idp-1;
|
||||||
/* grow it */
|
/* grow it */
|
||||||
@ -156,6 +142,20 @@ int mdb_midl_grow( MDB_IDL *idp, int num )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mdb_midl_need( MDB_IDL *idp, unsigned num )
|
||||||
|
{
|
||||||
|
MDB_IDL ids = *idp;
|
||||||
|
num += ids[0];
|
||||||
|
if (num > ids[-1]) {
|
||||||
|
num = (num + num/4 + (256 + 2)) & -256;
|
||||||
|
if (!(ids = realloc(ids-1, num * sizeof(MDB_ID))))
|
||||||
|
return ENOMEM;
|
||||||
|
*ids++ = num -= 2;
|
||||||
|
*idp = ids;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int mdb_midl_append( MDB_IDL *idp, MDB_ID id )
|
int mdb_midl_append( MDB_IDL *idp, MDB_ID id )
|
||||||
{
|
{
|
||||||
MDB_IDL ids = *idp;
|
MDB_IDL ids = *idp;
|
||||||
@ -184,6 +184,22 @@ int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n )
|
||||||
|
{
|
||||||
|
MDB_ID *ids = *idp, len = ids[0];
|
||||||
|
/* Too big? */
|
||||||
|
if (len + n > ids[-1]) {
|
||||||
|
if (mdb_midl_grow(idp, n | MDB_IDL_UM_MAX))
|
||||||
|
return ENOMEM;
|
||||||
|
ids = *idp;
|
||||||
|
}
|
||||||
|
ids[0] = len + n;
|
||||||
|
ids += len;
|
||||||
|
while (n)
|
||||||
|
ids[n--] = id++;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Quicksort + Insertion sort for small arrays */
|
/* Quicksort + Insertion sort for small arrays */
|
||||||
|
|
||||||
#define SMALL 8
|
#define SMALL 8
|
||||||
|
@ -52,64 +52,33 @@ typedef size_t MDB_ID;
|
|||||||
*/
|
*/
|
||||||
typedef MDB_ID *MDB_IDL;
|
typedef MDB_ID *MDB_IDL;
|
||||||
|
|
||||||
#define MDB_NOID (~(MDB_ID)0)
|
|
||||||
|
|
||||||
/* IDL sizes - likely should be even bigger
|
/* IDL sizes - likely should be even bigger
|
||||||
* limiting factors: sizeof(ID), thread stack size
|
* limiting factors: sizeof(ID), thread stack size
|
||||||
*/
|
*/
|
||||||
#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
|
#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
|
||||||
#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN)
|
#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN)
|
||||||
#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1))
|
#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1))
|
||||||
#define MDB_IDL_UM_SIZEOF (MDB_IDL_UM_SIZE * sizeof(MDB_ID))
|
|
||||||
|
|
||||||
#define MDB_IDL_DB_MAX (MDB_IDL_DB_SIZE-1)
|
#define MDB_IDL_DB_MAX (MDB_IDL_DB_SIZE-1)
|
||||||
|
|
||||||
#define MDB_IDL_UM_MAX (MDB_IDL_UM_SIZE-1)
|
#define MDB_IDL_UM_MAX (MDB_IDL_UM_SIZE-1)
|
||||||
|
|
||||||
#define MDB_IDL_IS_RANGE(ids) ((ids)[0] == MDB_NOID)
|
#define MDB_IDL_SIZEOF(ids) (((ids)[0]+1) * sizeof(MDB_ID))
|
||||||
#define MDB_IDL_RANGE_SIZE (3)
|
|
||||||
#define MDB_IDL_RANGE_SIZEOF (MDB_IDL_RANGE_SIZE * sizeof(MDB_ID))
|
|
||||||
#define MDB_IDL_SIZEOF(ids) ((MDB_IDL_IS_RANGE(ids) \
|
|
||||||
? MDB_IDL_RANGE_SIZE : ((ids)[0]+1)) * sizeof(MDB_ID))
|
|
||||||
|
|
||||||
#define MDB_IDL_RANGE_FIRST(ids) ((ids)[1])
|
|
||||||
#define MDB_IDL_RANGE_LAST(ids) ((ids)[2])
|
|
||||||
|
|
||||||
#define MDB_IDL_RANGE( ids, f, l ) \
|
|
||||||
do { \
|
|
||||||
(ids)[0] = MDB_NOID; \
|
|
||||||
(ids)[1] = (f); \
|
|
||||||
(ids)[2] = (l); \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define MDB_IDL_ZERO(ids) \
|
|
||||||
do { \
|
|
||||||
(ids)[0] = 0; \
|
|
||||||
(ids)[1] = 0; \
|
|
||||||
(ids)[2] = 0; \
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define MDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 )
|
#define MDB_IDL_IS_ZERO(ids) ( (ids)[0] == 0 )
|
||||||
#define MDB_IDL_IS_ALL( range, ids ) ( (ids)[0] == MDB_NOID \
|
|
||||||
&& (ids)[1] <= (range)[1] && (range)[2] <= (ids)[2] )
|
|
||||||
|
|
||||||
#define MDB_IDL_CPY( dst, src ) (memcpy( dst, src, MDB_IDL_SIZEOF( src ) ))
|
#define MDB_IDL_CPY( dst, src ) (memcpy( dst, src, MDB_IDL_SIZEOF( src ) ))
|
||||||
|
|
||||||
#define MDB_IDL_ID( bdb, ids, id ) MDB_IDL_RANGE( ids, id, ((bdb)->bi_lastid) )
|
|
||||||
#define MDB_IDL_ALL( bdb, ids ) MDB_IDL_RANGE( ids, 1, ((bdb)->bi_lastid) )
|
|
||||||
|
|
||||||
#define MDB_IDL_FIRST( ids ) ( (ids)[1] )
|
#define MDB_IDL_FIRST( ids ) ( (ids)[1] )
|
||||||
#define MDB_IDL_LAST( ids ) ( MDB_IDL_IS_RANGE(ids) \
|
#define MDB_IDL_LAST( ids ) ( (ids)[(ids)[0]] )
|
||||||
? (ids)[2] : (ids)[(ids)[0]] )
|
|
||||||
|
|
||||||
#define MDB_IDL_N( ids ) ( MDB_IDL_IS_RANGE(ids) \
|
/** Append ID to IDL. The IDL must be big enough. */
|
||||||
? ((ids)[2]-(ids)[1])+1 : (ids)[0] )
|
#define mdb_midl_xappend(idl, id) do { \
|
||||||
|
MDB_ID *xidl = (idl), xlen = ++(xidl[0]); \
|
||||||
|
xidl[xlen] = (id); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#if 0 /* superseded by append/sort */
|
#if 0 /* superseded by append/sort */
|
||||||
/** Insert an ID into an IDL.
|
/** Insert an ID into an IDL.
|
||||||
* @param[in,out] ids The IDL to insert into.
|
* @param[in,out] ids The IDL to insert into.
|
||||||
* @param[in] id The ID to insert.
|
* @param[in] id The ID to insert.
|
||||||
* @return 0 on success, -1 if the ID was already present in the IDL.
|
* @return 0 on success, -1 if ID was already present, -2 on error.
|
||||||
*/
|
*/
|
||||||
int mdb_midl_insert( MDB_IDL ids, MDB_ID id );
|
int mdb_midl_insert( MDB_IDL ids, MDB_ID id );
|
||||||
#endif
|
#endif
|
||||||
@ -132,28 +101,35 @@ void mdb_midl_free(MDB_IDL ids);
|
|||||||
*/
|
*/
|
||||||
int mdb_midl_shrink(MDB_IDL *idp);
|
int mdb_midl_shrink(MDB_IDL *idp);
|
||||||
|
|
||||||
/** Grow an IDL.
|
/** Make room for num additional elements in an IDL.
|
||||||
* Add room for num additional elements.
|
* @param[in,out] idp Address of the IDL.
|
||||||
* @param[in,out] idp Address of the IDL to grow.
|
* @param[in] num Number of elements to make room for.
|
||||||
* @param[in] num Number of elements to add.
|
* @return 0 on success, ENOMEM on failure.
|
||||||
* @return 0 on success, -1 on failure.
|
|
||||||
*/
|
*/
|
||||||
int mdb_midl_grow(MDB_IDL *idp, int num);
|
int mdb_midl_need(MDB_IDL *idp, unsigned num);
|
||||||
|
|
||||||
/** Append an ID onto an IDL.
|
/** Append an ID onto an IDL.
|
||||||
* @param[in,out] idp Address of the IDL to append to.
|
* @param[in,out] idp Address of the IDL to append to.
|
||||||
* @param[in] id The ID to append.
|
* @param[in] id The ID to append.
|
||||||
* @return 0 on success, -1 if the IDL is too large.
|
* @return 0 on success, ENOMEM if the IDL is too large.
|
||||||
*/
|
*/
|
||||||
int mdb_midl_append( MDB_IDL *idp, MDB_ID id );
|
int mdb_midl_append( MDB_IDL *idp, MDB_ID id );
|
||||||
|
|
||||||
/** Append an IDL onto an IDL.
|
/** Append an IDL onto an IDL.
|
||||||
* @param[in,out] idp Address of the IDL to append to.
|
* @param[in,out] idp Address of the IDL to append to.
|
||||||
* @param[in] app The IDL to append.
|
* @param[in] app The IDL to append.
|
||||||
* @return 0 on success, -1 if the IDL is too large.
|
* @return 0 on success, ENOMEM if the IDL is too large.
|
||||||
*/
|
*/
|
||||||
int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app );
|
int mdb_midl_append_list( MDB_IDL *idp, MDB_IDL app );
|
||||||
|
|
||||||
|
/** Append an ID range onto an IDL.
|
||||||
|
* @param[in,out] idp Address of the IDL to append to.
|
||||||
|
* @param[in] id The lowest ID to append.
|
||||||
|
* @param[in] n Number of IDs to append.
|
||||||
|
* @return 0 on success, ENOMEM if the IDL is too large.
|
||||||
|
*/
|
||||||
|
int mdb_midl_append_range( MDB_IDL *idp, MDB_ID id, unsigned n );
|
||||||
|
|
||||||
/** Sort an IDL.
|
/** Sort an IDL.
|
||||||
* @param[in,out] ids The IDL to sort.
|
* @param[in,out] ids The IDL to sort.
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user