| 2174 | |
| 2175 | |
| 2176 | void BTR_remove(thread_db* tdbb, WIN* root_window, index_insertion* insertion) |
| 2177 | { |
| 2178 | /************************************** |
| 2179 | * |
| 2180 | * B T R _ r e m o v e |
| 2181 | * |
| 2182 | ************************************** |
| 2183 | * |
| 2184 | * Functional description |
| 2185 | * Remove an index node from a b-tree. |
| 2186 | * If the node doesn't exist, don't get overly excited. |
| 2187 | * |
| 2188 | **************************************/ |
| 2189 | |
| 2190 | //const Database* dbb = tdbb->getDatabase(); |
| 2191 | index_desc* idx = insertion->iib_descriptor; |
| 2192 | RelationPages* relPages = insertion->iib_relation->getPages(tdbb); |
| 2193 | WIN window(relPages->rel_pg_space_id, idx->idx_root); |
| 2194 | btree_page* page = (btree_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_index); |
| 2195 | |
| 2196 | // If the page is level 0, re-fetch it for write |
| 2197 | const UCHAR level = page->btr_level; |
| 2198 | if (level == 0) |
| 2199 | { |
| 2200 | CCH_RELEASE(tdbb, &window); |
| 2201 | CCH_FETCH(tdbb, &window, LCK_write, pag_index); |
| 2202 | } |
| 2203 | |
| 2204 | // remove the node from the index tree via recursive descent |
| 2205 | contents result = remove_node(tdbb, insertion, &window); |
| 2206 | |
| 2207 | // if the root page points at only one lower page, remove this |
| 2208 | // level to prevent the tree from being deeper than necessary-- |
| 2209 | // do this only if the level is greater than 1 to prevent |
| 2210 | // excessive thrashing in the case where a small table is |
| 2211 | // constantly being loaded and deleted. |
| 2212 | if ((result == contents_single) && (level > 1)) |
| 2213 | { |
| 2214 | // we must first release the windows to obtain the root for write |
| 2215 | // without getting deadlocked |
| 2216 | |
| 2217 | CCH_RELEASE(tdbb, &window); |
| 2218 | CCH_RELEASE(tdbb, root_window); |
| 2219 | |
| 2220 | index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, root_window, LCK_write, pag_root); |
| 2221 | page = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index); |
| 2222 | |
| 2223 | // get the page number of the child, and check to make sure |
| 2224 | // the page still has only one node on it |
| 2225 | UCHAR* pointer = page->btr_nodes + page->btr_jump_size; |
| 2226 | IndexNode pageNode; |
| 2227 | pointer = pageNode.readNode(pointer, false); |
| 2228 | |
| 2229 | const ULONG number = pageNode.pageNumber; |
| 2230 | pointer = pageNode.readNode(pointer, false); |
| 2231 | if (!(pageNode.isEndBucket || pageNode.isEndLevel)) |
| 2232 | { |
| 2233 | CCH_RELEASE(tdbb, &window); |
no test coverage detected