Commit ccbb93c0 authored by marko's avatar marko

branches/zip: btr_copy_externally_stored_field_prefix_low():

Split the code to subroutines.

btr_copy_blob_prefix(): New function: copy the prefix of the externally
stored part of an uncompressed BLOB.

btr_copy_zblob_prefix(): New function: copy the prefix of the externally
stored part of a compressed BLOB.

btr_blob_get_part_len(), btr_blob_get_next_page_no(): Add const qualifier
to the parameter.
parent d3d72895
...@@ -3549,7 +3549,7 @@ ulint ...@@ -3549,7 +3549,7 @@ ulint
btr_blob_get_part_len( btr_blob_get_part_len(
/*==================*/ /*==================*/
/* out: part length */ /* out: part length */
byte* blob_header) /* in: blob header */ const byte* blob_header) /* in: blob header */
{ {
return(mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN)); return(mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN));
} }
...@@ -3562,7 +3562,7 @@ btr_blob_get_next_page_no( ...@@ -3562,7 +3562,7 @@ btr_blob_get_next_page_no(
/*======================*/ /*======================*/
/* out: page number or FIL_NULL if /* out: page number or FIL_NULL if
no more pages */ no more pages */
byte* blob_header) /* in: blob header */ const byte* blob_header) /* in: blob header */
{ {
return(mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO)); return(mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO));
} }
...@@ -4170,46 +4170,88 @@ btr_rec_free_updated_extern_fields( ...@@ -4170,46 +4170,88 @@ btr_rec_free_updated_extern_fields(
} }
/*********************************************************************** /***********************************************************************
Copies the prefix of an externally stored field of a record. */ Copies the prefix of an uncompressed BLOB. */
static static
ulint ulint
btr_copy_externally_stored_field_prefix_low( btr_copy_blob_prefix(
/*========================================*/ /*=================*/
/* out: bytes written to buf */ /* out: bytes written to buf */
byte* buf, /* out: the externally stored part of byte* buf, /* out: the externally stored part of
the field, or a prefix of it */ the field, or a prefix of it */
ulint len, /* in: length of buf, in bytes */ ulint len, /* in: length of buf, in bytes */
ulint zip_size,/* in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint space_id,/* in: space id of the first BLOB page */ ulint space_id,/* in: space id of the first BLOB page */
ulint page_no,/* in: page number of the first BLOB page */ ulint page_no,/* in: page number of the first BLOB page */
ulint offset) /* in: offset on the first BLOB page */ ulint offset) /* in: offset on the first BLOB page */
{ {
ulint copied_len = 0; ulint copied_len = 0;
for (;;) {
mtr_t mtr; mtr_t mtr;
z_stream d_stream; buf_block_t* block;
const page_t* page;
const byte* blob_header;
ulint part_len;
ulint copy_len;
if (UNIV_UNLIKELY(len == 0)) { mtr_start(&mtr);
return(0);
block = buf_page_get(space_id, page_no, RW_S_LATCH, &mtr);
#ifdef UNIV_SYNC_DEBUG
buf_block_dbg_add_level(block, SYNC_EXTERN_STORAGE);
#endif /* UNIV_SYNC_DEBUG */
page = buf_block_get_frame(block);
/* Unfortunately, FIL_PAGE_TYPE was uninitialized for
many pages until MySQL/InnoDB 5.1.7. */
/* ut_ad(fil_page_get_type(page) == FIL_PAGE_TYPE_BLOB); */
blob_header = page + offset;
part_len = btr_blob_get_part_len(blob_header);
copy_len = ut_min(part_len, len - copied_len);
memcpy(buf + copied_len,
blob_header + BTR_BLOB_HDR_SIZE, copy_len);
copied_len += copy_len;
page_no = btr_blob_get_next_page_no(blob_header);
mtr_commit(&mtr);
if (page_no == FIL_NULL || copy_len != part_len) {
return(copied_len);
} }
if (UNIV_UNLIKELY(zip_size)) { /* On other BLOB pages except the first the BLOB header
int err; always is at the page data start: */
d_stream.zalloc = (alloc_func) 0;
d_stream.zfree = (free_func) 0;
d_stream.opaque = (voidpf) 0;
err = inflateInit(&d_stream); offset = FIL_PAGE_DATA;
ut_a(err == Z_OK);
d_stream.next_out = buf; ut_ad(copied_len <= len);
d_stream.avail_out = len;
d_stream.avail_in = 0;
} }
}
/***********************************************************************
Copies the prefix of a compressed BLOB. */
static
void
btr_copy_zblob_prefix(
/*==================*/
z_stream* d_stream,/* in/out: the decompressing stream */
ulint zip_size,/* in: compressed BLOB page size */
ulint space_id,/* in: space id of the first BLOB page */
ulint page_no,/* in: page number of the first BLOB page */
ulint offset) /* in: offset on the first BLOB page */
{
ut_ad(ut_is_2pow(zip_size));
ut_ad(zip_size >= PAGE_ZIP_MIN_SIZE);
ut_ad(zip_size <= UNIV_PAGE_SIZE);
ut_ad(space_id);
for (;;) { for (;;) {
mtr_t mtr;
buf_block_t* block; buf_block_t* block;
page_t* page; page_t* page;
int err;
ulint next_page_no;
mtr_start(&mtr); mtr_start(&mtr);
...@@ -4219,10 +4261,6 @@ btr_copy_externally_stored_field_prefix_low( ...@@ -4219,10 +4261,6 @@ btr_copy_externally_stored_field_prefix_low(
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
page = buf_block_get_frame(block); page = buf_block_get_frame(block);
if (UNIV_UNLIKELY(zip_size)) {
int err;
ulint next_page_no;
if (UNIV_UNLIKELY(fil_page_get_type(page) if (UNIV_UNLIKELY(fil_page_get_type(page)
!= FIL_PAGE_TYPE_ZBLOB)) { != FIL_PAGE_TYPE_ZBLOB)) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
...@@ -4245,13 +4283,13 @@ btr_copy_externally_stored_field_prefix_low( ...@@ -4245,13 +4283,13 @@ btr_copy_externally_stored_field_prefix_low(
offset += 4; offset += 4;
} }
d_stream.next_in = page + offset; d_stream->next_in = page + offset;
d_stream.avail_in = zip_size - offset; d_stream->avail_in = zip_size - offset;
err = inflate(&d_stream, Z_NO_FLUSH); err = inflate(d_stream, Z_NO_FLUSH);
switch (err) { switch (err) {
case Z_OK: case Z_OK:
if (!d_stream.avail_out) { if (!d_stream->avail_out) {
goto end_of_blob; goto end_of_blob;
} }
break; break;
...@@ -4274,7 +4312,7 @@ inflate_error: ...@@ -4274,7 +4312,7 @@ inflate_error:
} }
if (next_page_no == FIL_NULL) { if (next_page_no == FIL_NULL) {
if (!d_stream.avail_in) { if (!d_stream->avail_in) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: unexpected end of" " InnoDB: unexpected end of"
...@@ -4283,7 +4321,7 @@ inflate_error: ...@@ -4283,7 +4321,7 @@ inflate_error:
(ulong) page_no, (ulong) page_no,
(ulong) space_id); (ulong) space_id);
} else { } else {
err = inflate(&d_stream, Z_FINISH); err = inflate(d_stream, Z_FINISH);
if (UNIV_UNLIKELY if (UNIV_UNLIKELY
(err != Z_STREAM_END)) { (err != Z_STREAM_END)) {
goto inflate_error; goto inflate_error;
...@@ -4292,8 +4330,8 @@ inflate_error: ...@@ -4292,8 +4330,8 @@ inflate_error:
end_of_blob: end_of_blob:
mtr_commit(&mtr); mtr_commit(&mtr);
inflateEnd(&d_stream); inflateEnd(d_stream);
return(d_stream.total_out); return;
} }
mtr_commit(&mtr); mtr_commit(&mtr);
...@@ -4303,33 +4341,50 @@ end_of_blob: ...@@ -4303,33 +4341,50 @@ end_of_blob:
page_no = next_page_no; page_no = next_page_no;
offset = FIL_PAGE_NEXT; offset = FIL_PAGE_NEXT;
} else { }
byte* blob_header }
= page + offset;
ulint part_len
= btr_blob_get_part_len(blob_header);
ulint copy_len
= ut_min(part_len, len - copied_len);
memcpy(buf + copied_len,
blob_header + BTR_BLOB_HDR_SIZE, copy_len);
copied_len += copy_len;
page_no = btr_blob_get_next_page_no(blob_header); /***********************************************************************
Copies the prefix of an externally stored field of a record. */
static
ulint
btr_copy_externally_stored_field_prefix_low(
/*========================================*/
/* out: bytes written to buf */
byte* buf, /* out: the externally stored part of
the field, or a prefix of it */
ulint len, /* in: length of buf, in bytes */
ulint zip_size,/* in: nonzero=compressed BLOB page size,
zero for uncompressed BLOBs */
ulint space_id,/* in: space id of the first BLOB page */
ulint page_no,/* in: page number of the first BLOB page */
ulint offset) /* in: offset on the first BLOB page */
{
if (UNIV_UNLIKELY(len == 0)) {
return(0);
}
mtr_commit(&mtr); if (UNIV_UNLIKELY(zip_size)) {
int err;
z_stream d_stream;
if (page_no == FIL_NULL || copy_len != part_len) { d_stream.zalloc = (alloc_func) 0;
return(copied_len); d_stream.zfree = (free_func) 0;
} d_stream.opaque = (voidpf) 0;
/* On other BLOB pages except the first the BLOB header err = inflateInit(&d_stream);
always is at the page data start: */ ut_a(err == Z_OK);
offset = FIL_PAGE_DATA; d_stream.next_out = buf;
d_stream.avail_out = len;
d_stream.avail_in = 0;
ut_ad(copied_len <= len); btr_copy_zblob_prefix(&d_stream, zip_size,
} space_id, page_no, offset);
return(d_stream.total_out);
} else {
return(btr_copy_blob_prefix(buf, len, space_id,
page_no, offset));
} }
} }
......
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