Commit a18381a9 authored by marko's avatar marko

branches/zip: page_zip_decompress_clust(): Optimize the case when the

record does not contain externally stored columns.

page_zip_decompress_clust_ext(): New function for decompressing records
containing externally stored columns.
parent 0af6d909
...@@ -2075,6 +2075,107 @@ page_zip_decompress_sec( ...@@ -2075,6 +2075,107 @@ page_zip_decompress_sec(
return(TRUE); return(TRUE);
} }
/**************************************************************************
Decompress a record of a leaf node of a clustered index that contains
externally stored columns. */
static
ibool
page_zip_decompress_clust_ext(
/*==========================*/
/* out: TRUE on success */
z_stream* d_stream, /* in/out: compressed page stream */
rec_t* rec, /* in/out: record */
const ulint* offsets, /* in: rec_get_offsets(rec) */
ulint trx_id_col) /* in: position of of DB_TRX_ID */
{
ulint i;
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
ulint len;
byte* dst;
if (UNIV_UNLIKELY(i == trx_id_col)) {
/* Skip trx_id and roll_ptr */
dst = rec_get_nth_field(rec, offsets, i, &len);
if (UNIV_UNLIKELY(len < DATA_TRX_ID_LEN
+ DATA_ROLL_PTR_LEN)
|| rec_offs_nth_extern(offsets, i)) {
return(FALSE);
}
d_stream->avail_out = dst - d_stream->next_out;
switch (inflate(d_stream, Z_SYNC_FLUSH)) {
case Z_STREAM_END:
case Z_OK:
case Z_BUF_ERROR:
if (!d_stream->avail_out) {
break;
}
/* fall through */
default:
return(FALSE);
}
ut_ad(d_stream->next_out == dst);
d_stream->next_out += DATA_TRX_ID_LEN
+ DATA_ROLL_PTR_LEN;
} else if (rec_offs_nth_extern(offsets, i)) {
dst = rec_get_nth_field(rec, offsets, i, &len);
ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
dst += len - BTR_EXTERN_FIELD_REF_SIZE;
d_stream->avail_out = dst - d_stream->next_out;
switch (inflate(d_stream,
Z_SYNC_FLUSH)) {
case Z_STREAM_END:
case Z_OK:
case Z_BUF_ERROR:
if (!d_stream->avail_out) {
break;
}
/* fall through */
default:
return(FALSE);
}
ut_ad(d_stream->next_out == dst);
/* Reserve space for the data at
the end of the space reserved for
the compressed data and the
page modification log. */
if (UNIV_UNLIKELY
(d_stream->avail_in
<= BTR_EXTERN_FIELD_REF_SIZE)) {
/* out of space */
return(FALSE);
}
/* Clear the BLOB pointer in case
the record will be deleted and the
space will not be reused. Note that
the final initialization of the BLOB
pointers (copying from "externs"
or clearing) will have to take place
only after the page modification log
has been applied. Otherwise, we
could end up with an uninitialized
BLOB pointer when a record is deleted,
reallocated and deleted. */
memset(d_stream->next_out, 0,
BTR_EXTERN_FIELD_REF_SIZE);
d_stream->next_out
+= BTR_EXTERN_FIELD_REF_SIZE;
}
}
return(TRUE);
}
/************************************************************************** /**************************************************************************
Compress the records of a leaf node of a clustered index. */ Compress the records of a leaf node of a clustered index. */
static static
...@@ -2108,7 +2209,6 @@ page_zip_decompress_clust( ...@@ -2108,7 +2209,6 @@ page_zip_decompress_clust(
/* Decompress the records in heap_no order. */ /* Decompress the records in heap_no order. */
for (slot = 0; slot < n_dense; slot++) { for (slot = 0; slot < n_dense; slot++) {
rec_t* rec = recs[slot]; rec_t* rec = recs[slot];
ulint i;
d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES d_stream->avail_out = rec - REC_N_NEW_EXTRA_BYTES
- d_stream->next_out; - d_stream->next_out;
...@@ -2148,87 +2248,42 @@ page_zip_decompress_clust( ...@@ -2148,87 +2248,42 @@ page_zip_decompress_clust(
For each externally stored column, restore the For each externally stored column, restore the
BTR_EXTERN_FIELD_REF separately. */ BTR_EXTERN_FIELD_REF separately. */
for (i = 0; i < rec_offs_n_fields(offsets); i++) { if (UNIV_UNLIKELY(rec_offs_any_extern(offsets))) {
ulint len; if (UNIV_UNLIKELY
byte* dst; (!page_zip_decompress_clust_ext(
d_stream, rec, offsets, trx_id_col))) {
if (UNIV_UNLIKELY(i == trx_id_col)) { goto zlib_error;
/* Skip trx_id and roll_ptr */ }
dst = rec_get_nth_field(rec, offsets, i, &len); } else {
if (UNIV_UNLIKELY(len < DATA_TRX_ID_LEN /* Skip trx_id and roll_ptr */
+ DATA_ROLL_PTR_LEN) ulint len;
|| rec_offs_nth_extern(offsets, i)) { byte* dst = rec_get_nth_field(rec, offsets,
trx_id_col, &len);
if (UNIV_UNLIKELY(len < DATA_TRX_ID_LEN
+ DATA_ROLL_PTR_LEN)) {
goto zlib_error; goto zlib_error;
} }
d_stream->avail_out = dst - d_stream->next_out; d_stream->avail_out = dst - d_stream->next_out;
switch (inflate(d_stream, Z_SYNC_FLUSH)) {
case Z_STREAM_END:
case Z_OK:
case Z_BUF_ERROR:
if (!d_stream->avail_out) {
break;
}
/* fall through */
default:
goto zlib_error;
}
ut_ad(d_stream->next_out == dst); switch (inflate(d_stream, Z_SYNC_FLUSH)) {
case Z_STREAM_END:
d_stream->next_out += DATA_TRX_ID_LEN case Z_OK:
+ DATA_ROLL_PTR_LEN; case Z_BUF_ERROR:
} else if (rec_offs_nth_extern(offsets, i)) { if (!d_stream->avail_out) {
dst = rec_get_nth_field(rec, offsets, i, &len); break;
ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
dst += len - BTR_EXTERN_FIELD_REF_SIZE;
d_stream->avail_out = dst - d_stream->next_out;
switch (inflate(d_stream,
Z_SYNC_FLUSH)) {
case Z_STREAM_END:
case Z_OK:
case Z_BUF_ERROR:
if (!d_stream->avail_out) {
break;
}
/* fall through */
default:
goto zlib_error;
} }
/* fall through */
default:
goto zlib_error;
}
ut_ad(d_stream->next_out == dst); ut_ad(d_stream->next_out == dst);
/* Reserve space for the data at
the end of the space reserved for
the compressed data and the
page modification log. */
if (UNIV_UNLIKELY
(d_stream->avail_in
<= BTR_EXTERN_FIELD_REF_SIZE)) {
/* out of space */
goto zlib_error;
}
/* Clear the BLOB pointer in case d_stream->next_out += DATA_TRX_ID_LEN
the record will be deleted and the + DATA_ROLL_PTR_LEN;
space will not be reused. Note that
the final initialization of the BLOB
pointers (copying from "externs"
or clearing) will have to take place
only after the page modification log
has been applied. Otherwise, we
could end up with an uninitialized
BLOB pointer when a record is deleted,
reallocated and deleted. */
memset(d_stream->next_out, 0,
BTR_EXTERN_FIELD_REF_SIZE);
d_stream->next_out
+= BTR_EXTERN_FIELD_REF_SIZE;
}
} }
/* Decompress the last bytes of the record. */ /* Decompress the last bytes of the record. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment