| 1413 | |
| 1414 | |
| 1415 | void BTR_insert(thread_db* tdbb, WIN* root_window, index_insertion* insertion) |
| 1416 | { |
| 1417 | /************************************** |
| 1418 | * |
| 1419 | * B T R _ i n s e r t |
| 1420 | * |
| 1421 | ************************************** |
| 1422 | * |
| 1423 | * Functional description |
| 1424 | * Insert a node into an index. |
| 1425 | * |
| 1426 | **************************************/ |
| 1427 | SET_TDBB(tdbb); |
| 1428 | |
| 1429 | index_desc* idx = insertion->iib_descriptor; |
| 1430 | RelationPages* relPages = insertion->iib_relation->getPages(tdbb); |
| 1431 | WIN window(relPages->rel_pg_space_id, idx->idx_root); |
| 1432 | btree_page* bucket = (btree_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_index); |
| 1433 | UCHAR root_level = bucket->btr_level; |
| 1434 | |
| 1435 | if (bucket->btr_level == 0) |
| 1436 | { |
| 1437 | CCH_RELEASE(tdbb, &window); |
| 1438 | CCH_FETCH(tdbb, &window, LCK_write, pag_index); |
| 1439 | } |
| 1440 | |
| 1441 | CCH_RELEASE(tdbb, root_window); |
| 1442 | |
| 1443 | temporary_key key; |
| 1444 | key.key_flags = 0; |
| 1445 | key.key_length = 0; |
| 1446 | |
| 1447 | RecordNumber recordNumber(0); |
| 1448 | BtrPageGCLock lock(tdbb); |
| 1449 | insertion->iib_dont_gc_lock = &lock; |
| 1450 | ULONG split_page = add_node(tdbb, &window, insertion, &key, &recordNumber, NULL, NULL); |
| 1451 | if (split_page == NO_SPLIT) |
| 1452 | return; |
| 1453 | |
| 1454 | // The top of the index has split. We need to make a new level and |
| 1455 | // update the index root page. Oh boy. |
| 1456 | index_root_page* root = (index_root_page*) CCH_FETCH(tdbb, root_window, LCK_write, pag_root); |
| 1457 | |
| 1458 | window.win_page = root->irt_rpt[idx->idx_id].getRoot(); |
| 1459 | bucket = (btree_page*) CCH_FETCH(tdbb, &window, LCK_write, pag_index); |
| 1460 | |
| 1461 | if (window.win_page.getPageNum() != idx->idx_root) |
| 1462 | { |
| 1463 | // AB: It could be possible that the "top" page meanwhile was changed by |
| 1464 | // another insert. In that case we are going to insert our split_page |
| 1465 | // in the existing "top" page instead of making a new "top" page. |
| 1466 | |
| 1467 | // hvlad: yes, old "top" page could be changed, and more - it could have |
| 1468 | // a split too. In this case we should insert our split page not at the |
| 1469 | // current "top" page but at the page at correct level. |
| 1470 | // Note, while we propagate our split page at lower level, "top" page |
| 1471 | // could be splitted again. Thus, to avoid endless loop we won't release |
| 1472 | // root page while propagate our split page. |
no test coverage detected