~mordred/ubuntu/maverick/drizzle/prerelease

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/index_xt.cc

  • Committer: Monty Taylor
  • Date: 2010-09-26 16:09:02 UTC
  • mto: This revision was merged to the branch mainline in revision 1383.
  • Revision ID: mordred@inaugust.com-20100926160902-r30v5hegk16cjk22
Tags: upstream-2010.09.1794
ImportĀ upstreamĀ versionĀ 2010.09.1794

Show diffs side-by-side

added added

removed removed

Lines of Context:
282
282
        }
283
283
 
284
284
        if ((XT_NODE_ID(wrote_pos) = XT_NODE_ID(tab->tab_ind_free))) {
 
285
                xtIndexNodeID next_node;
 
286
 
285
287
                /* Use the block on the free list: */
286
 
                if (!xt_ind_read_bytes(ot, ind, wrote_pos, sizeof(XTIndFreeBlockRec), (xtWord1 *) &free_block))
287
 
                        goto failed;
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))
 
289
                        goto failed;
 
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);
 
293
                        goto failed;
 
294
                }
 
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--;
1568
1575
        }
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++;
1577
 
        }
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));
 
1576
 
 
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!
 
1580
                 */
 
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++;
 
1589
                }
 
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);
1587
1599
#endif
1588
 
        iref.ir_updated = TRUE;
 
1600
                iref.ir_updated = TRUE;
1589
1601
 
1590
1602
#ifdef DEBUG
1591
 
        if (ind->mi_lazy_delete)
1592
1603
                ASSERT_NS(item->i_pos.i_total_size <= XT_INDEX_PAGE_DATA_SIZE);
1593
1604
#endif
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);
 
1606
        }
1596
1607
 
1597
1608
        /* The node has overflowed!! */
1598
1609
#ifdef IND_SKEW_SPLIT_ON_APPEND
1600
1611
#endif
1601
1612
        result.sr_item = item->i_pos;
1602
1613
 
 
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);
 
1624
 
1603
1625
        /* Adjust the stack (we want the parents of the delete node): */
1604
1626
        for (;;) {
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))
1613
1635
                goto failed_1;
1614
1636
 
1615
1637
        if (!idx_new_branch(ot, ind, &new_branch))
1617
1639
 
1618
1640
        /* Split the node: */
1619
1641
        new_size = result.sr_item.i_total_size - result.sr_item.i_item_offset - result.sr_item.i_item_size;
1620
 
        // TODO: Are 2 buffers now required?
1621
1642
        new_branch_ptr = (XTIdxBranchDPtr) &ot->ot_ind_wbuf.tb_data[XT_INDEX_PAGE_DATA_SIZE];
1622
1643
        memmove(new_branch_ptr->tb_data, &iref.ir_branch->tb_data[result.sr_item.i_item_offset + result.sr_item.i_item_size], new_size);
1623
1644
 
1627
1648
                goto failed_2;
1628
1649
 
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))
2403
2425
                goto failed_1;
2404
2426
 
 
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);
 
2429
                goto failed_1;
 
2430
        }
 
2431
 
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];
3077
3104
#endif
3078
3105
        ASSERT_NS(iref.ir_xlock == 2);
3079
3106
        ASSERT_NS(iref.ir_updated == 2);
 
3107
        if (ind->mi_key_corrupted) {
 
3108
                xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3109
                return FAILED;
 
3110
        }
3080
3111
        return OK;
3081
3112
 
3082
3113
        failed:
3228
3259
        //idx_check_index(ot, ind, TRUE);
3229
3260
        //idx_check_on_key(ot);
3230
3261
#endif
 
3262
        if (ind->mi_key_corrupted) {
 
3263
                xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3264
                return FAILED;
 
3265
        }
3231
3266
        return OK;
3232
3267
 
3233
3268
        failed:
3318
3353
 
3319
3354
        if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) {
3320
3355
                XT_INDEX_UNLOCK(ind, ot);
 
3356
                if (ind->mi_key_corrupted) {
 
3357
                        xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3358
                        return FAILED;
 
3359
                }
3321
3360
                return OK;
3322
3361
        }
3323
3362
 
3425
3464
                ot->ot_curr_rec_id = 0;
3426
3465
                ot->ot_curr_row_id = 0;
3427
3466
                XT_INDEX_UNLOCK(ind, ot);
 
3467
                if (ind->mi_key_corrupted) {
 
3468
                        xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3469
                        return FAILED;
 
3470
                }
3428
3471
                return OK;
3429
3472
        }
3430
3473
 
3466
3509
        ot->ot_curr_row_id = result.sr_row_id;
3467
3510
        ot->ot_ind_state = result.sr_item;
3468
3511
 
 
3512
        if (ind->mi_key_corrupted) {
 
3513
                xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3514
                return FAILED;
 
3515
        }
3469
3516
        return OK;
3470
3517
 
3471
3518
        failed:
3532
3579
 
3533
3580
        if (!(XT_NODE_ID(current) = XT_NODE_ID(ind->mi_root))) {
3534
3581
                XT_INDEX_UNLOCK(ind, ot);
 
3582
                if (ind->mi_key_corrupted) {
 
3583
                        xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3584
                        return FAILED;
 
3585
                }
3535
3586
                return OK;
3536
3587
        }
3537
3588
 
3628
3679
        ot->ot_curr_row_id = 0;
3629
3680
 
3630
3681
        XT_INDEX_UNLOCK(ind, ot);
 
3682
        if (ind->mi_key_corrupted) {
 
3683
                xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3684
                return FAILED;
 
3685
        }
3631
3686
        return OK;
3632
3687
 
3633
3688
        unlock_check_on_key:
3656
3711
        ot->ot_curr_rec_id = result.sr_rec_id;
3657
3712
        ot->ot_curr_row_id = result.sr_row_id;
3658
3713
        ot->ot_ind_state = result.sr_item;
 
3714
        if (ind->mi_key_corrupted) {
 
3715
                xt_register_taberr(XT_REG_CONTEXT, XT_ERR_INDEX_CORRUPTED, ot->ot_table->tab_name);
 
3716
                return FAILED;
 
3717
        }
3659
3718
        return OK;
3660
3719
 
3661
3720
        failed:
4344
4403
#ifdef DUMP_INDEX
4345
4404
                        printf("%d ", (int) XT_NODE_ID(current));
4346
4405
#endif
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();
4349
4408
                                break;
4350
4409
                        }
5144
5203
                                        if (!ilp_open_log(&il, log_id, FALSE, self))
5145
5204
                                                goto failed;
5146
5205
                                        if (il->il_tab_id && il->il_log_eof) {
 
5206
                                                char table_name[XT_IDENTIFIER_NAME_SIZE*3+3];
 
5207
 
5147
5208
                                                if (!il->il_open_table(&ot))
5148
5209
                                                        goto failed;
5149
5210
                                                if (ot) {
5150
 
                                                        if (!il->il_apply_log_write(ot))
5151
 
                                                                goto failed;
5152
 
                                                        if (!il->il_apply_log_flush(ot))
5153
 
                                                                goto failed;
 
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)
 
5216
                                                                        goto failed;
 
5217
                                                                xt_tab_disable_index(ot->ot_table, XT_INDEX_CORRUPTED);
 
5218
                                                                xt_log_and_clear_exception_ns();
 
5219
                                                        }
 
5220
                                                        else {
 
5221
                                                                if (!il->il_apply_log_flush(ot))
 
5222
                                                                        goto failed;
 
5223
                                                        }
5154
5224
                                                        ot->ot_thread = self;
5155
5225
                                                        il->il_close_table(ot);
5156
5226
                                                }
5164
5234
        return;
5165
5235
 
5166
5236
        failed:
5167
 
        /* TODO: Mark index as corrupted: */
5168
5237
        if (ot && il)
5169
5238
                il->il_close_table(ot);
5170
5239
        if (il)
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();
5701
 
                                return OK;
 
5769
                                return FAILED;
5702
5770
                        }
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))
5704
5772
                                return FAILED;
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();
5911
 
                                                        return OK;
 
5978
                                                        return FAILED;
5912
5979
                                                }
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))
5914
5981
                                                        return FAILED;
5997
6064
                                break;
5998
6065
                        default:
5999
6066
                                xt_register_ixterr(XT_REG_CONTEXT, XT_ERR_INDEX_LOG_CORRUPT, xt_file_path(il_of));
6000
 
                                xt_log_and_clear_exception_ns();
6001
 
                                return OK;
 
6067
                                return FAILED;
6002
6068
                }
6003
6069
#ifdef CHECK_IF_WRITE_WAS_OK
6004
6070
                if (node_id) {