@@ -1188,6 +1188,21 @@ typedef struct MDB_xcursor {
1188
1188
unsigned char mx_dbflag ;
1189
1189
} MDB_xcursor ;
1190
1190
1191
+ /** Check if there is an inited xcursor, so #XCURSOR_REFRESH() is proper */
1192
+ #define XCURSOR_INITED (mc ) \
1193
+ ((mc)->mc_xcursor && ((mc)->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED))
1194
+
1195
+ /** Update sub-page pointer, if any, in \b mc->mc_xcursor. Needed
1196
+ * when the node which contains the sub-page may have moved. Called
1197
+ * with \b mp = mc->mc_pg[mc->mc_top], \b ki = mc->mc_ki[mc->mc_top].
1198
+ */
1199
+ #define XCURSOR_REFRESH (mc , mp , ki ) do { \
1200
+ MDB_page *xr_pg = (mp); \
1201
+ MDB_node *xr_node = NODEPTR(xr_pg, ki); \
1202
+ if ((xr_node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) \
1203
+ (mc)->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(xr_node); \
1204
+ } while (0)
1205
+
1191
1206
/** State of FreeDB old pages, stored in the MDB_env */
1192
1207
typedef struct MDB_pgstate {
1193
1208
pgno_t * mf_pghead ; /**< Reclaimed freeDB pages, or NULL before use */
@@ -1618,7 +1633,7 @@ mdb_cursor_chk(MDB_cursor *mc)
1618
1633
}
1619
1634
if (mc -> mc_ki [i ] >= NUMKEYS (mc -> mc_pg [i ]))
1620
1635
printf ("ack!\n" );
1621
- if (mc -> mc_xcursor && (mc -> mc_xcursor -> mx_cursor . mc_flags & C_INITIALIZED )) {
1636
+ if (XCURSOR_INITED (mc )) {
1622
1637
node = NODEPTR (mc -> mc_pg [mc -> mc_top ], mc -> mc_ki [mc -> mc_top ]);
1623
1638
if (((node -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA ) &&
1624
1639
mc -> mc_xcursor -> mx_cursor .mc_pg [0 ] != NODEDATA (node )) {
@@ -2433,14 +2448,8 @@ mdb_page_touch(MDB_cursor *mc)
2433
2448
if (m2 == mc ) continue ;
2434
2449
if (m2 -> mc_pg [mc -> mc_top ] == mp ) {
2435
2450
m2 -> mc_pg [mc -> mc_top ] = np ;
2436
- if ((mc -> mc_db -> md_flags & MDB_DUPSORT ) &&
2437
- IS_LEAF (np ) &&
2438
- (m2 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED ))
2439
- {
2440
- MDB_node * leaf = NODEPTR (np , m2 -> mc_ki [mc -> mc_top ]);
2441
- if ((leaf -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA )
2442
- m2 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (leaf );
2443
- }
2451
+ if (XCURSOR_INITED (m2 ) && IS_LEAF (np ))
2452
+ XCURSOR_REFRESH (m2 , np , m2 -> mc_ki [mc -> mc_top ]);
2444
2453
}
2445
2454
}
2446
2455
}
@@ -6726,11 +6735,8 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
6726
6735
if (m3 -> mc_ki [i ] >= mc -> mc_ki [i ] && insert_key ) {
6727
6736
m3 -> mc_ki [i ]++ ;
6728
6737
}
6729
- if (m3 -> mc_xcursor && (m3 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED )) {
6730
- MDB_node * n2 = NODEPTR (mp , m3 -> mc_ki [i ]);
6731
- if ((n2 -> mn_flags & (F_SUBDATA |F_DUPDATA )) == F_DUPDATA )
6732
- m3 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (n2 );
6733
- }
6738
+ if (XCURSOR_INITED (m3 ))
6739
+ XCURSOR_REFRESH (m3 , mp , m3 -> mc_ki [i ]);
6734
6740
}
6735
6741
}
6736
6742
}
@@ -6781,9 +6787,7 @@ mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
6781
6787
if (m2 -> mc_ki [i ] == mc -> mc_ki [i ]) {
6782
6788
mdb_xcursor_init2 (m2 , mx , new_dupdata );
6783
6789
} else if (!insert_key && m2 -> mc_ki [i ] < nkeys ) {
6784
- MDB_node * n2 = NODEPTR (mp , m2 -> mc_ki [i ]);
6785
- if ((n2 -> mn_flags & (F_SUBDATA |F_DUPDATA )) == F_DUPDATA )
6786
- m2 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (n2 );
6790
+ XCURSOR_REFRESH (m2 , mp , m2 -> mc_ki [i ]);
6787
6791
}
6788
6792
}
6789
6793
}
@@ -6888,13 +6892,12 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
6888
6892
if (m2 == mc || m2 -> mc_snum < mc -> mc_snum ) continue ;
6889
6893
if (!(m2 -> mc_flags & C_INITIALIZED )) continue ;
6890
6894
if (m2 -> mc_pg [mc -> mc_top ] == mp ) {
6891
- if (m2 -> mc_ki [mc -> mc_top ] == mc -> mc_ki [mc -> mc_top ]) {
6892
- m2 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (leaf );
6893
- } else {
6894
- MDB_node * n2 = NODEPTR (mp , m2 -> mc_ki [mc -> mc_top ]);
6895
- if (!(n2 -> mn_flags & F_SUBDATA ))
6896
- m2 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (n2 );
6895
+ MDB_node * n2 = leaf ;
6896
+ if (m2 -> mc_ki [mc -> mc_top ] != mc -> mc_ki [mc -> mc_top ]) {
6897
+ n2 = NODEPTR (mp , m2 -> mc_ki [mc -> mc_top ]);
6898
+ if (n2 -> mn_flags & F_SUBDATA ) continue ;
6897
6899
}
6900
+ m2 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (n2 );
6898
6901
}
6899
6902
}
6900
6903
}
@@ -7731,12 +7734,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft)
7731
7734
m3 -> mc_ki [csrc -> mc_top ] = cdst -> mc_ki [cdst -> mc_top ];
7732
7735
m3 -> mc_ki [csrc -> mc_top - 1 ]++ ;
7733
7736
}
7734
- if (m3 -> mc_xcursor && (m3 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED ) &&
7735
- IS_LEAF (mps )) {
7736
- MDB_node * node = NODEPTR (m3 -> mc_pg [csrc -> mc_top ], m3 -> mc_ki [csrc -> mc_top ]);
7737
- if ((node -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA )
7738
- m3 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (node );
7739
- }
7737
+ if (XCURSOR_INITED (m3 ) && IS_LEAF (mps ))
7738
+ XCURSOR_REFRESH (m3 , m3 -> mc_pg [csrc -> mc_top ], m3 -> mc_ki [csrc -> mc_top ]);
7740
7739
}
7741
7740
} else
7742
7741
/* Adding on the right, bump others down */
@@ -7757,12 +7756,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft)
7757
7756
} else {
7758
7757
m3 -> mc_ki [csrc -> mc_top ]-- ;
7759
7758
}
7760
- if (m3 -> mc_xcursor && (m3 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED ) &&
7761
- IS_LEAF (mps )) {
7762
- MDB_node * node = NODEPTR (m3 -> mc_pg [csrc -> mc_top ], m3 -> mc_ki [csrc -> mc_top ]);
7763
- if ((node -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA )
7764
- m3 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (node );
7765
- }
7759
+ if (XCURSOR_INITED (m3 ) && IS_LEAF (mps ))
7760
+ XCURSOR_REFRESH (m3 , m3 -> mc_pg [csrc -> mc_top ], m3 -> mc_ki [csrc -> mc_top ]);
7766
7761
}
7767
7762
}
7768
7763
}
@@ -7963,12 +7958,8 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
7963
7958
m3 -> mc_ki [top - 1 ] > csrc -> mc_ki [top - 1 ]) {
7964
7959
m3 -> mc_ki [top - 1 ]-- ;
7965
7960
}
7966
- if (m3 -> mc_xcursor && (m3 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED ) &&
7967
- IS_LEAF (psrc )) {
7968
- MDB_node * node = NODEPTR (m3 -> mc_pg [top ], m3 -> mc_ki [top ]);
7969
- if ((node -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA )
7970
- m3 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (node );
7971
- }
7961
+ if (XCURSOR_INITED (m3 ) && IS_LEAF (psrc ))
7962
+ XCURSOR_REFRESH (m3 , m3 -> mc_pg [top ], m3 -> mc_ki [top ]);
7972
7963
}
7973
7964
}
7974
7965
{
@@ -8230,11 +8221,8 @@ mdb_cursor_del0(MDB_cursor *mc)
8230
8221
} else if (m3 -> mc_ki [mc -> mc_top ] > ki ) {
8231
8222
m3 -> mc_ki [mc -> mc_top ]-- ;
8232
8223
}
8233
- if (m3 -> mc_xcursor && (m3 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED )) {
8234
- MDB_node * node = NODEPTR (m3 -> mc_pg [mc -> mc_top ], m3 -> mc_ki [mc -> mc_top ]);
8235
- if ((node -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA )
8236
- m3 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (node );
8237
- }
8224
+ if (XCURSOR_INITED (m3 ))
8225
+ XCURSOR_REFRESH (m3 , m3 -> mc_pg [mc -> mc_top ], m3 -> mc_ki [mc -> mc_top ]);
8238
8226
}
8239
8227
}
8240
8228
}
@@ -8764,12 +8752,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno
8764
8752
m3 -> mc_ki [ptop ] >= mc -> mc_ki [ptop ]) {
8765
8753
m3 -> mc_ki [ptop ]++ ;
8766
8754
}
8767
- if (m3 -> mc_xcursor && (m3 -> mc_xcursor -> mx_cursor .mc_flags & C_INITIALIZED ) &&
8768
- IS_LEAF (mp )) {
8769
- MDB_node * node = NODEPTR (m3 -> mc_pg [mc -> mc_top ], m3 -> mc_ki [mc -> mc_top ]);
8770
- if ((node -> mn_flags & (F_DUPDATA |F_SUBDATA )) == F_DUPDATA )
8771
- m3 -> mc_xcursor -> mx_cursor .mc_pg [0 ] = NODEDATA (node );
8772
- }
8755
+ if (XCURSOR_INITED (m3 ) && IS_LEAF (mp ))
8756
+ XCURSOR_REFRESH (m3 , m3 -> mc_pg [mc -> mc_top ], m3 -> mc_ki [mc -> mc_top ]);
8773
8757
}
8774
8758
}
8775
8759
DPRINTF (("mp left: %d, rp left: %d" , SIZELEFT (mp ), SIZELEFT (rp )));
0 commit comments