summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2005-04-22 15:27:11 +0300
committerunknown <marko@hundin.mysql.fi>2005-04-22 15:27:11 +0300
commit1c8f5500963814507754e878e092fdc76ebce6a7 (patch)
treea71fc413839010136b97da8ec360f479d8e282fa /innobase
parent33d5b13bbebcfc3657a7b8cc10eec10f73d44d71 (diff)
downloadmariadb-git-1c8f5500963814507754e878e092fdc76ebce6a7.tar.gz
InnoDB: Optimize rec_get_offsets(), rec_copy_prefix_to_buf() and
other rec_ functions based on OProfile measurements on GNU/Linux x86. innobase/include/rem0rec.h: Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp. Remove rec_set_node_ptr_flag(). innobase/include/rem0rec.ic: Replace FALSE/TRUE ibool comp with zero/nonzero ulint comp. Remove rec_set_node_ptr_flag(). Add UNIV_LIKELY and UNIV_UNLIKELY hints. Correct a spelling error in comment. Simplify rec_get_deleted_flag(). innobase/rem/rem0rec.c: Add UNIV_LIKELY and UNIV_UNLIKELY hints. rec_init_offsets(), rec_get_offsets_func(): Optimize for x86. rec_set_field_extern_bits(): Move "comp" flag outside the loop. rec_copy_prefix_to_buf(): Add UNIV_PREFETCH hints.
Diffstat (limited to 'innobase')
-rw-r--r--innobase/include/rem0rec.h34
-rw-r--r--innobase/include/rem0rec.ic80
-rw-r--r--innobase/rem/rem0rec.c146
3 files changed, 136 insertions, 124 deletions
diff --git a/innobase/include/rem0rec.h b/innobase/include/rem0rec.h
index 134c37c8030..3c150d6601d 100644
--- a/innobase/include/rem0rec.h
+++ b/innobase/include/rem0rec.h
@@ -51,7 +51,7 @@ rec_get_next_offs(
/* out: the page offset of the next
chained record */
rec_t* rec, /* in: physical record */
- ibool comp); /* in: TRUE=compact page format */
+ ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the next record offset field
of the record. */
@@ -60,7 +60,7 @@ void
rec_set_next_offs(
/*==============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint next); /* in: offset of the next record */
/**********************************************************
The following function is used to get the number of fields
@@ -90,7 +90,7 @@ rec_get_n_owned(
/*============*/
/* out: number of owned records */
rec_t* rec, /* in: physical record */
- ibool comp); /* in: TRUE=compact page format */
+ ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the number of owned
records. */
@@ -99,7 +99,7 @@ void
rec_set_n_owned(
/*============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint n_owned); /* in: the number of owned */
/**********************************************************
The following function is used to retrieve the info bits of
@@ -110,7 +110,7 @@ rec_get_info_bits(
/*==============*/
/* out: info bits */
rec_t* rec, /* in: physical record */
- ibool comp); /* in: TRUE=compact page format */
+ ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the info bits of a record. */
UNIV_INLINE
@@ -118,7 +118,7 @@ void
rec_set_info_bits(
/*==============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint bits); /* in: info bits */
/**********************************************************
The following function retrieves the status bits of a new-style record. */
@@ -147,7 +147,7 @@ rec_get_info_and_status_bits(
/*=========================*/
/* out: info bits */
rec_t* rec, /* in: physical record */
- ibool comp); /* in: TRUE=compact page format */
+ ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the info and status
bits of a record. (Only compact records have status bits.) */
@@ -156,7 +156,7 @@ void
rec_set_info_and_status_bits(
/*=========================*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint bits); /* in: info bits */
/**********************************************************
@@ -167,7 +167,7 @@ rec_get_deleted_flag(
/*=================*/
/* out: TRUE if delete marked */
rec_t* rec, /* in: physical record */
- ibool comp); /* in: TRUE=compact page format */
+ ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the deleted bit. */
UNIV_INLINE
@@ -175,7 +175,7 @@ void
rec_set_deleted_flag(
/*=================*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ibool flag); /* in: TRUE if delete marked */
/**********************************************************
The following function tells if a new-style record is a node pointer. */
@@ -186,14 +186,6 @@ rec_get_node_ptr_flag(
/* out: TRUE if node pointer */
rec_t* rec); /* in: physical record */
/**********************************************************
-The following function is used to flag a record as a node pointer. */
-UNIV_INLINE
-void
-rec_set_node_ptr_flag(
-/*=================*/
- rec_t* rec, /* in: physical record */
- ibool flag); /* in: TRUE if the record is a node pointer */
-/**********************************************************
The following function is used to get the order number
of the record in the heap of the index page. */
UNIV_INLINE
@@ -202,7 +194,7 @@ rec_get_heap_no(
/*=============*/
/* out: heap order number */
rec_t* rec, /* in: physical record */
- ibool comp); /* in: TRUE=compact page format */
+ ulint comp); /* in: nonzero=compact page format */
/**********************************************************
The following function is used to set the heap number
field in the record. */
@@ -211,7 +203,7 @@ void
rec_set_heap_no(
/*=============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint heap_no);/* in: the heap number */
/**********************************************************
The following function is used to test whether the data offsets
@@ -305,7 +297,7 @@ rec_get_nth_field(
Determine if the offsets are for a record in the new
compact format. */
UNIV_INLINE
-ibool
+ulint
rec_offs_comp(
/*==========*/
/* out: TRUE if compact format */
diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic
index 2593fb8edeb..cd742aef6a6 100644
--- a/innobase/include/rem0rec.ic
+++ b/innobase/include/rem0rec.ic
@@ -265,7 +265,7 @@ rec_get_next_offs(
/* out: the page offset of the next chained record, or
0 if none */
rec_t* rec, /* in: physical record */
- ibool comp) /* in: TRUE=compact page format */
+ ulint comp) /* in: nonzero=compact page format */
{
ulint field_value;
@@ -312,7 +312,7 @@ void
rec_set_next_offs(
/*==============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint next) /* in: offset of the next record, or 0 if none */
{
ut_ad(rec);
@@ -414,7 +414,7 @@ rec_get_n_fields(
{
ut_ad(rec);
ut_ad(index);
- if (!index->table->comp) {
+ if (UNIV_UNLIKELY(!index->table->comp)) {
return(rec_get_n_fields_old(rec));
}
switch (rec_get_status(rec)) {
@@ -440,7 +440,7 @@ rec_get_n_owned(
/*============*/
/* out: number of owned records */
rec_t* rec, /* in: physical record */
- ibool comp) /* in: TRUE=compact page format */
+ ulint comp) /* in: nonzero=compact page format */
{
ulint ret;
@@ -461,7 +461,7 @@ void
rec_set_n_owned(
/*============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint n_owned) /* in: the number of owned */
{
ut_ad(rec);
@@ -480,7 +480,7 @@ rec_get_info_bits(
/*==============*/
/* out: info bits */
rec_t* rec, /* in: physical record */
- ibool comp) /* in: TRUE=compact page format */
+ ulint comp) /* in: nonzero=compact page format */
{
ulint ret;
@@ -501,7 +501,7 @@ void
rec_set_info_bits(
/*==============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint bits) /* in: info bits */
{
ut_ad(rec);
@@ -537,14 +537,14 @@ rec_get_info_and_status_bits(
/*=========================*/
/* out: info bits */
rec_t* rec, /* in: physical record */
- ibool comp) /* in: TRUE=compact page format */
+ ulint comp) /* in: nonzero=compact page format */
{
ulint bits;
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
& (REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT)
# error "REC_NEW_STATUS_MASK and REC_INFO_BITS_MASK overlap"
#endif
- if (comp) {
+ if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
bits = rec_get_info_bits(rec, TRUE) | rec_get_status(rec);
} else {
bits = rec_get_info_bits(rec, FALSE);
@@ -560,7 +560,7 @@ void
rec_set_info_and_status_bits(
/*=========================*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint bits) /* in: info bits */
{
#if (REC_NEW_STATUS_MASK >> REC_NEW_STATUS_SHIFT) \
@@ -583,14 +583,15 @@ rec_get_deleted_flag(
/*=================*/
/* out: TRUE if delete marked */
rec_t* rec, /* in: physical record */
- ibool comp) /* in: TRUE=compact page format */
+ ulint comp) /* in: nonzero=compact page format */
{
- if (REC_INFO_DELETED_FLAG & rec_get_info_bits(rec, comp)) {
-
- return(TRUE);
+ if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) {
+ return(0 != rec_get_bit_field_1(rec, REC_NEW_INFO_BITS,
+ REC_INFO_DELETED_FLAG, REC_INFO_BITS_SHIFT));
+ } else {
+ return(0 != rec_get_bit_field_1(rec, REC_OLD_INFO_BITS,
+ REC_INFO_DELETED_FLAG, REC_INFO_BITS_SHIFT));
}
-
- return(FALSE);
}
/**********************************************************
@@ -600,24 +601,23 @@ void
rec_set_deleted_flag(
/*=================*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ibool flag) /* in: TRUE if delete marked */
{
- ulint old_val;
- ulint new_val;
+ ulint val;
ut_ad(TRUE == 1);
ut_ad(flag <= TRUE);
- old_val = rec_get_info_bits(rec, comp);
+ val = rec_get_info_bits(rec, comp);
if (flag) {
- new_val = REC_INFO_DELETED_FLAG | old_val;
+ val |= REC_INFO_DELETED_FLAG;
} else {
- new_val = ~REC_INFO_DELETED_FLAG & old_val;
+ val &= ~REC_INFO_DELETED_FLAG;
}
- rec_set_info_bits(rec, comp, new_val);
+ rec_set_info_bits(rec, comp, val);
}
/**********************************************************
@@ -633,26 +633,6 @@ rec_get_node_ptr_flag(
}
/**********************************************************
-The following function is used to flag a record as a node pointer. */
-UNIV_INLINE
-void
-rec_set_node_ptr_flag(
-/*=================*/
- rec_t* rec, /* in: physical record */
- ibool flag) /* in: TRUE if the record is a node pointer */
-{
- ulint status;
- ut_ad(flag <= TRUE);
- ut_ad(REC_STATUS_NODE_PTR >= rec_get_status(rec));
- if (flag) {
- status = REC_STATUS_NODE_PTR;
- } else {
- status = REC_STATUS_ORDINARY;
- }
- rec_set_status(rec, status);
-}
-
-/**********************************************************
The following function is used to get the order number of the record in the
heap of the index page. */
UNIV_INLINE
@@ -661,7 +641,7 @@ rec_get_heap_no(
/*=============*/
/* out: heap order number */
rec_t* rec, /* in: physical record */
- ibool comp) /* in: TRUE=compact page format */
+ ulint comp) /* in: nonzero=compact page format */
{
ulint ret;
@@ -682,7 +662,7 @@ void
rec_set_heap_no(
/*=============*/
rec_t* rec, /* in: physical record */
- ibool comp, /* in: TRUE=compact page format */
+ ulint comp, /* in: nonzero=compact page format */
ulint heap_no)/* in: the heap number */
{
ut_ad(heap_no <= REC_MAX_HEAP_NO);
@@ -843,7 +823,7 @@ rec_offs_validate(
{
ulint i = rec_offs_n_fields(offsets);
ulint last = ULINT_MAX;
- ibool comp = (*rec_offs_base(offsets) & REC_OFFS_COMPACT) != 0;
+ ulint comp = *rec_offs_base(offsets) & REC_OFFS_COMPACT;
if (rec) {
ut_ad((ulint) rec == offsets[2]);
@@ -926,7 +906,7 @@ rec_get_nth_field(
ut_ad(n < rec_offs_n_fields(offsets));
ut_ad(len);
- if (n == 0) {
+ if (UNIV_UNLIKELY(n == 0)) {
field = rec;
} else {
field = rec + (rec_offs_base(offsets)[n] & REC_OFFS_MASK);
@@ -1037,7 +1017,7 @@ rec_set_nth_field_extern_bit(
where rec is, or NULL; in the NULL case
we do not write to log about the change */
{
- if (index->table->comp) {
+ if (UNIV_LIKELY(index->table->comp)) {
rec_set_nth_field_extern_bit_new(rec, index, i, val, mtr);
} else {
rec_set_nth_field_extern_bit_old(rec, i, val, mtr);
@@ -1048,7 +1028,7 @@ rec_set_nth_field_extern_bit(
Returns the offset of n - 1th field end if the record is stored in the 1-byte
offsets form. If the field is SQL null, the flag is ORed in the returned
value. This function and the 2-byte counterpart are defined here because the
-C-compilerwas not able to sum negative and positive constant offsets, and
+C-compiler was not able to sum negative and positive constant offsets, and
warned of constant arithmetic overflow within the compiler. */
UNIV_INLINE
ulint
@@ -1452,7 +1432,7 @@ rec_get_converted_size(
? dict_index_get_n_unique_in_tree(index) + 1
: dict_index_get_n_fields(index)));
- if (index->table->comp) {
+ if (UNIV_LIKELY(index->table->comp)) {
return(rec_get_converted_size_new(index, dtuple));
}
diff --git a/innobase/rem/rem0rec.c b/innobase/rem/rem0rec.c
index a8f75072e65..a1e7e348781 100644
--- a/innobase/rem/rem0rec.c
+++ b/innobase/rem/rem0rec.c
@@ -159,22 +159,20 @@ rec_init_offsets(
ulint* offsets)/* in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
- ulint n_fields = rec_offs_n_fields(offsets);
ulint i = 0;
ulint offs;
rec_offs_make_valid(rec, index, offsets);
- if (index->table->comp) {
+ if (UNIV_LIKELY(index->table->comp)) {
const byte* nulls;
const byte* lens;
dict_field_t* field;
- dtype_t* type;
ulint null_mask;
ulint status = rec_get_status(rec);
ulint n_node_ptr_field = ULINT_UNDEFINED;
- switch (status) {
+ switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
/* the field is 8 bytes long */
@@ -196,56 +194,74 @@ rec_init_offsets(
null_mask = 1;
/* read the lengths of fields 0..n */
- for (; i < n_fields; i++) {
- ibool is_null = FALSE, is_external = FALSE;
+ do {
ulint len;
- if (i == n_node_ptr_field) {
- len = 4;
+ if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
+ len = offs += 4;
goto resolved;
}
field = dict_index_get_nth_field(index, i);
- type = dict_col_get_type(dict_field_get_col(field));
- if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) {
+ if (!(dtype_get_prtype(dict_col_get_type(
+ dict_field_get_col(field)))
+ & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
- is_null = (*nulls & null_mask) != 0;
- null_mask <<= 1;
- if (null_mask == 0x100) {
+
+ if (UNIV_UNLIKELY(!(byte) null_mask)) {
nulls--;
null_mask = 1;
}
+
+ if (*nulls & null_mask) {
+ null_mask <<= 1;
+ /* No length is stored for NULL fields.
+ We do not advance offs, and we set
+ the length to zero and enable the
+ SQL NULL flag in offsets[]. */
+ len = REC_OFFS_SQL_NULL;
+ goto resolved;
+ }
+ null_mask <<= 1;
+
+ ut_ad(!field->fixed_len);
+ goto variable_length;
}
- if (is_null) {
- /* No length is stored for NULL fields. */
- len = 0;
- } else if (!field->fixed_len) {
+ if (UNIV_UNLIKELY(!field->fixed_len)) {
+ dtype_t* type;
+ variable_length:
/* Variable-length field: read the length */
+ type = dict_col_get_type(
+ dict_field_get_col(field));
len = *lens--;
- if (dtype_get_len(type) > 255
- || dtype_get_mtype(type) == DATA_BLOB) {
+ if (UNIV_UNLIKELY(dtype_get_len(type) > 255)
+ || UNIV_UNLIKELY(dtype_get_mtype(type)
+ == DATA_BLOB)) {
if (len & 0x80) {
/* 1exxxxxxx xxxxxxxx */
- is_external = !!(len & 0x40);
- len &= 0x3f;
len <<= 8;
len |= *lens--;
+
+ offs += len & 0x3fff;
+ if (UNIV_UNLIKELY(len
+ & 0x4000)) {
+ len = offs
+ | REC_OFFS_EXTERNAL;
+ } else {
+ len = offs;
+ }
+
+ goto resolved;
}
}
+
+ len = offs += len;
} else {
- len = field->fixed_len;
+ len = offs += field->fixed_len;
}
resolved:
- offs += len;
- len = offs;
- if (is_external) {
- len |= REC_OFFS_EXTERNAL;
- }
- if (is_null) {
- len |= REC_OFFS_SQL_NULL;
- }
rec_offs_base(offsets)[i + 1] = len;
- }
+ } while (++i < rec_offs_n_fields(offsets));
*rec_offs_base(offsets) =
(rec - (lens + 1)) | REC_OFFS_COMPACT;
@@ -253,22 +269,22 @@ rec_init_offsets(
/* Old-style record: determine extra size and end offsets */
offs = REC_N_OLD_EXTRA_BYTES;
if (rec_get_1byte_offs_flag(rec)) {
- offs += n_fields;
+ offs += rec_offs_n_fields(offsets);
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
- for (; i < n_fields; i++) {
+ do {
offs = rec_1_get_field_end_info(rec, i);
if (offs & REC_1BYTE_SQL_NULL_MASK) {
offs &= ~REC_1BYTE_SQL_NULL_MASK;
offs |= REC_OFFS_SQL_NULL;
}
rec_offs_base(offsets)[1 + i] = offs;
- }
+ } while (++i < rec_offs_n_fields(offsets));
} else {
- offs += 2 * n_fields;
+ offs += 2 * rec_offs_n_fields(offsets);
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
- for (; i < n_fields; i++) {
+ do {
offs = rec_2_get_field_end_info(rec, i);
if (offs & REC_2BYTE_SQL_NULL_MASK) {
offs &= ~REC_2BYTE_SQL_NULL_MASK;
@@ -279,7 +295,7 @@ rec_init_offsets(
offs |= REC_OFFS_EXTERNAL;
}
rec_offs_base(offsets)[1 + i] = offs;
- }
+ } while (++i < rec_offs_n_fields(offsets));
}
}
}
@@ -310,8 +326,9 @@ rec_get_offsets_func(
ut_ad(index);
ut_ad(heap);
- if (index->table->comp) {
- switch (rec_get_status(rec)) {
+ if (UNIV_LIKELY(index->table->comp)) {
+ switch (UNIV_EXPECT(rec_get_status(rec),
+ REC_STATUS_ORDINARY)) {
case REC_STATUS_ORDINARY:
n = dict_index_get_n_fields(index);
break;
@@ -331,13 +348,14 @@ rec_get_offsets_func(
n = rec_get_n_fields_old(rec);
}
- if (n_fields < n) {
+ if (UNIV_UNLIKELY(n_fields < n)) {
n = n_fields;
}
size = n + (1 + REC_OFFS_HEADER_SIZE);
- if (!offsets || rec_offs_get_n_alloc(offsets) < size) {
+ if (UNIV_UNLIKELY(!offsets) ||
+ UNIV_UNLIKELY(rec_offs_get_n_alloc(offsets) < size)) {
if (!*heap) {
*heap = mem_heap_create_func(size * sizeof(ulint),
NULL, MEM_HEAP_DYNAMIC, file, line);
@@ -652,9 +670,17 @@ rec_set_field_extern_bits(
to log about the change */
{
ulint i;
-
- for (i = 0; i < n_fields; i++) {
- rec_set_nth_field_extern_bit(rec, index, vec[i], TRUE, mtr);
+
+ if (UNIV_LIKELY(index->table->comp)) {
+ for (i = 0; i < n_fields; i++) {
+ rec_set_nth_field_extern_bit_new(rec, index, vec[i],
+ TRUE, mtr);
+ }
+ } else {
+ for (i = 0; i < n_fields; i++) {
+ rec_set_nth_field_extern_bit_old(rec, vec[i],
+ TRUE, mtr);
+ }
}
}
@@ -949,7 +975,7 @@ rec_convert_dtuple_to_rec(
ut_ad(dtuple_validate(dtuple));
ut_ad(dtuple_check_typed(dtuple));
- if (index->table->comp) {
+ if (UNIV_LIKELY(index->table->comp)) {
rec = rec_convert_dtuple_to_rec_new(buf, index, dtuple);
} else {
rec = rec_convert_dtuple_to_rec_old(buf, dtuple);
@@ -1078,17 +1104,19 @@ rec_copy_prefix_to_buf(
for the copied prefix, or NULL */
ulint* buf_size) /* in/out: buffer size */
{
- byte* nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
- byte* lens = nulls - (index->n_nullable + 7) / 8;
+ byte* nulls;
+ byte* lens;
dict_field_t* field;
dtype_t* type;
ulint i;
- ulint prefix_len = 0;
+ ulint prefix_len;
ibool is_null;
- ulint null_mask = 1;
+ ulint null_mask;
ulint status;
- if (!index->table->comp) {
+ UNIV_PREFETCH_RW(*buf);
+
+ if (UNIV_UNLIKELY(!index->table->comp)) {
ut_ad(rec_validate_old(rec));
return(rec_copy_prefix_to_buf_old(rec, n_fields,
rec_get_field_start_offs(rec, n_fields),
@@ -1109,10 +1137,16 @@ rec_copy_prefix_to_buf(
case REC_STATUS_SUPREMUM:
/* infimum or supremum record: no sense to copy anything */
default:
- ut_a(0);
+ ut_error;
return(NULL);
}
+ nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
+ lens = nulls - (index->n_nullable + 7) / 8;
+ UNIV_PREFETCH_R(lens);
+ prefix_len = 0;
+ null_mask = 1;
+
/* read the lengths of fields 0..n */
for (i = 0; i < n_fields; i++) {
field = dict_index_get_nth_field(index, i);
@@ -1122,8 +1156,11 @@ rec_copy_prefix_to_buf(
/* nullable field => read the null flag */
is_null = !!(*nulls & null_mask);
null_mask <<= 1;
- if (null_mask == 0x100)
- nulls--, null_mask = 1;
+ if (null_mask == 0x100) {
+ --nulls;
+ UNIV_PREFETCH_R(nulls);
+ null_mask = 1;
+ }
}
if (is_null) {
@@ -1138,12 +1175,15 @@ rec_copy_prefix_to_buf(
len &= 0x3f;
len <<= 8;
len |= *lens--;
+ UNIV_PREFETCH_R(lens);
}
}
prefix_len += len;
}
}
+ UNIV_PREFETCH_R(rec + prefix_len);
+
prefix_len += rec - (lens + 1);
if ((*buf == NULL) || (*buf_size < prefix_len)) {