]> git.sur5r.net Git - openldap/blobdiff - libraries/libmdb/mdb.c
Fix mdb_split, fix MDB_GET_BOTH
[openldap] / libraries / libmdb / mdb.c
index 32beaaf54ee46b16aa29026026a48fde4cb121d2..431d1af5aeb41f6ca32fcdf507d1c668115a079c 100644 (file)
 #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
 #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;
@@ -2572,6 +2580,7 @@ set2:
                                int ex2, *ex2p;
                                if (op == MDB_GET_BOTH) {
                                        ex2p = &ex2;
+                                       ex2 = 0;
                                } else {
                                        ex2p = NULL;
                                }
@@ -3654,34 +3663,32 @@ mdb_split(MDB_txn *txn, MDB_dbi dbi, MDB_page **mpp, unsigned int *newindxp,
                /* Maximum free space in an empty page */
                pmax = txn->mt_env->me_psize - PAGEHDRSZ;
                nsize = mdb_leaf_size(txn->mt_env, newkey, newdata);
-               if (newindx <= split_indx) {
-split1:
+               if (newindx < split_indx) {
                        psize = nsize;
                        for (i=0; i<split_indx; i++) {
                                node = NODEPTR(&mdp->p, i);
-                               psize += NODESIZE + NODEKSZ(node);
+                               psize += NODESIZE + NODEKSZ(node) + sizeof(indx_t);
                                if (F_ISSET(node->mn_flags, F_BIGDATA))
                                        psize += sizeof(pgno_t);
                                else
                                        psize += NODEDSZ(node);
                                if (psize > pmax) {
-                                       split_indx--;
-                                       goto split1;
+                                       split_indx = i;
+                                       break;
                                }
                        }
                } else {
-split2:
                        psize = nsize;
-                       for (i=split_indx; i<nkeys; i++) {
+                       for (i=nkeys-1; i>=split_indx; i--) {
                                node = NODEPTR(&mdp->p, i);
-                               psize += NODESIZE + NODEKSZ(node);
+                               psize += NODESIZE + NODEKSZ(node) + sizeof(indx_t);
                                if (F_ISSET(node->mn_flags, F_BIGDATA))
                                        psize += sizeof(pgno_t);
                                else
                                        psize += NODEDSZ(node);
                                if (psize > pmax) {
-                                       split_indx++;
-                                       goto split2;
+                                       split_indx = i+1;
+                                       break;
                                }
                        }
                }
@@ -4138,3 +4145,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;
 }
+
+/** @} */