MDEV-30567 rec_get_offsets() is not optimal
rec_init_offsets_comp_ordinary(), rec_init_offsets(), rec_get_offsets_reverse(), rec_get_nth_field_offs_old(): Simplify some bitwise arithmetics to avoid conditional jumps, and add branch prediction hints with the assumption that most variable-length columns are short. Tested by: Matthias Leich
This commit is contained in:
parent
99ee200b8b
commit
66b21ed540
@ -217,14 +217,12 @@ rec_get_n_extern_new(
|
|||||||
stored in one byte for 0..127. The length
|
stored in one byte for 0..127. The length
|
||||||
will be encoded in two bytes when it is 128 or
|
will be encoded in two bytes when it is 128 or
|
||||||
more, or when the field is stored externally. */
|
more, or when the field is stored externally. */
|
||||||
if (DATA_BIG_COL(col)) {
|
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||||
if (len & 0x80) {
|
/* 1exxxxxxx xxxxxxxx */
|
||||||
/* 1exxxxxxx xxxxxxxx */
|
if (len & 0x40) {
|
||||||
if (len & 0x40) {
|
n_extern++;
|
||||||
n_extern++;
|
|
||||||
}
|
|
||||||
lens--;
|
|
||||||
}
|
}
|
||||||
|
lens--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (++i < n);
|
} while (++i < n);
|
||||||
@ -432,24 +430,21 @@ start:
|
|||||||
stored in one byte for 0..127. The length
|
stored in one byte for 0..127. The length
|
||||||
will be encoded in two bytes when it is 128 or
|
will be encoded in two bytes when it is 128 or
|
||||||
more, or when the field is stored externally. */
|
more, or when the field is stored externally. */
|
||||||
if ((len & 0x80) && DATA_BIG_COL(col)) {
|
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||||
/* 1exxxxxxx xxxxxxxx */
|
/* 1exxxxxxx xxxxxxxx */
|
||||||
len <<= 8;
|
len <<= 8;
|
||||||
len |= *lens--;
|
len |= *lens--;
|
||||||
|
static_assert(STORED_OFFPAGE == 0x4000, "");
|
||||||
|
static_assert(REC_OFFS_EXTERNAL == 0x4000, "");
|
||||||
|
const rec_offs ext = len & REC_OFFS_EXTERNAL;
|
||||||
offs += get_value(len);
|
offs += get_value(len);
|
||||||
if (UNIV_UNLIKELY(len & 0x4000)) {
|
len = offs | ext;
|
||||||
ut_ad(dict_index_is_clust(index));
|
any |= ext;
|
||||||
any |= REC_OFFS_EXTERNAL;
|
ut_ad(!ext || index->is_primary());
|
||||||
len = combine(offs, STORED_OFFPAGE);
|
|
||||||
} else {
|
|
||||||
len = offs;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = offs += len;
|
len = offs += static_cast<rec_offs>(len);
|
||||||
} else {
|
} else {
|
||||||
len = offs += field->fixed_len;
|
len = offs += field->fixed_len;
|
||||||
}
|
}
|
||||||
@ -714,23 +709,20 @@ rec_init_offsets(
|
|||||||
encoded in two bytes when it is 128 or
|
encoded in two bytes when it is 128 or
|
||||||
more, or when the field is stored
|
more, or when the field is stored
|
||||||
externally. */
|
externally. */
|
||||||
if (DATA_BIG_COL(col)) {
|
if (UNIV_UNLIKELY(len & 0x80)
|
||||||
if (len & 0x80) {
|
&& DATA_BIG_COL(col)) {
|
||||||
/* 1exxxxxxx xxxxxxxx */
|
/* 1exxxxxxx xxxxxxxx */
|
||||||
|
len <<= 8;
|
||||||
|
len |= *lens--;
|
||||||
|
|
||||||
len <<= 8;
|
/* B-tree node pointers
|
||||||
len |= *lens--;
|
must not contain externally
|
||||||
|
stored columns. Thus
|
||||||
/* B-tree node pointers
|
the "e" flag must be 0. */
|
||||||
must not contain externally
|
ut_a(!(len & 0x4000));
|
||||||
stored columns. Thus
|
offs += len & 0x3fff;
|
||||||
the "e" flag must be 0. */
|
len = offs;
|
||||||
ut_a(!(len & 0x4000));
|
goto resolved;
|
||||||
offs += get_value(len);
|
|
||||||
len = offs;
|
|
||||||
|
|
||||||
goto resolved;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = offs += len;
|
len = offs += len;
|
||||||
@ -758,26 +750,24 @@ resolved:
|
|||||||
do {
|
do {
|
||||||
offs = rec_1_get_field_end_info(rec, i);
|
offs = rec_1_get_field_end_info(rec, i);
|
||||||
if (offs & REC_1BYTE_SQL_NULL_MASK) {
|
if (offs & REC_1BYTE_SQL_NULL_MASK) {
|
||||||
offs &= ~REC_1BYTE_SQL_NULL_MASK;
|
offs ^= REC_1BYTE_SQL_NULL_MASK
|
||||||
set_type(offs, SQL_NULL);
|
| SQL_NULL;
|
||||||
}
|
}
|
||||||
rec_offs_base(offsets)[1 + i] = offs;
|
rec_offs_base(offsets)[1 + i] = offs;
|
||||||
} while (++i < n);
|
} while (++i < n);
|
||||||
} else {
|
} else {
|
||||||
offs += 2 * static_cast<rec_offs>(n_fields);
|
offs += static_cast<rec_offs>(2 * n_fields);
|
||||||
any = offs;
|
any = offs;
|
||||||
/* Determine offsets to fields */
|
/* Determine offsets to fields */
|
||||||
do {
|
do {
|
||||||
offs = rec_2_get_field_end_info(rec, i);
|
offs = rec_2_get_field_end_info(rec, i);
|
||||||
if (offs & REC_2BYTE_SQL_NULL_MASK) {
|
static_assert(REC_2BYTE_SQL_NULL_MASK
|
||||||
offs &= ~REC_2BYTE_SQL_NULL_MASK;
|
== SQL_NULL, "");
|
||||||
set_type(offs, SQL_NULL);
|
static_assert(REC_2BYTE_EXTERN_MASK
|
||||||
}
|
== STORED_OFFPAGE, "");
|
||||||
if (offs & REC_2BYTE_EXTERN_MASK) {
|
static_assert(REC_OFFS_EXTERNAL
|
||||||
offs &= ~REC_2BYTE_EXTERN_MASK;
|
== STORED_OFFPAGE, "");
|
||||||
set_type(offs, STORED_OFFPAGE);
|
any |= (offs & REC_OFFS_EXTERNAL);
|
||||||
any |= REC_OFFS_EXTERNAL;
|
|
||||||
}
|
|
||||||
rec_offs_base(offsets)[1 + i] = offs;
|
rec_offs_base(offsets)[1 + i] = offs;
|
||||||
} while (++i < n);
|
} while (++i < n);
|
||||||
}
|
}
|
||||||
@ -1028,23 +1018,18 @@ rec_get_offsets_reverse(
|
|||||||
stored in one byte for 0..127. The length
|
stored in one byte for 0..127. The length
|
||||||
will be encoded in two bytes when it is 128 or
|
will be encoded in two bytes when it is 128 or
|
||||||
more, or when the field is stored externally. */
|
more, or when the field is stored externally. */
|
||||||
if (DATA_BIG_COL(col)) {
|
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||||
if (len & 0x80) {
|
/* 1exxxxxxx xxxxxxxx */
|
||||||
/* 1exxxxxxx xxxxxxxx */
|
len &= 0x7f;
|
||||||
len <<= 8;
|
len <<= 8;
|
||||||
len |= *lens++;
|
len |= *lens++;
|
||||||
|
static_assert(STORED_OFFPAGE == 0x4000, "");
|
||||||
offs += get_value(len);
|
static_assert(REC_OFFS_EXTERNAL == 0x4000, "");
|
||||||
if (UNIV_UNLIKELY(len & 0x4000)) {
|
rec_offs ext = len & REC_OFFS_EXTERNAL;
|
||||||
any_ext = REC_OFFS_EXTERNAL;
|
offs += get_value(len);
|
||||||
len = combine(offs,
|
len = offs | ext;
|
||||||
STORED_OFFPAGE);
|
any_ext |= ext;
|
||||||
} else {
|
goto resolved;
|
||||||
len = offs;
|
|
||||||
}
|
|
||||||
|
|
||||||
goto resolved;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
len = offs += len;
|
len = offs += len;
|
||||||
@ -1089,7 +1074,7 @@ rec_get_nth_field_offs_old(
|
|||||||
return(os);
|
return(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
next_os = next_os & ~REC_1BYTE_SQL_NULL_MASK;
|
next_os &= ~REC_1BYTE_SQL_NULL_MASK;
|
||||||
} else {
|
} else {
|
||||||
os = rec_2_get_field_start_offs(rec, n);
|
os = rec_2_get_field_start_offs(rec, n);
|
||||||
|
|
||||||
@ -1101,8 +1086,7 @@ rec_get_nth_field_offs_old(
|
|||||||
return(os);
|
return(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
next_os = next_os & ~(REC_2BYTE_SQL_NULL_MASK
|
next_os &= ~(REC_2BYTE_SQL_NULL_MASK | REC_2BYTE_EXTERN_MASK);
|
||||||
| REC_2BYTE_EXTERN_MASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*len = next_os - os;
|
*len = next_os - os;
|
||||||
@ -1255,7 +1239,8 @@ rec_get_converted_size_comp_prefix_low(
|
|||||||
} else if (dfield_is_ext(dfield)) {
|
} else if (dfield_is_ext(dfield)) {
|
||||||
ut_ad(DATA_BIG_COL(field->col));
|
ut_ad(DATA_BIG_COL(field->col));
|
||||||
extra_size += 2;
|
extra_size += 2;
|
||||||
} else if (len < 128 || !DATA_BIG_COL(field->col)) {
|
} else if (UNIV_LIKELY(len < 128)
|
||||||
|
|| !DATA_BIG_COL(field->col)) {
|
||||||
extra_size++;
|
extra_size++;
|
||||||
} else {
|
} else {
|
||||||
/* For variable-length columns, we look up the
|
/* For variable-length columns, we look up the
|
||||||
@ -1652,7 +1637,7 @@ start:
|
|||||||
|
|
||||||
/* set the null flag if necessary */
|
/* set the null flag if necessary */
|
||||||
if (dfield_is_null(field)) {
|
if (dfield_is_null(field)) {
|
||||||
*nulls |= null_mask;
|
*nulls |= static_cast<byte>(null_mask);
|
||||||
null_mask <<= 1;
|
null_mask <<= 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2122,14 +2107,12 @@ rec_copy_prefix_to_buf(
|
|||||||
stored in one byte for 0..127. The length
|
stored in one byte for 0..127. The length
|
||||||
will be encoded in two bytes when it is 128 or
|
will be encoded in two bytes when it is 128 or
|
||||||
more, or when the column is stored externally. */
|
more, or when the column is stored externally. */
|
||||||
if (DATA_BIG_COL(col)) {
|
if (UNIV_UNLIKELY(len & 0x80) && DATA_BIG_COL(col)) {
|
||||||
if (len & 0x80) {
|
/* 1exxxxxx */
|
||||||
/* 1exxxxxx */
|
len &= 0x3f;
|
||||||
len &= 0x3f;
|
len <<= 8;
|
||||||
len <<= 8;
|
len |= *lens--;
|
||||||
len |= *lens--;
|
UNIV_PREFETCH_R(lens);
|
||||||
UNIV_PREFETCH_R(lens);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
prefix_len += len;
|
prefix_len += len;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user