]> git.sur5r.net Git - openldap/blobdiff - libraries/libmdb/mdb.c
libmdb/.gitignore += test[45], Doxygen output
[openldap] / libraries / libmdb / mdb.c
index 5a73e99317f04849ab1ef78845f846b99f2cbc17..b392826d07effad746b7ecadc8d00271b46b595c 100644 (file)
@@ -316,8 +316,8 @@ typedef uint16_t     indx_t;
  *     Since the database uses multi-version concurrency control, readers don't
  *     actually need any locking. This table is used to keep track of which
  *     readers are using data from which old transactions, so that we'll know
- *     when a particular old transaction is no longer in use, Old transactions
- *     that have freed any data pages can then have their freed pages reclaimed
+ *     when a particular old transaction is no longer in use. Old transactions
+ *     that have discarded any data pages can then have those pages reclaimed
  *     for use by a later write transaction.
  *
  *     The lock table is constructed such that reader slots are aligned with the
@@ -469,10 +469,12 @@ typedef struct MDB_txninfo {
  * headers on any page after the first.
  */
 typedef struct MDB_page {
-       union {
-               pgno_t          mp_pgno;        /**< page number */
-               void *          mp_next;        /**< for in-memory list of freed structs */
-       };
+#define        mp_pgno mp_p.p_pgno
+#define        mp_next mp_p.p_next
+       union padded {
+               pgno_t          p_pgno; /**< page number */
+               void *          p_next; /**< for in-memory list of freed structs */
+       } mp_p;
 #define        P_BRANCH         0x01           /**< branch page */
 #define        P_LEAF           0x02           /**< leaf page */
 #define        P_OVERFLOW       0x04           /**< overflow page */
@@ -480,13 +482,16 @@ typedef struct MDB_page {
 #define        P_DIRTY          0x10           /**< dirty page */
 #define        P_LEAF2          0x20           /**< for #MDB_DUPFIXED records */
        uint32_t        mp_flags;
-       union {
+#define mp_lower       mp_pb.pb.pb_lower
+#define mp_upper       mp_pb.pb.pb_upper
+#define mp_pages       mp_pb.pb_pages
+       union page_bounds {
                struct {
-                       indx_t          mp_lower;               /**< lower bound of free space */
-                       indx_t          mp_upper;               /**< upper bound of free space */
-               };
-               uint32_t        mp_pages;       /**< number of overflow pages */
-       };
+                       indx_t          pb_lower;               /**< lower bound of free space */
+                       indx_t          pb_upper;               /**< upper bound of free space */
+               } pb;
+               uint32_t        pb_pages;       /**< number of overflow pages */
+       } mp_pb;
        indx_t          mp_ptrs[1];             /**< dynamic size */
 } MDB_page;
 
@@ -881,7 +886,7 @@ mdb_strerror(int err)
  * @param[in] buf the buffer to write into. Should always be #DKBUF.
  * @return The key in hexadecimal form.
  */
-static char *
+char *
 mdb_dkey(MDB_val *key, char *buf)
 {
        char *ptr = buf;
@@ -2897,7 +2902,6 @@ mdb_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data,
 set1:
                        if (exactp)
                                *exactp = 1;
-                       rc = 0;
                        leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
                        goto set3;
                }
@@ -3279,9 +3283,11 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
                goto top;
        } else {
                int exact = 0;
-               rc = mdb_cursor_set(mc, key, NULL, MDB_SET, &exact);
+               MDB_val d2;
+               rc = mdb_cursor_set(mc, key, &d2, MDB_SET, &exact);
                if (flags == MDB_NOOVERWRITE && rc == 0) {
                        DPRINTF("duplicate key [%s]", DKEY(key));
+                       *data = d2;
                        return MDB_KEYEXIST;
                }
                if (rc && rc != MDB_NOTFOUND)
@@ -3336,6 +3342,9 @@ top:
                                rdata = &xdata;
                                xdata.mv_size = sizeof(MDB_db);
                                xdata.mv_data = &dummy;
+                               /* new sub-DB, must fully init xcursor */
+                               if (flags == MDB_CURRENT)
+                                       flags = 0;
                                goto new_sub;
                        }
                        goto put_sub;