mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 19:11:46 +01:00
branches/zip: Speed up rec_offs_any_extern() and rec_offs_n_extern()
by adding the REC_OFFS_EXTERNAL flag to rec_offs_base(offsets)[0]. This reduces the processor usage of page_zip_write_rec() by about 40% in one test case. The code could be sped up further by testing rec_offs_any_extern() outside of loops that check rec_offs_nth_extern(). The vast majority of records does not contain any externally stored columns.
This commit is contained in:
parent
645b392294
commit
8ef3075630
4 changed files with 61 additions and 46 deletions
|
@ -420,6 +420,15 @@ rec_offs_comp(
|
||||||
/* out: nonzero if compact format */
|
/* out: nonzero if compact format */
|
||||||
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
|
Determine if the offsets are for a record containing
|
||||||
|
externally stored columns. */
|
||||||
|
UNIV_INLINE
|
||||||
|
ulint
|
||||||
|
rec_offs_any_extern(
|
||||||
|
/*================*/
|
||||||
|
/* out: nonzero if externally stored */
|
||||||
|
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
||||||
|
/**********************************************************
|
||||||
Returns nonzero if the extern bit is set in nth field of rec. */
|
Returns nonzero if the extern bit is set in nth field of rec. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ulint
|
ulint
|
||||||
|
@ -448,15 +457,6 @@ rec_offs_nth_size(
|
||||||
ulint n); /* in: nth field */
|
ulint n); /* in: nth field */
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
Returns TRUE if the extern bit is set in any of the fields
|
|
||||||
of a record. */
|
|
||||||
UNIV_INLINE
|
|
||||||
ibool
|
|
||||||
rec_offs_any_extern(
|
|
||||||
/*================*/
|
|
||||||
/* out: TRUE if a field is stored externally */
|
|
||||||
const ulint* offsets);/* in: array returned by rec_get_offsets() */
|
|
||||||
/**********************************************************
|
|
||||||
Returns the number of extern bits set in a record. */
|
Returns the number of extern bits set in a record. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
ulint
|
ulint
|
||||||
|
|
|
@ -1045,6 +1045,20 @@ rec_offs_comp(
|
||||||
return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
|
return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
Determine if the offsets are for a record containing
|
||||||
|
externally stored columns. */
|
||||||
|
UNIV_INLINE
|
||||||
|
ulint
|
||||||
|
rec_offs_any_extern(
|
||||||
|
/*================*/
|
||||||
|
/* out: nonzero if externally stored */
|
||||||
|
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
||||||
|
{
|
||||||
|
ut_ad(rec_offs_validate(NULL, NULL, offsets));
|
||||||
|
return(UNIV_UNLIKELY(*rec_offs_base(offsets) & REC_OFFS_EXTERNAL));
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
Returns nonzero if the extern bit is set in nth field of rec. */
|
Returns nonzero if the extern bit is set in nth field of rec. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
@ -1093,25 +1107,6 @@ rec_offs_nth_size(
|
||||||
& REC_OFFS_MASK);
|
& REC_OFFS_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************
|
|
||||||
Returns TRUE if the extern bit is set in any of the fields
|
|
||||||
of a record. */
|
|
||||||
UNIV_INLINE
|
|
||||||
ibool
|
|
||||||
rec_offs_any_extern(
|
|
||||||
/*================*/
|
|
||||||
/* out: TRUE if a field is stored externally */
|
|
||||||
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
|
||||||
{
|
|
||||||
ulint i;
|
|
||||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
|
||||||
if (rec_offs_nth_extern(offsets, i)) {
|
|
||||||
return(TRUE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
Returns the number of extern bits set in a record. */
|
Returns the number of extern bits set in a record. */
|
||||||
UNIV_INLINE
|
UNIV_INLINE
|
||||||
|
@ -1121,13 +1116,18 @@ rec_offs_n_extern(
|
||||||
/* out: number of externally stored fields */
|
/* out: number of externally stored fields */
|
||||||
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
||||||
{
|
{
|
||||||
ulint i;
|
|
||||||
ulint n = 0;
|
ulint n = 0;
|
||||||
|
|
||||||
|
if (rec_offs_any_extern(offsets)) {
|
||||||
|
ulint i;
|
||||||
|
|
||||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
for (i = rec_offs_n_fields(offsets); i--; ) {
|
||||||
if (rec_offs_nth_extern(offsets, i)) {
|
if (rec_offs_nth_extern(offsets, i)) {
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return(n);
|
return(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,7 +1416,7 @@ rec_offs_extra_size(
|
||||||
{
|
{
|
||||||
ulint size;
|
ulint size;
|
||||||
ut_ad(rec_offs_validate(NULL, NULL, offsets));
|
ut_ad(rec_offs_validate(NULL, NULL, offsets));
|
||||||
size = *rec_offs_base(offsets) & ~REC_OFFS_COMPACT;
|
size = *rec_offs_base(offsets) & ~(REC_OFFS_COMPACT | REC_OFFS_EXTERNAL);
|
||||||
ut_ad(size < UNIV_PAGE_SIZE);
|
ut_ad(size < UNIV_PAGE_SIZE);
|
||||||
return(size);
|
return(size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2200,6 +2200,9 @@ zlib_done:
|
||||||
columns in this record. For each externally
|
columns in this record. For each externally
|
||||||
stored column, restore or clear the
|
stored column, restore or clear the
|
||||||
BTR_EXTERN_FIELD_REF. */
|
BTR_EXTERN_FIELD_REF. */
|
||||||
|
if (!rec_offs_any_extern(offsets)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
|
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
|
||||||
if (!rec_offs_nth_extern(offsets, i)) {
|
if (!rec_offs_nth_extern(offsets, i)) {
|
||||||
|
@ -3159,19 +3162,23 @@ page_zip_clear_rec(
|
||||||
/* Do not clear the record, because there is not enough space
|
/* Do not clear the record, because there is not enough space
|
||||||
to log the operation. */
|
to log the operation. */
|
||||||
|
|
||||||
|
if (rec_offs_any_extern(offsets)) {
|
||||||
ulint i;
|
ulint i;
|
||||||
|
|
||||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
for (i = rec_offs_n_fields(offsets); i--; ) {
|
||||||
/* Clear all BLOB pointers in order to make
|
/* Clear all BLOB pointers in order to make
|
||||||
page_zip_validate() pass. */
|
page_zip_validate() pass. */
|
||||||
if (rec_offs_nth_extern(offsets, i)) {
|
if (rec_offs_nth_extern(offsets, i)) {
|
||||||
ulint len;
|
ulint len;
|
||||||
byte* field = rec_get_nth_field(rec, offsets,
|
byte* field = rec_get_nth_field(
|
||||||
i, &len);
|
rec, offsets, i, &len);
|
||||||
memset(field + len - BTR_EXTERN_FIELD_REF_SIZE,
|
memset(field + len
|
||||||
|
- BTR_EXTERN_FIELD_REF_SIZE,
|
||||||
0, BTR_EXTERN_FIELD_REF_SIZE);
|
0, BTR_EXTERN_FIELD_REF_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef UNIV_ZIP_DEBUG
|
#ifdef UNIV_ZIP_DEBUG
|
||||||
ut_a(page_zip_validate(page_zip, page));
|
ut_a(page_zip_validate(page_zip, page));
|
||||||
|
|
|
@ -218,7 +218,8 @@ ulint, where rec_offs_n_fields(offsets) has been initialized to the
|
||||||
number of fields in the record. The rest of the array will be
|
number of fields in the record. The rest of the array will be
|
||||||
initialized by this function. rec_offs_base(offsets)[0] will be set
|
initialized by this function. rec_offs_base(offsets)[0] will be set
|
||||||
to the extra size (if REC_OFFS_COMPACT is set, the record is in the
|
to the extra size (if REC_OFFS_COMPACT is set, the record is in the
|
||||||
new format), and rec_offs_base(offsets)[1..n_fields] will be set to
|
new format; if REC_OFFS_EXTERNAL is set, the record contains externally
|
||||||
|
stored columns), and rec_offs_base(offsets)[1..n_fields] will be set to
|
||||||
offsets past the end of fields 0..n_fields, or to the beginning of
|
offsets past the end of fields 0..n_fields, or to the beginning of
|
||||||
fields 1..n_fields+1. When the high-order bit of the offset at [i+1]
|
fields 1..n_fields+1. When the high-order bit of the offset at [i+1]
|
||||||
is set (REC_OFFS_SQL_NULL), the field i is NULL. When the second
|
is set (REC_OFFS_SQL_NULL), the field i is NULL. When the second
|
||||||
|
@ -240,6 +241,7 @@ rec_init_offsets(
|
||||||
rec_offs_make_valid(rec, index, offsets);
|
rec_offs_make_valid(rec, index, offsets);
|
||||||
|
|
||||||
if (dict_table_is_comp(index->table)) {
|
if (dict_table_is_comp(index->table)) {
|
||||||
|
ulint any_ext;
|
||||||
const byte* nulls;
|
const byte* nulls;
|
||||||
const byte* lens;
|
const byte* lens;
|
||||||
dict_field_t* field;
|
dict_field_t* field;
|
||||||
|
@ -266,6 +268,7 @@ rec_init_offsets(
|
||||||
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
|
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
|
||||||
lens = nulls - (index->n_nullable + 7) / 8;
|
lens = nulls - (index->n_nullable + 7) / 8;
|
||||||
offs = 0;
|
offs = 0;
|
||||||
|
any_ext = 0;
|
||||||
null_mask = 1;
|
null_mask = 1;
|
||||||
|
|
||||||
/* read the lengths of fields 0..n */
|
/* read the lengths of fields 0..n */
|
||||||
|
@ -316,6 +319,7 @@ rec_init_offsets(
|
||||||
& 0x4000)) {
|
& 0x4000)) {
|
||||||
ut_ad(dict_index_is_clust
|
ut_ad(dict_index_is_clust
|
||||||
(index));
|
(index));
|
||||||
|
any_ext = REC_OFFS_EXTERNAL;
|
||||||
len = offs
|
len = offs
|
||||||
| REC_OFFS_EXTERNAL;
|
| REC_OFFS_EXTERNAL;
|
||||||
} else {
|
} else {
|
||||||
|
@ -335,7 +339,7 @@ resolved:
|
||||||
} while (++i < rec_offs_n_fields(offsets));
|
} while (++i < rec_offs_n_fields(offsets));
|
||||||
|
|
||||||
*rec_offs_base(offsets)
|
*rec_offs_base(offsets)
|
||||||
= (rec - (lens + 1)) | REC_OFFS_COMPACT;
|
= (rec - (lens + 1)) | REC_OFFS_COMPACT | any_ext;
|
||||||
} else {
|
} else {
|
||||||
/* Old-style record: determine extra size and end offsets */
|
/* Old-style record: determine extra size and end offsets */
|
||||||
offs = REC_N_OLD_EXTRA_BYTES;
|
offs = REC_N_OLD_EXTRA_BYTES;
|
||||||
|
@ -364,6 +368,7 @@ resolved:
|
||||||
if (offs & REC_2BYTE_EXTERN_MASK) {
|
if (offs & REC_2BYTE_EXTERN_MASK) {
|
||||||
offs &= ~REC_2BYTE_EXTERN_MASK;
|
offs &= ~REC_2BYTE_EXTERN_MASK;
|
||||||
offs |= REC_OFFS_EXTERNAL;
|
offs |= REC_OFFS_EXTERNAL;
|
||||||
|
*rec_offs_base(offsets) |= REC_OFFS_EXTERNAL;
|
||||||
}
|
}
|
||||||
rec_offs_base(offsets)[1 + i] = offs;
|
rec_offs_base(offsets)[1 + i] = offs;
|
||||||
} while (++i < rec_offs_n_fields(offsets));
|
} while (++i < rec_offs_n_fields(offsets));
|
||||||
|
@ -459,6 +464,7 @@ rec_get_offsets_reverse(
|
||||||
ulint n;
|
ulint n;
|
||||||
ulint i;
|
ulint i;
|
||||||
ulint offs;
|
ulint offs;
|
||||||
|
ulint any_ext;
|
||||||
const byte* nulls;
|
const byte* nulls;
|
||||||
const byte* lens;
|
const byte* lens;
|
||||||
dict_field_t* field;
|
dict_field_t* field;
|
||||||
|
@ -485,6 +491,7 @@ rec_get_offsets_reverse(
|
||||||
lens = nulls + (index->n_nullable + 7) / 8;
|
lens = nulls + (index->n_nullable + 7) / 8;
|
||||||
i = offs = 0;
|
i = offs = 0;
|
||||||
null_mask = 1;
|
null_mask = 1;
|
||||||
|
any_ext = 0;
|
||||||
|
|
||||||
/* read the lengths of fields 0..n */
|
/* read the lengths of fields 0..n */
|
||||||
do {
|
do {
|
||||||
|
@ -529,6 +536,7 @@ rec_get_offsets_reverse(
|
||||||
|
|
||||||
offs += len & 0x3fff;
|
offs += len & 0x3fff;
|
||||||
if (UNIV_UNLIKELY(len & 0x4000)) {
|
if (UNIV_UNLIKELY(len & 0x4000)) {
|
||||||
|
any_ext = REC_OFFS_EXTERNAL;
|
||||||
len = offs | REC_OFFS_EXTERNAL;
|
len = offs | REC_OFFS_EXTERNAL;
|
||||||
} else {
|
} else {
|
||||||
len = offs;
|
len = offs;
|
||||||
|
@ -548,7 +556,7 @@ resolved:
|
||||||
|
|
||||||
ut_ad(lens >= extra);
|
ut_ad(lens >= extra);
|
||||||
*rec_offs_base(offsets) = (lens - extra + REC_N_NEW_EXTRA_BYTES)
|
*rec_offs_base(offsets) = (lens - extra + REC_N_NEW_EXTRA_BYTES)
|
||||||
| REC_OFFS_COMPACT;
|
| REC_OFFS_COMPACT | any_ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
|
|
Loading…
Add table
Reference in a new issue