15
15
* You should have received a copy of the GNU General Public License
16
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
19
* 2005-09-30 Paul McCullagh
284
284
if ((XT_NODE_ID(wrote_pos) = XT_NODE_ID(tab->tab_ind_free))) {
285
xtIndexNodeID next_node;
287
285
/* Use the block on the free list: */
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);
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);
296
289
xt_unlock_mutex_ns(&tab->tab_ind_lock);
297
290
*address = wrote_pos;
298
291
TRACK_BLOCK_ALLOC(wrote_pos);
1573
1566
if (idx_is_item_deleted(iref.ir_branch, &item->i_pos))
1574
1567
iref.ir_block->cp_del_count--;
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));
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));
1593
1581
#ifdef IND_OPT_DATA_WRITTEN
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);
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);
1600
iref.ir_updated = TRUE;
1588
iref.ir_updated = TRUE;
1591
if (ind->mi_lazy_delete)
1603
1592
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)
1605
1595
return xt_ind_release(ot, ind, XT_UNLOCK_W_UPDATE, &iref);
1608
1597
/* The node has overflowed!! */
1609
1598
#ifdef IND_SKEW_SPLIT_ON_APPEND
1612
1601
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);
1625
1603
/* Adjust the stack (we want the parents of the delete node): */
1627
1605
if (idx_pop(stack) == item)
1631
1609
/* We assume that value can be overwritten (which is the case) */
1632
1610
key_value.sv_flags = XT_SEARCH_WHOLE_KEY;
1633
1611
key_value.sv_key = key_buf;
1634
if (!idx_get_middle_branch_item(ot, ind, &ot->ot_ind_wbuf, &key_value, &result))
1612
if (!idx_get_middle_branch_item(ot, ind, iref.ir_branch, &key_value, &result))
1637
1615
if (!idx_new_branch(ot, ind, &new_branch))
1650
1629
/* Change the size of the old branch: */
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);
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));
1654
1632
#ifdef IND_OPT_DATA_WRITTEN
1655
1633
iref.ir_block->cb_header = TRUE;
1656
1634
if (result.sr_item.i_item_offset < iref.ir_block->cb_min_pos)
2424
2402
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);
2432
2405
/* Copy and write the rest of the data to the new node: */
2433
2406
new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;
2434
2407
new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];
4403
4344
#ifdef DUMP_INDEX
4404
4345
printf("%d ", (int) XT_NODE_ID(current));
4406
if (!xt_ind_read_bytes(ot, NULL, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) {
4347
if (!xt_ind_read_bytes(ot, *ind, current, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block)) {
4407
4348
xt_log_and_clear_exception_ns();
5203
5144
if (!ilp_open_log(&il, log_id, FALSE, self))
5205
5146
if (il->il_tab_id && il->il_log_eof) {
5206
char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
5208
5147
if (!il->il_open_table(&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))
5150
if (!il->il_apply_log_write(ot))
5152
if (!il->il_apply_log_flush(ot))
5224
5154
ot->ot_thread = self;
5225
5155
il->il_close_table(ot);
5766
5697
/* Corrupt log?! */
5767
5698
if (il_buffer_len < req_size) {
5768
5699
xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
5700
xt_log_and_clear_exception_ns();
5771
5703
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))
5975
5907
/* Corrupt log?! */
5976
5908
if (il_buffer_len < req_size) {
5977
5909
xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
5910
xt_log_and_clear_exception_ns();
5980
5913
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))