Commit e91dae3e authored by Howard Chu's avatar Howard Chu
Browse files

Cleanup midl, start documenting internals

parent b30d0266
......@@ -308,7 +308,7 @@ EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation.
EXTRACT_STATIC = NO
EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation.
......@@ -581,7 +581,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = mdb.h
INPUT = mdb.c mdb.h midl.c midl.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -55,6 +55,20 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
#ifndef _WIN32
#include <pthread.h>
#endif
#include "mdb.h"
#include "midl.h"
/** @defgroup internal MDB Internals
* @{
*/
/** @defgroup compat Windows Compatibility Macros
* @{
*/
#ifdef _WIN32
#define pthread_t DWORD
#define pthread_mutex_t HANDLE
......@@ -71,33 +85,25 @@
#define LOCK_MUTEX_W(env) pthread_mutex_lock(env->me_wmutex)
#define UNLOCK_MUTEX_W(env) pthread_mutex_unlock(env->me_wmutex)
#define getpid() GetCurrentProcessId()
#else
#include <pthread.h>
#define LOCK_MUTEX_R(env) pthread_mutex_lock(&env->me_txns->mti_mutex)
#define UNLOCK_MUTEX_R(env) pthread_mutex_unlock(&env->me_txns->mti_mutex)
#define LOCK_MUTEX_W(env) pthread_mutex_lock(&env->me_txns->mti_wmutex)
#define UNLOCK_MUTEX_W(env) pthread_mutex_unlock(&env->me_txns->mti_wmutex)
#endif
#ifdef _WIN32
#define fdatasync(fd) !FlushFileBuffers(fd)
#define ErrCode() GetLastError()
#define GetPageSize(x) {SYSTEM_INFO si; GetSystemInfo(&si); (x) = si.dwPageSize;}
#define close(fd) CloseHandle(fd)
#define munmap(ptr,len) UnmapViewOfFile(ptr)
#else
#define LOCK_MUTEX_R(env) pthread_mutex_lock(&env->me_txns->mti_mutex)
#define UNLOCK_MUTEX_R(env) pthread_mutex_unlock(&env->me_txns->mti_mutex)
#define LOCK_MUTEX_W(env) pthread_mutex_lock(&env->me_txns->mti_wmutex)
#define UNLOCK_MUTEX_W(env) pthread_mutex_unlock(&env->me_txns->mti_wmutex)
#define ErrCode() errno
#define HANDLE int
#define INVALID_HANDLE_VALUE -1
#define GetPageSize(x) (x) = sysconf(_SC_PAGE_SIZE)
#endif
#include "mdb.h"
#define ULONG unsigned long
typedef ULONG pgno_t;
#include "midl.h"
/** @} */
#ifndef _WIN32
/* Note: If O_DSYNC is undefined but exists in /usr/include,
* preferably set some compiler flag to get the definition.
* Otherwise compile with the less efficient -DMDB_DSYNC=O_SYNC.
......@@ -105,6 +111,10 @@ typedef ULONG pgno_t;
#ifndef MDB_DSYNC
# define MDB_DSYNC O_DSYNC
#endif
#endif
#define ULONG unsigned long
typedef ULONG pgno_t;
#ifndef DEBUG
#define DEBUG 0
......@@ -382,7 +392,7 @@ struct MDB_txn {
MDB_env *mt_env;
pgno_t *mt_free_pgs; /* this is an IDL */
union {
MIDL2 *dirty_list; /* modified pages */
ID2L dirty_list; /* modified pages */
MDB_reader *reader;
} mt_u;
MDB_dbx *mt_dbxs; /* array */
......@@ -429,7 +439,7 @@ struct MDB_env {
pthread_key_t me_txkey; /* thread-key for readers */
MDB_dpage *me_dpages;
pgno_t me_free_pgs[MDB_IDL_UM_SIZE];
MIDL2 me_dirty_list[MDB_IDL_DB_SIZE];
ID2 me_dirty_list[MDB_IDL_DB_SIZE];
LAZY_RWLOCK_DEF(me_dblock);
#ifdef _WIN32
HANDLE me_rmutex; /* Windows mutexes don't reside in shared mem */
......@@ -643,7 +653,7 @@ mdb_alloc_page(MDB_txn *txn, MDB_dbi dbi, MDB_page *parent, unsigned int parent_
{
MDB_dpage *dp;
pgno_t pgno = P_INVALID;
MIDL2 mid;
ID2 mid;
if (txn->mt_txnid > 2) {
......@@ -752,7 +762,7 @@ mdb_alloc_page(MDB_txn *txn, MDB_dbi dbi, MDB_page *parent, unsigned int parent_
}
mid.mid = dp->p.mp_pgno;
mid.mptr = dp;
mdb_midl2_insert(txn->mt_u.dirty_list, &mid);
mdb_mid2l_insert(txn->mt_u.dirty_list, &mid);
return dp;
}
......@@ -2059,10 +2069,8 @@ mdb_get_page(MDB_txn *txn, pgno_t pgno, MDB_page **ret)
if (!F_ISSET(txn->mt_flags, MDB_TXN_RDONLY) && txn->mt_u.dirty_list[0].mid) {
MDB_dpage *dp;
MIDL2 id;
unsigned x;
id.mid = pgno;
x = mdb_midl2_search(txn->mt_u.dirty_list, &id);
x = mdb_mid2l_search(txn->mt_u.dirty_list, pgno);
if (x <= txn->mt_u.dirty_list[0].mid && txn->mt_u.dirty_list[x].mid == pgno) {
dp = txn->mt_u.dirty_list[x].mptr;
p = &dp->p;
......@@ -4138,3 +4146,5 @@ int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
txn->mt_dbxs[dbi].md_rel = rel;
return MDB_SUCCESS;
}
/** @} */
......@@ -65,6 +65,9 @@
#include <sys/types.h>
/** @defgroup public Public API
* @{
*/
/** @defgroup Version Version Macros
* @{
*/
......@@ -782,4 +785,5 @@ int mdb_cursor_count(MDB_cursor *cursor, unsigned long *countp);
*/
int mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b);
/** @} */
#endif /* _MDB_H_ */
/* idl.c - ldap bdb back-end ID list functions */
/** @file midl.c
* @brief ldap bdb back-end ID List functions */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
......@@ -19,11 +20,15 @@
#include <assert.h>
#include "midl.h"
typedef unsigned long pgno_t;
#define CMP(x,y) ( (x) > (y) ? -1 : (x) < (y) )
/** @defgroup internal MDB Internals
* @{
*/
/** @defgroup idls ID List Management
* @{
*/
#define CMP(x,y) ( (x) < (y) ? -1 : (x) > (y) )
unsigned mdb_midl_search( ID *ids, ID id )
static unsigned mdb_midl_search( IDL ids, ID id )
{
/*
* binary search of id in ids
......@@ -38,7 +43,7 @@ unsigned mdb_midl_search( ID *ids, ID id )
while( 0 < n ) {
int pivot = n >> 1;
cursor = base + pivot;
val = CMP( id, ids[cursor + 1] );
val = CMP( ids[cursor + 1], id );
if( val < 0 ) {
n = pivot;
......@@ -59,7 +64,7 @@ unsigned mdb_midl_search( ID *ids, ID id )
}
}
int mdb_midl_insert( ID *ids, ID id )
int mdb_midl_insert( IDL ids, ID id )
{
unsigned x, i;
......@@ -108,7 +113,7 @@ int mdb_midl_insert( ID *ids, ID id )
return 0;
}
unsigned mdb_midl2_search( MIDL2 *ids, MIDL2 *id )
unsigned mdb_mid2l_search( ID2L ids, ID id )
{
/*
* binary search of id in ids
......@@ -123,7 +128,7 @@ unsigned mdb_midl2_search( MIDL2 *ids, MIDL2 *id )
while( 0 < n ) {
int pivot = n >> 1;
cursor = base + pivot;
val = CMP( ids[cursor + 1].mid, id->mid );
val = CMP( id, ids[cursor + 1].mid );
if( val < 0 ) {
n = pivot;
......@@ -144,11 +149,11 @@ unsigned mdb_midl2_search( MIDL2 *ids, MIDL2 *id )
}
}
int mdb_midl2_insert( MIDL2 *ids, MIDL2 *id )
int mdb_mid2l_insert( ID2L ids, ID2 *id )
{
unsigned x, i;
x = mdb_midl2_search( ids, id );
x = mdb_mid2l_search( ids, id->mid );
assert( x > 0 );
if( x < 1 ) {
......@@ -175,3 +180,5 @@ int mdb_midl2_insert( MIDL2 *ids, MIDL2 *id )
return 0;
}
/** @} */
/** @} */
/* idl.h - ldap bdb back-end ID list header file */
/** @file midl.h
* @brief ldap bdb back-end ID List header file.
*
* This file was originally part of back-bdb but has been
* modified for use in libmdb. Most of the macros defined
* in this file are unused, just left over from the original.
*
* This file is only used internally in libmdb and its definitions
* are not exposed publicly.
*/
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
......@@ -17,7 +26,24 @@
#ifndef _MDB_MIDL_H_
#define _MDB_MIDL_H_
/** @defgroup internal MDB Internals
* @{
*/
/** @defgroup idls ID List Management
* @{
*/
/** An ID should be the largest integer type supported on a machine.
*/
#define ID unsigned long
/** An IDL is an ID List, a sorted array of IDs. The first
* element of the array is a counter for how many actual
* IDs are in the list. In the original back-bdb code, IDLs are
* sorted in ascending order. For libmdb IDLs are sorted in
* descending order.
*/
typedef ID *IDL;
#define NOID (~(ID)0)
/* IDL sizes - likely should be even bigger
......@@ -71,14 +97,42 @@
#define MDB_IDL_N( ids ) ( MDB_IDL_IS_RANGE(ids) \
? ((ids)[2]-(ids)[1])+1 : (ids)[0] )
int mdb_midl_insert( ID *ids, ID id );
typedef struct MIDL2 {
ID mid;
void *mptr;
} MIDL2;
unsigned mdb_midl2_search( MIDL2 *ids, MIDL2 *id );
int mdb_midl2_insert( MIDL2 *ids, MIDL2 *id );
/** Insert an ID into an IDL.
* @param[in,out] ids The IDL to insert into.
* @param[in] id The ID to insert.
* @return 0 on success, -1 if the ID was already present in the IDL.
*/
int mdb_midl_insert( IDL ids, ID id );
/** An ID2 is an ID/pointer pair.
*/
typedef struct ID2 {
ID mid; /**< The ID */
void *mptr; /**< The pointer */
} ID2;
/** An ID2L is an ID2 List, a sorted array of ID2s.
* The first element's \b mid member is a count of how many actual
* elements are in the array. The \b mptr member of the first element is unused.
* The array is sorted in ascending order by \b mid.
*/
typedef ID2 *ID2L;
/** Search for an ID in an ID2L.
* @param[in] ids The ID2L to search.
* @param[in] id The ID to search for.
* @return The index of the first ID2 whose \b mid member is greater than or equal to \b id.
*/
unsigned mdb_mid2l_search( ID2L ids, ID id );
/** Insert an ID2 into a ID2L.
* @param[in,out] ids The ID2L to insert into.
* @param[in] id The ID2 to insert.
* @return 0 on success, -1 if the ID was already present in the MIDL2.
*/
int mdb_mid2l_insert( ID2L ids, ID2 *id );
/** @} */
/** @} */
#endif /* _MDB_MIDL_H_ */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment