diff options
-rw-r--r-- | src/btree/rec_write.c | 2 | ||||
-rw-r--r-- | src/include/cell.i | 26 |
2 files changed, 20 insertions, 8 deletions
diff --git a/src/btree/rec_write.c b/src/btree/rec_write.c index 5401dacca6e..05c93bbe7ca 100644 --- a/src/btree/rec_write.c +++ b/src/btree/rec_write.c @@ -744,7 +744,7 @@ __rec_dict_copy_incr(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_KV *kv) else { offset = WT_PTRDIFF32(r->first_free, dp->cell); kv->len = kv->cell_len = - __wt_cell_pack_copy(&kv->cell, offset); + __wt_cell_pack_copy(&kv->cell, 0, offset); kv->buf.data = NULL; kv->buf.size = 0; } diff --git a/src/include/cell.i b/src/include/cell.i index 9f713e53dac..79392bee6f1 100644 --- a/src/include/cell.i +++ b/src/include/cell.i @@ -198,13 +198,18 @@ __wt_cell_pack_data(WT_CELL *cell, uint64_t rle, uint32_t size) * Write a copy value cell. */ static inline uint32_t -__wt_cell_pack_copy(WT_CELL *cell, uint64_t v) +__wt_cell_pack_copy(WT_CELL *cell, uint64_t rle, uint64_t v) { uint8_t *p; p = cell->__chunk + 1; - /* Type + copy offset */ - cell->__chunk[0] = WT_CELL_VALUE_COPY | WT_CELL_64V; + + if (rle < 2) /* Type + copy offset */ + cell->__chunk[0] = WT_CELL_VALUE_COPY; + else { /* Type + RLE + copy offset */ + cell->__chunk[0] = WT_CELL_VALUE_COPY | WT_CELL_64V; + (void)__wt_vpack_uint(&p, 0, rle); + } (void)__wt_vpack_uint(&p, 0, v); return (WT_PTRDIFF32(p, cell)); @@ -371,6 +376,7 @@ __wt_cell_unpack_safe(WT_CELL *cell, WT_CELL_UNPACK *unpack, uint8_t *end) uint64_t v; const uint8_t *p; uint32_t saved_len; + uint64_t saved_v; /* * The verification code specifies an end argument, a pointer to 1 past @@ -464,15 +470,21 @@ __wt_cell_unpack_safe(WT_CELL *cell, WT_CELL_UNPACK *unpack, uint8_t *end) switch (unpack->raw) { case WT_CELL_VALUE_COPY: /* - * The cell's value is an offset to a cell written earlier in - * the page. Save and restore the length of this cell, we need - * it to step through the set of cells on the page. + * The cell is followed by an offset to a cell written earlier + * in the page. Save/restore the length and RLE of this cell, + * we need the length to step through the set of cells on the + * page and this RLE is probably different from the RLE of the + * earlier cell. */ + WT_RET(__wt_vunpack_uint( + &p, end == NULL ? 0 : (size_t)(end - p), &v)); saved_len = WT_PTRDIFF32(p, cell); - cell = (WT_CELL *)((uint8_t *)cell - unpack->v); + saved_v = unpack->v; + cell = (WT_CELL *)((uint8_t *)cell - v); ret = __wt_cell_unpack_safe(cell, unpack, end); unpack->raw = WT_CELL_VALUE_COPY; unpack->__len = saved_len; + unpack->v = saved_v; return (ret); case WT_CELL_KEY_OVFL: |