mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 21:42:35 +01:00
branches/zip: Identify records in the modification log by heap_no.
page_zip_compress(), page_zip_decompress(), page_zip_write_rec(): Note that the end marker of the modification log is 1 byte. page_zip_find_heap_no(): Remove. page_zip_apply_log(): Remove parameter "page". Instead of a 2-byte offset to the record, decode the heap number using a variable-length code. page_zip_write_rec(): Check the range of heap_no with debug assertions. Encode the heap number instead of an offset to the start of the record.
This commit is contained in:
parent
c86de5b837
commit
d1c2a0f5c1
1 changed files with 43 additions and 81 deletions
124
page/page0zip.c
124
page/page0zip.c
|
@ -496,8 +496,8 @@ page_zip_compress(
|
|||
|
||||
c_stream.next_out = buf;
|
||||
/* Subtract the space reserved for uncompressed data. */
|
||||
/* Page header, end marker of modification log */
|
||||
c_stream.avail_out = buf_end - buf - PAGE_ZIP_DIR_SLOT_SIZE;
|
||||
/* Page header and the end marker of the modification log */
|
||||
c_stream.avail_out = buf_end - buf - 1;
|
||||
/* Dense page directory and uncompressed columns, if any */
|
||||
if (page_is_leaf(page)) {
|
||||
trx_id_col = dict_index_get_sys_col_pos(index, DATA_TRX_ID);
|
||||
|
@ -644,7 +644,7 @@ page_zip_compress(
|
|||
|
||||
ut_ad(externs == c_stream.next_out
|
||||
+ c_stream.avail_out
|
||||
+ PAGE_ZIP_DIR_SLOT_SIZE/* mod log */);
|
||||
+ 1/* end of modification log */);
|
||||
|
||||
/* Copy the BLOB pointer */
|
||||
memcpy(externs, c_stream.next_in,
|
||||
|
@ -736,9 +736,10 @@ zlib_error:
|
|||
ut_ad(buf + c_stream.total_out == c_stream.next_out);
|
||||
ut_ad((ulint) (storage - c_stream.next_out) >= c_stream.avail_out);
|
||||
|
||||
/* Zero out the area reserved for the modification log */
|
||||
memset(c_stream.next_out, 0, c_stream.avail_out
|
||||
+ PAGE_ZIP_DIR_SLOT_SIZE);
|
||||
/* Zero out the area reserved for the modification log.
|
||||
Space for the end marker of the modification log is not
|
||||
included in avail_out. */
|
||||
memset(c_stream.next_out, 0, c_stream.avail_out + 1/* end marker */);
|
||||
|
||||
page_zip->m_end = page_zip->m_start = PAGE_DATA + c_stream.total_out;
|
||||
page_zip->n_blobs = n_blobs;
|
||||
|
@ -1070,55 +1071,6 @@ page_zip_set_extra_bytes(
|
|||
return(TRUE);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Find the heap number of a record by binary search in the sorted
|
||||
dense page directory. */
|
||||
static
|
||||
ulint
|
||||
page_zip_find_heap_no(
|
||||
/*==================*/
|
||||
/* out: the heap number of the smallest record
|
||||
in recs[] that is >= start; 0 if not found */
|
||||
const byte* start, /* in: start address of the record */
|
||||
rec_t** recs, /* in: dense page directory,
|
||||
sorted by address (indexed by heap_no - 2) */
|
||||
ulint n_dense)/* in: number of entries in recs[] */
|
||||
{
|
||||
ulint low = 0;
|
||||
ulint high = n_dense;
|
||||
ulint mid;
|
||||
|
||||
for (;;) {
|
||||
mid = (low + high) / 2;
|
||||
|
||||
/* 'start' should be at least REC_N_NEW_EXTRA_BYTES
|
||||
smaller than the matching entry in recs[] */
|
||||
ut_ad(start != recs[mid]);
|
||||
|
||||
if (UNIV_UNLIKELY(low == high)) {
|
||||
if (UNIV_UNLIKELY(start > recs[high])) {
|
||||
return(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (start > recs[mid]) {
|
||||
/* Too high */
|
||||
high = mid;
|
||||
} else {
|
||||
/* Either this is too low, or we found a match. */
|
||||
low = mid + 1;
|
||||
if (start > recs[low]) {
|
||||
/* The adjacent record does not match.
|
||||
This is the closest match. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(mid + 2);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Apply the modification log to an uncompressed page. */
|
||||
static
|
||||
|
@ -1129,7 +1081,6 @@ page_zip_apply_log(
|
|||
or NULL on failure */
|
||||
const byte* data, /* in: modification log */
|
||||
ulint size, /* in: maximum length of the log, in bytes */
|
||||
page_t* page, /* out: uncompressed page */
|
||||
rec_t** recs, /* in: dense page directory,
|
||||
sorted by address (indexed by heap_no - 2) */
|
||||
ulint n_dense,/* in: size of recs[] */
|
||||
|
@ -1143,30 +1094,28 @@ page_zip_apply_log(
|
|||
const byte* const end = data + size;
|
||||
|
||||
for (;;) {
|
||||
ulint start;
|
||||
ulint val;
|
||||
rec_t* rec;
|
||||
ulint len;
|
||||
ulint hs;
|
||||
|
||||
start = mach_read_from_2((byte*) data);
|
||||
if (UNIV_UNLIKELY(data + 2 >= end)) {
|
||||
return(NULL);
|
||||
}
|
||||
if (UNIV_UNLIKELY(!start)) {
|
||||
val = *data++;
|
||||
if (UNIV_UNLIKELY(!val)) {
|
||||
break;
|
||||
}
|
||||
if (UNIV_UNLIKELY(start < PAGE_ZIP_START)) {
|
||||
if (val & 0x80) {
|
||||
val = (val & 0x7f) << 7 | *data++;
|
||||
}
|
||||
if (UNIV_UNLIKELY(data >= end)) {
|
||||
return(NULL);
|
||||
}
|
||||
if (UNIV_UNLIKELY(val >= n_dense)) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
data += 2;
|
||||
|
||||
/* Determine the heap number of the record. */
|
||||
hs = page_zip_find_heap_no(page + start, recs, n_dense)
|
||||
<< REC_HEAP_NO_SHIFT;
|
||||
if (UNIV_UNLIKELY(!hs)) {
|
||||
return(NULL);
|
||||
}
|
||||
/* Determine the heap number and status bits of the record. */
|
||||
rec = recs[val - 1];
|
||||
hs = (val + 1) << REC_HEAP_NO_SHIFT;
|
||||
hs |= heap_status & ((1 << REC_HEAP_NO_SHIFT) - 1);
|
||||
|
||||
/* This may either be an old record that is being
|
||||
|
@ -1184,8 +1133,6 @@ page_zip_apply_log(
|
|||
heap_status & REC_STATUS_NODE_PTR,
|
||||
offsets);
|
||||
|
||||
rec = page + start + rec_offs_extra_size(offsets);
|
||||
|
||||
mach_write_to_2(rec - REC_NEW_HEAP_NO, hs);
|
||||
|
||||
/* Copy the extra bytes (backwards). */
|
||||
|
@ -1290,7 +1237,10 @@ page_zip_decompress(
|
|||
|
||||
/* The dense directory excludes the infimum and supremum records. */
|
||||
n_dense = page_dir_get_n_heap(page_zip->data) - 2;
|
||||
ut_a(n_dense * PAGE_ZIP_DIR_SLOT_SIZE < page_zip->size);
|
||||
if (UNIV_UNLIKELY(n_dense * PAGE_ZIP_DIR_SLOT_SIZE
|
||||
>= page_zip->size)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
heap = mem_heap_create(n_dense * (3 * sizeof *recs));
|
||||
recsc = recs = mem_heap_alloc(heap, n_dense * (2 * sizeof *recs));
|
||||
|
@ -1328,6 +1278,8 @@ page_zip_decompress(
|
|||
ut_a(err == Z_OK);
|
||||
|
||||
d_stream.next_in = page_zip->data + PAGE_DATA;
|
||||
/* Subtract the space reserved for
|
||||
the page header and the end marker of the modification log. */
|
||||
d_stream.avail_in = page_zip->size - (PAGE_DATA + 1);
|
||||
|
||||
d_stream.next_out = page + PAGE_ZIP_START;
|
||||
|
@ -1633,7 +1585,7 @@ zlib_done:
|
|||
const byte* mod_log_ptr;
|
||||
mod_log_ptr = page_zip_apply_log(
|
||||
page_zip->data + page_zip->m_start,
|
||||
d_stream.avail_in, page, recs, n_dense,
|
||||
d_stream.avail_in, recs, n_dense,
|
||||
heap_status, index, offsets);
|
||||
|
||||
if (UNIV_UNLIKELY(!mod_log_ptr)) {
|
||||
|
@ -1765,6 +1717,7 @@ page_zip_write_rec(
|
|||
page_t* page;
|
||||
byte* data;
|
||||
byte* storage;
|
||||
ulint heap_no;
|
||||
|
||||
ut_ad(buf_block_get_page_zip(buf_block_align((byte*)rec)) == page_zip);
|
||||
ut_ad(page_zip_simple_validate(page_zip));
|
||||
|
@ -1783,17 +1736,26 @@ page_zip_write_rec(
|
|||
- PAGE_DIR - PAGE_DIR_SLOT_SIZE
|
||||
* page_dir_get_n_slots(page));
|
||||
|
||||
heap_no = rec_get_heap_no_new((rec_t*) rec);
|
||||
ut_ad(heap_no >= 2); /* not infimum or supremum */
|
||||
ut_ad(heap_no < page_dir_get_n_heap(page));
|
||||
|
||||
/* Append to the modification log. */
|
||||
data = page_zip->data + page_zip->m_end;
|
||||
ut_ad(!mach_read_from_2(data));
|
||||
|
||||
{
|
||||
/* Identify the record by writing its start address. 0 is
|
||||
/* Identify the record by writing its heap number - 1. 0 is
|
||||
reserved to indicate the end of the modification log. */
|
||||
const byte* start = rec_get_start((rec_t*) rec, offsets);
|
||||
const byte* b = rec - REC_N_NEW_EXTRA_BYTES;
|
||||
|
||||
mach_write_to_2(data, ut_align_offset(start, UNIV_PAGE_SIZE));
|
||||
if (heap_no - 1 >= 128) {
|
||||
*data++ = 0x80 | (heap_no - 1) >> 7;
|
||||
} else {
|
||||
*data++ = heap_no - 1;
|
||||
}
|
||||
|
||||
/* Write the extra bytes backwards, so that
|
||||
rec_offs_extra_size() can be easily computed in
|
||||
page_zip_apply_log() by invoking
|
||||
|
@ -1847,7 +1809,7 @@ page_zip_write_rec(
|
|||
|
||||
/* Copy roll_ptr and trx_id to the uncompressed area. */
|
||||
memcpy(storage - (DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN)
|
||||
* (rec_get_heap_no_new((rec_t*) rec) - 2),
|
||||
* (heap_no - 2),
|
||||
start,
|
||||
DATA_TRX_ID_LEN + DATA_ROLL_PTR_LEN);
|
||||
ut_a(data < storage
|
||||
|
@ -1855,7 +1817,7 @@ page_zip_write_rec(
|
|||
* (page_dir_get_n_heap(page) - 2)
|
||||
- page_zip->n_blobs
|
||||
* BTR_EXTERN_FIELD_REF_SIZE
|
||||
- 2 /* for the modification log terminator */);
|
||||
- 1 /* for the modification log terminator */);
|
||||
} else {
|
||||
/* This is a node pointer page. */
|
||||
ulint len;
|
||||
|
@ -1871,13 +1833,13 @@ page_zip_write_rec(
|
|||
|
||||
/* Copy the node pointer to the uncompressed area. */
|
||||
memcpy(storage - REC_NODE_PTR_SIZE
|
||||
* (rec_get_heap_no_new((rec_t*) rec) - 2),
|
||||
* (heap_no - 2),
|
||||
rec + len,
|
||||
REC_NODE_PTR_SIZE);
|
||||
ut_a(data < storage
|
||||
- REC_NODE_PTR_SIZE
|
||||
* (page_dir_get_n_heap(page) - 2)
|
||||
- 2 /* for the modification log terminator */);
|
||||
- 1 /* for the modification log terminator */);
|
||||
}
|
||||
|
||||
page_zip->m_end = data - page_zip->data;
|
||||
|
|
Loading…
Reference in a new issue