mirror of
				https://github.com/isar/libmdbx.git
				synced 2025-11-01 03:48:57 +08:00 
			
		
		
		
	mdbx: backport - fix tracking around mdbx_cursor_del().
This commit is contained in:
		
				
					committed by
					
						 Leonid Yuriev
						Leonid Yuriev
					
				
			
			
				
	
			
			
			
						parent
						
							f57ffc987c
						
					
				
				
					commit
					e32ca55258
				
			
							
								
								
									
										67
									
								
								src/mdbx.c
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								src/mdbx.c
									
									
									
									
									
								
							| @@ -9347,6 +9347,7 @@ static int mdbx_cursor_del0(MDBX_cursor *mc) { | ||||
|   MDBX_cursor *m2, *m3; | ||||
|   MDBX_dbi dbi = mc->mc_dbi; | ||||
|  | ||||
|   mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top])); | ||||
|   ki = mc->mc_ki[mc->mc_top]; | ||||
|   mp = mc->mc_pg[mc->mc_top]; | ||||
|   mdbx_node_del(mc, mc->mc_db->md_xsize); | ||||
| @@ -9355,9 +9356,9 @@ static int mdbx_cursor_del0(MDBX_cursor *mc) { | ||||
|     /* Adjust other cursors pointing to mp */ | ||||
|     for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2 = m2->mc_next) { | ||||
|       m3 = (mc->mc_flags & C_SUB) ? &m2->mc_xcursor->mx_cursor : m2; | ||||
|       if (!(m2->mc_flags & m3->mc_flags & C_INITIALIZED)) | ||||
|       if (m3 == mc || !(m2->mc_flags & m3->mc_flags & C_INITIALIZED)) | ||||
|         continue; | ||||
|       if (m3 == mc || m3->mc_snum < mc->mc_snum) | ||||
|       if (m3->mc_snum < mc->mc_snum) | ||||
|         continue; | ||||
|       if (m3->mc_pg[mc->mc_top] == mp) { | ||||
|         if (m3->mc_ki[mc->mc_top] == ki) { | ||||
| @@ -9388,32 +9389,35 @@ static int mdbx_cursor_del0(MDBX_cursor *mc) { | ||||
|       return rc; | ||||
|     } | ||||
|  | ||||
|     ki = mc->mc_ki[mc->mc_top]; | ||||
|     mp = mc->mc_pg[mc->mc_top]; | ||||
|     mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top])); | ||||
|     nkeys = NUMKEYS(mp); | ||||
|     mdbx_cassert(mc, (mc->mc_db->md_entries > 0 && nkeys > 0) || | ||||
|                          ((mc->mc_flags & C_SUB) && | ||||
|                           mc->mc_db->md_entries == 0 && nkeys == 0)); | ||||
|  | ||||
|     /* Adjust other cursors pointing to mp */ | ||||
|     for (m2 = mc->mc_txn->mt_cursors[dbi]; !rc && m2; m2 = m2->mc_next) { | ||||
|     /* Adjust THIS and other cursors pointing to mp */ | ||||
|     for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2 = m2->mc_next) { | ||||
|       m3 = (mc->mc_flags & C_SUB) ? &m2->mc_xcursor->mx_cursor : m2; | ||||
|       if (!(m2->mc_flags & m3->mc_flags & C_INITIALIZED)) | ||||
|       if (m3 == mc || !(m2->mc_flags & m3->mc_flags & C_INITIALIZED)) | ||||
|         continue; | ||||
|       if (m3->mc_snum < mc->mc_snum) | ||||
|         continue; | ||||
|       if (m3->mc_pg[mc->mc_top] == mp) { | ||||
|         /* if m3 points past last node in page, find next sibling */ | ||||
|         if (m3->mc_ki[mc->mc_top] >= mc->mc_ki[mc->mc_top]) { | ||||
|           if (m3->mc_ki[mc->mc_top] >= nkeys) { | ||||
|             rc = mdbx_cursor_sibling(m3, 1); | ||||
|             if (rc == MDBX_NOTFOUND) { | ||||
|               m3->mc_flags |= C_EOF; | ||||
|               rc = MDBX_SUCCESS; | ||||
|               continue; | ||||
|             } else if (unlikely(rc != MDBX_SUCCESS)) | ||||
|               break; | ||||
|           } | ||||
|           if (mc->mc_db->md_flags & MDBX_DUPSORT) { | ||||
|         if (m3->mc_ki[mc->mc_top] >= nkeys) { | ||||
|           rc = mdbx_cursor_sibling(m3, true); | ||||
|           if (rc == MDBX_NOTFOUND) { | ||||
|             m3->mc_flags |= C_EOF; | ||||
|             rc = MDBX_SUCCESS; | ||||
|             continue; | ||||
|           } else if (unlikely(rc != MDBX_SUCCESS)) | ||||
|             break; | ||||
|         } | ||||
|         if (m3->mc_ki[mc->mc_top] >= ki || m3->mc_pg[mc->mc_top] != mp) { | ||||
|           if ((mc->mc_db->md_flags & MDBX_DUPSORT) != 0 && | ||||
|               (m3->mc_flags & C_EOF) == 0) { | ||||
|             MDBX_node *node = | ||||
|                 NODEPTR(m3->mc_pg[m3->mc_top], m3->mc_ki[m3->mc_top]); | ||||
|             /* If this node has dupdata, it may need to be reinited | ||||
| @@ -9426,14 +9430,41 @@ static int mdbx_cursor_del0(MDBX_cursor *mc) { | ||||
|                   m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); | ||||
|               } else { | ||||
|                 rc = mdbx_xcursor_init1(m3, node); | ||||
|                 if (likely(rc == MDBX_SUCCESS)) | ||||
|                   m3->mc_xcursor->mx_cursor.mc_flags |= C_DEL; | ||||
|                 if (unlikely(rc != MDBX_SUCCESS)) | ||||
|                   break; | ||||
|                 m3->mc_xcursor->mx_cursor.mc_flags |= C_DEL; | ||||
|               } | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (mc->mc_ki[mc->mc_top] >= nkeys) { | ||||
|       rc = mdbx_cursor_sibling(mc, true); | ||||
|       if (rc == MDBX_NOTFOUND) { | ||||
|         mc->mc_flags |= C_EOF; | ||||
|         rc = MDBX_SUCCESS; | ||||
|       } | ||||
|     } | ||||
|     if ((mc->mc_db->md_flags & MDBX_DUPSORT) != 0 && | ||||
|         (mc->mc_flags & C_EOF) == 0) { | ||||
|       MDBX_node *node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); | ||||
|       /* If this node has dupdata, it may need to be reinited | ||||
|        * because its data has moved. | ||||
|        * If the xcursor was not initd it must be reinited. | ||||
|        * Else if node points to a subDB, nothing is needed. */ | ||||
|       if (node->mn_flags & F_DUPDATA) { | ||||
|         if (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { | ||||
|           if (!(node->mn_flags & F_SUBDATA)) | ||||
|             mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); | ||||
|         } else { | ||||
|           rc = mdbx_xcursor_init1(mc, node); | ||||
|           if (likely(rc != MDBX_SUCCESS)) | ||||
|             mc->mc_xcursor->mx_cursor.mc_flags |= C_DEL; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     mc->mc_flags |= C_DEL; | ||||
|   } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user