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