284
284
if ((XT_NODE_ID(wrote_pos) = XT_NODE_ID(tab->tab_ind_free))) {
285
xtIndexNodeID next_node;
285
287
/* Use the block on the free list: */
286
if (!xt_ind_read_bytes(ot, ind, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block))
288
XT_NODE_ID(tab->tab_ind_free) = (xtIndexNodeID) XT_GET_DISK_8(free_block.if_next_block_8);
288
if (!xt_ind_read_bytes(ot, NULL, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block))
290
XT_NODE_ID(next_node) = (xtIndexNodeID) XT_GET_DISK_8(free_block.if_next_block_8);
291
if (XT_NODE_ID(next_node) >= XT_NODE_ID(tab->tab_ind_eof)) {
292
xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, tab->tab_name);
295
XT_NODE_ID(tab->tab_ind_free) = XT_NODE_ID(next_node);
289
296
xt_unlock_mutex_ns(&tab->tab_ind_lock);
290
297
*address = wrote_pos;
291
298
TRACK_BLOCK_ALLOC(wrote_pos);
1566
1573
if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))
1567
1574
iref.ir_block->cp_del_count--;
1569
memmove(&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item_size],
1570
&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size],
1571
item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size);
1572
memcpy(&iref.ir_branch->tb_data[item->i_pos.i_item_offset],
1573
item_buf, item_size);
1574
if (ind->mi_lazy_delete) {
1575
if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))
1576
iref.ir_block->cp_del_count++;
1578
item->i_pos.i_total_size = item->i_pos.i_total_size + item_size - item->i_pos.i_item_size;
1579
XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(item->i_pos.i_total_size));
1580
IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2));
1577
if (item->i_pos.i_total_size + item_size - item->i_pos.i_item_size <= XT_INDEX_PAGE_DATA_SIZE) {
1578
/* The new item is larger than the old, this can result
1579
* in overflow of the node!
1581
memmove(&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item_size],
1582
&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size],
1583
item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size);
1584
memcpy(&iref.ir_branch->tb_data[item->i_pos.i_item_offset],
1585
item_buf, item_size);
1586
if (ind->mi_lazy_delete) {
1587
if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))
1588
iref.ir_block->cp_del_count++;
1590
item->i_pos.i_total_size = item->i_pos.i_total_size + item_size - item->i_pos.i_item_size;
1591
XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(item->i_pos.i_total_size));
1592
IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2));
1581
1593
#ifdef IND_OPT_DATA_WRITTEN
1582
iref.ir_block->cb_header = TRUE;
1583
if (item->i_pos.i_item_offset < iref.ir_block->cb_min_pos)
1584
iref.ir_block->cb_min_pos = item->i_pos.i_item_offset;
1585
iref.ir_block->cb_max_pos = item->i_pos.i_total_size;
1586
ASSERT_NS(iref.ir_block->cb_min_pos <= iref.ir_block->cb_max_pos);
1594
iref.ir_block->cb_header = TRUE;
1595
if (item->i_pos.i_item_offset < iref.ir_block->cb_min_pos)
1596
iref.ir_block->cb_min_pos = item->i_pos.i_item_offset;
1597
iref.ir_block->cb_max_pos = item->i_pos.i_total_size;
1598
ASSERT_NS(iref.ir_block->cb_min_pos <= iref.ir_block->cb_max_pos);
1588
iref.ir_updated = TRUE;
1600
iref.ir_updated = TRUE;
1591
if (ind->mi_lazy_delete)
1592
1603
ASSERT_NS(item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE);
1594
if (item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE)
1595
1605
return xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref);
1597
1608
/* The node has overflowed!! */
1598
1609
#ifdef IND_SKEW_SPLIT_ON_APPEND
1601
1612
result.sr_item = item->i_pos;
1614
memcpy(ot->ot_ind_wbuf.tb_data, iref.ir_branch->tb_data, item->i_pos.i_item_offset); // First part of the buffer
1615
memcpy(&ot->ot_ind_wbuf.tb_data[item->i_pos.i_item_offset], item_buf, item_size); // The new item
1616
memcpy(&ot->ot_ind_wbuf.tb_data[item->i_pos.i_item_offset + item_size],
1617
&iref.ir_branch->tb_data[item->i_pos.i_item_offset + item->i_pos.i_item_size],
1618
item->i_pos.i_total_size - item->i_pos.i_item_offset - item->i_pos.i_item_size);
1619
item->i_pos.i_total_size += item_size - item->i_pos.i_item_size;
1620
item->i_pos.i_item_size = item_size;
1621
XT_SET_DISK_2(ot->ot_ind_wbuf.tb_size_2, XT_MAKE_LEAF_SIZE(item->i_pos.i_total_size));
1622
IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(ot->ot_ind_wbuf.tb_size_2));
1623
ASSERT_NS(item->i_pos.i_total_size > XT_INDEX_PAGE_DATA_SIZE && item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE*2);
1603
1625
/* Adjust the stack (we want the parents of the delete node): */
1605
1627
if (idx_pop(stack) == item)
1609
1631
/* We assume that value can be overwritten (which is the case) */
1610
1632
key_value.sv_flags = XT_SEARCH_WHOLE_KEY;
1611
1633
key_value.sv_key = key_buf;
1612
if (!idx_get_middle_branch_item(ot, ind, iref.ir_branch, &key_value, &result))
1634
if (!idx_get_middle_branch_item(ot, ind, &ot->ot_ind_wbuf, &key_value, &result))
1615
1637
if (!idx_new_branch(ot, ind, &new_branch))
1629
1650
/* Change the size of the old branch: */
1630
XT_SET_DISK_2(iref.ir_branch->tb_size_2, XT_MAKE_NODE_SIZE(result.sr_item.i_item_offset));
1631
IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(iref.ir_branch->tb_size_2));
1651
XT_SET_DISK_2(ot->ot_ind_wbuf.tb_size_2, XT_MAKE_NODE_SIZE(result.sr_item.i_item_offset));
1652
IDX_TRACE("%d-> %x\n", (int) XT_NODE_ID(current), (int) XT_GET_DISK_2(ot->ot_ind_wbuf.tb_size_2));
1653
memcpy(iref.ir_branch, &ot->ot_ind_wbuf, offsetof(XTIdxBranchDRec, tb_data) + result.sr_item.i_item_offset);
1632
1654
#ifdef IND_OPT_DATA_WRITTEN
1633
1655
iref.ir_block->cb_header = TRUE;
1634
1656
if (result.sr_item.i_item_offset < iref.ir_block->cb_min_pos)
2402
2424
if (!idx_new_branch(ot, ind, &new_branch))
2427
if (XT_NODE_ID(current) == XT_NODE_ID(new_branch)) {
2428
xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
2405
2432
/* Copy and write the rest of the data to the new node: */
2406
2433
new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;
2407
2434
new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];
4344
4403
#ifdef DUMP_INDEX
4345
4404
printf("%d ", (int) XT_NODE_ID(current));
4347
if (!xt_ind_read_bytes(ot, *ind, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) {
4406
if (!xt_ind_read_bytes(ot, NULL, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) {
4348
4407
xt_log_and_clear_exception_ns();
5144
5203
if (!ilp_open_log(&il, log_id, FALSE, self))
5146
5205
if (il->il_tab_id && il->il_log_eof) {
5206
char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
5147
5208
if (!il->il_open_table(&ot))
5150
if (!il->il_apply_log_write(ot))
5152
if (!il->il_apply_log_flush(ot))
5211
xt_tab_make_table_name(ot->ot_table->tab_name, table_name, sizeof(table_name));
5212
xt_logf(XT_NT_INFO, "PBXT: Recovering index, table: %s, bytes to read: %llu\n", table_name, (u_llong) il->il_log_eof);
5213
if (!il->il_apply_log_write(ot)) {
5214
/* If recovery of an index fails, then it is corrupt! */
5215
if (ot->ot_thread->t_exception.e_xt_err != XT_ERR_NO_INDEX_CACHE)
5217
xt_tab_disable_index(ot->ot_table, XT_INDEX_CORRUPTED);
5218
xt_log_and_clear_exception_ns();
5221
if (!il->il_apply_log_flush(ot))
5154
5224
ot->ot_thread = self;
5155
5225
il->il_close_table(ot);
5697
5766
/* Corrupt log?! */
5698
5767
if (il_buffer_len < req_size) {
5699
5768
xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
5700
xt_log_and_clear_exception_ns();
5703
5771
if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread))
5907
5975
/* Corrupt log?! */
5908
5976
if (il_buffer_len < req_size) {
5909
5977
xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
5910
xt_log_and_clear_exception_ns();
5913
5980
if (!xt_pread_file(il_of, offset, il_buffer_len, il_buffer_len, il_buffer, NULL, &ot->ot_thread->st_statistics.st_ilog, ot->ot_thread))