mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 05:22:25 +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 */
|
||||
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. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
|
@ -448,15 +457,6 @@ rec_offs_nth_size(
|
|||
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. */
|
||||
UNIV_INLINE
|
||||
ulint
|
||||
|
|
|
@ -1045,6 +1045,20 @@ rec_offs_comp(
|
|||
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. */
|
||||
UNIV_INLINE
|
||||
|
@ -1093,25 +1107,6 @@ rec_offs_nth_size(
|
|||
& 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. */
|
||||
UNIV_INLINE
|
||||
|
@ -1121,13 +1116,18 @@ rec_offs_n_extern(
|
|||
/* out: number of externally stored fields */
|
||||
const ulint* offsets)/* in: array returned by rec_get_offsets() */
|
||||
{
|
||||
ulint i;
|
||||
ulint n = 0;
|
||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
||||
if (rec_offs_nth_extern(offsets, i)) {
|
||||
n++;
|
||||
|
||||
if (rec_offs_any_extern(offsets)) {
|
||||
ulint i;
|
||||
|
||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
||||
if (rec_offs_nth_extern(offsets, i)) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(n);
|
||||
}
|
||||
|
||||
|
@ -1416,7 +1416,7 @@ rec_offs_extra_size(
|
|||
{
|
||||
ulint size;
|
||||
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);
|
||||
return(size);
|
||||
}
|
||||
|
|
|
@ -2200,6 +2200,9 @@ zlib_done:
|
|||
columns in this record. For each externally
|
||||
stored column, restore or clear the
|
||||
BTR_EXTERN_FIELD_REF. */
|
||||
if (!rec_offs_any_extern(offsets)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (i = 0; i < rec_offs_n_fields(offsets); i++) {
|
||||
if (!rec_offs_nth_extern(offsets, i)) {
|
||||
|
@ -3159,16 +3162,20 @@ page_zip_clear_rec(
|
|||
/* Do not clear the record, because there is not enough space
|
||||
to log the operation. */
|
||||
|
||||
ulint i;
|
||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
||||
/* Clear all BLOB pointers in order to make
|
||||
page_zip_validate() pass. */
|
||||
if (rec_offs_nth_extern(offsets, i)) {
|
||||
ulint len;
|
||||
byte* field = rec_get_nth_field(rec, offsets,
|
||||
i, &len);
|
||||
memset(field + len - BTR_EXTERN_FIELD_REF_SIZE,
|
||||
0, BTR_EXTERN_FIELD_REF_SIZE);
|
||||
if (rec_offs_any_extern(offsets)) {
|
||||
ulint i;
|
||||
|
||||
for (i = rec_offs_n_fields(offsets); i--; ) {
|
||||
/* Clear all BLOB pointers in order to make
|
||||
page_zip_validate() pass. */
|
||||
if (rec_offs_nth_extern(offsets, i)) {
|
||||
ulint len;
|
||||
byte* field = rec_get_nth_field(
|
||||
rec, offsets, i, &len);
|
||||
memset(field + len
|
||||
- BTR_EXTERN_FIELD_REF_SIZE,
|
||||
0, BTR_EXTERN_FIELD_REF_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -240,6 +241,7 @@ rec_init_offsets(
|
|||
rec_offs_make_valid(rec, index, offsets);
|
||||
|
||||
if (dict_table_is_comp(index->table)) {
|
||||
ulint any_ext;
|
||||
const byte* nulls;
|
||||
const byte* lens;
|
||||
dict_field_t* field;
|
||||
|
@ -266,6 +268,7 @@ rec_init_offsets(
|
|||
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
|
||||
lens = nulls - (index->n_nullable + 7) / 8;
|
||||
offs = 0;
|
||||
any_ext = 0;
|
||||
null_mask = 1;
|
||||
|
||||
/* read the lengths of fields 0..n */
|
||||
|
@ -316,6 +319,7 @@ rec_init_offsets(
|
|||
& 0x4000)) {
|
||||
ut_ad(dict_index_is_clust
|
||||
(index));
|
||||
any_ext = REC_OFFS_EXTERNAL;
|
||||
len = offs
|
||||
| REC_OFFS_EXTERNAL;
|
||||
} else {
|
||||
|
@ -335,7 +339,7 @@ resolved:
|
|||
} while (++i < rec_offs_n_fields(offsets));
|
||||
|
||||
*rec_offs_base(offsets)
|
||||
= (rec - (lens + 1)) | REC_OFFS_COMPACT;
|
||||
= (rec - (lens + 1)) | REC_OFFS_COMPACT | any_ext;
|
||||
} else {
|
||||
/* Old-style record: determine extra size and end offsets */
|
||||
offs = REC_N_OLD_EXTRA_BYTES;
|
||||
|
@ -364,6 +368,7 @@ resolved:
|
|||
if (offs & REC_2BYTE_EXTERN_MASK) {
|
||||
offs &= ~REC_2BYTE_EXTERN_MASK;
|
||||
offs |= REC_OFFS_EXTERNAL;
|
||||
*rec_offs_base(offsets) |= REC_OFFS_EXTERNAL;
|
||||
}
|
||||
rec_offs_base(offsets)[1 + i] = offs;
|
||||
} while (++i < rec_offs_n_fields(offsets));
|
||||
|
@ -459,6 +464,7 @@ rec_get_offsets_reverse(
|
|||
ulint n;
|
||||
ulint i;
|
||||
ulint offs;
|
||||
ulint any_ext;
|
||||
const byte* nulls;
|
||||
const byte* lens;
|
||||
dict_field_t* field;
|
||||
|
@ -485,6 +491,7 @@ rec_get_offsets_reverse(
|
|||
lens = nulls + (index->n_nullable + 7) / 8;
|
||||
i = offs = 0;
|
||||
null_mask = 1;
|
||||
any_ext = 0;
|
||||
|
||||
/* read the lengths of fields 0..n */
|
||||
do {
|
||||
|
@ -529,6 +536,7 @@ rec_get_offsets_reverse(
|
|||
|
||||
offs += len & 0x3fff;
|
||||
if (UNIV_UNLIKELY(len & 0x4000)) {
|
||||
any_ext = REC_OFFS_EXTERNAL;
|
||||
len = offs | REC_OFFS_EXTERNAL;
|
||||
} else {
|
||||
len = offs;
|
||||
|
@ -548,7 +556,7 @@ resolved:
|
|||
|
||||
ut_ad(lens >= extra);
|
||||
*rec_offs_base(offsets) = (lens - extra + REC_N_NEW_EXTRA_BYTES)
|
||||
| REC_OFFS_COMPACT;
|
||||
| REC_OFFS_COMPACT | any_ext;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
|
Loading…
Reference in a new issue