Ticket #455: bug-455-fix.patch

File bug-455-fix.patch, 4.6 KB (added by Olly Betts, 15 years ago)

candidate fix

  • backends/chert/chert_cursor.cc

     
    5555          is_after_end(false),
    5656          tag_status(UNREAD),
    5757          B(B_),
     58          version(B_->cursor_version),
    5859          level(B_->level)
    5960{
     61    B->cursor_created_since_last_modification = true;
    6062    C = new Cursor[level + 1];
    6163
    6264    for (int j = 0; j < level; j++) {
     
    6769    C[level].p = B->C[level].p;
    6870}
    6971
     72void
     73ChertCursor::resize()
     74{
     75    int new_level = B->level;
     76    if (new_level <= level) {
     77        for (int i = 0; i < new_level; i++) {
     78            C[i].n = BLK_UNUSED;
     79        }
     80        for (int j = new_level; j < level; ++j) {
     81            delete C[j].p;
     82        }
     83    } else {
     84        Cursor * old_C = C;
     85        C = new Cursor[new_level + 1];
     86        for (int i = 0; i < level; i++) {
     87            C[i].p = old_C[i].p;
     88            C[i].n = BLK_UNUSED;
     89        }
     90        delete old_C;
     91        for (int j = level; j < new_level; j++) {
     92            C[j].p = new byte[B->block_size];
     93            C[j].n = BLK_UNUSED;
     94        }
     95    }
     96    level = new_level;
     97    C[level].n = B->C[level].n;
     98    C[level].p = B->C[level].p;
     99    version = B->cursor_version;
     100}
     101
    70102ChertCursor::~ChertCursor()
    71103{
    72104    // Use the value of level stored in the cursor rather than the
     
    81113ChertCursor::prev()
    82114{
    83115    DEBUGCALL(DB, bool, "ChertCursor::prev", "");
    84     Assert(B->level <= level);
    85116    Assert(!is_after_end);
     117    if (B->cursor_version != version) {
     118        resize();
     119        is_positioned = false;
     120    }
    86121
    87122    if (!is_positioned) {
    88123        // We've read the last key and tag, and we're now not positioned.
     
    126161ChertCursor::next()
    127162{
    128163    DEBUGCALL(DB, bool, "ChertCursor::next", "");
    129     Assert(B->level <= level);
    130164    Assert(!is_after_end);
     165    if (B->cursor_version != version) {
     166        resize();
     167        (void)find_entry(current_key);
     168    }
     169
    131170    if (tag_status == UNREAD) {
    132171        while (true) {
    133172            if (! B->next(C, 0)) {
     
    157196ChertCursor::find_entry(const string &key)
    158197{
    159198    DEBUGCALL(DB, bool, "ChertCursor::find_entry", key);
    160     Assert(B->level <= level);
     199    if (B->cursor_version != version) {
     200        resize();
     201    }
    161202
    162203    is_after_end = false;
    163204
     
    203244ChertCursor::find_entry_ge(const string &key)
    204245{
    205246    DEBUGCALL(DB, bool, "ChertCursor::find_entry_ge", key);
    206     Assert(B->level <= level);
     247    if (B->cursor_version != version) {
     248        resize();
     249    }
    207250
    208251    is_after_end = false;
    209252
  • backends/chert/chert_table.h

     
    732732        /// Set to true when the database is opened to write.
    733733        bool writable;
    734734
     735        /// Flag for tracking when cursors need to rebuild.
     736        mutable bool cursor_created_since_last_modification;
     737
     738        /// Version count for tracking when cursors need to rebuild.
     739        unsigned long cursor_version;
     740
    735741        /* B-tree navigation functions */
    736742        bool prev(Cursor *C_, int j) const {
    737743            if (sequential) return prev_for_sequential(C_, j);
  • backends/chert/chert_cursor.h

     
    7272        /// Assignment not allowed
    7373        ChertCursor & operator=(const ChertCursor &);
    7474
     75        void resize();
     76
    7577    protected:
    7678        /** Whether the cursor is positioned at a valid entry.
    7779         *
     
    9698        /// Pointer to an array of Cursors
    9799        Cursor * C;
    98100
     101        unsigned long version;
     102
    99103        /** The value of level in the Btree structure. */
    100104        int level;
    101105
  • backends/chert/chert_table.cc

     
    11381138    }
    11391139    if (!replacement) ++item_count;
    11401140    Btree_modified = true;
     1141    if (cursor_created_since_last_modification) {
     1142        cursor_created_since_last_modification = false;
     1143        ++cursor_version;
     1144    }
    11411145}
    11421146
    11431147/* ChertTable::del(key) returns false if the key is not in the B-tree,
     
    11751179
    11761180    item_count--;
    11771181    Btree_modified = true;
     1182    if (cursor_created_since_last_modification) {
     1183        cursor_created_since_last_modification = false;
     1184        ++cursor_version;
     1185    }
    11781186    RETURN(true);
    11791187}
    11801188
     
    15791587          Btree_modified(false),
    15801588          full_compaction(false),
    15811589          writable(!readonly_),
     1590          cursor_created_since_last_modification(false),
     1591          cursor_version(0),
    15821592          split_p(0),
    15831593          compress_strategy(compress_strategy_),
    15841594          deflate_zstream(NULL),