summaryrefslogtreecommitdiff
path: root/storage/innobase/rem
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2019-11-04 22:30:12 +0300
committerEugene Kosov <claprix@yandex.ru>2019-12-13 00:26:50 +0700
commitf0aa073f2bf3d8d85b3d028df89cdb4cdfc4002d (patch)
tree63a3e0b64a64741d2b2b0ba47b02e9d92dc1f516 /storage/innobase/rem
parentbeec9c0e19284a0e50d3629f4cb2486007b0333b (diff)
downloadmariadb-git-f0aa073f2bf3d8d85b3d028df89cdb4cdfc4002d.tar.gz
MDEV-20950 Reduce size of record offsetsbb-10.2-MDEV-20950-stack-offsets
offset_t: this is a type which represents one record offset. It's unsigned short int. a lot of functions: replace ulint with offset_t btr_pcur_restore_position_func(), page_validate(), row_ins_scan_sec_index_for_duplicate(), row_upd_clust_rec_by_insert_inherit_func(), row_vers_impl_x_locked_low(), trx_undo_prev_version_build(): allocate record offsets on the stack instead of waiting for rec_get_offsets() to allocate it from mem_heap_t. So, reducing memory allocations. RECORD_OFFSET, INDEX_OFFSET: now it's less convenient to store pointers in offset_t* array. One pointer occupies now several offset_t. And those constant are start indexes into array to places where to store pointer values REC_OFFS_HEADER_SIZE: adjusted for the new reality REC_OFFS_NORMAL_SIZE: increase size from 100 to 300 which means less heap allocations. And sizeof(offset_t[REC_OFFS_NORMAL_SIZE]) now is 600 bytes which is smaller than previous 800 bytes. REC_OFFS_SEC_INDEX_SIZE: adjusted for the new reality rem0rec.h, rem0rec.ic, rem0rec.cc: various arguments, return values and local variables types were changed to fix numerous integer conversions issues. enum field_type_t: offset types concept was introduces which replaces old offset flags stuff. Like in earlier version, 2 upper bits are used to store offset type. And this enum represents those types. REC_OFFS_SQL_NULL, REC_OFFS_MASK: removed get_type(), set_type(), get_value(), combine(): these are convenience functions to work with offsets and it's types rec_offs_base()[0]: still uses an old scheme with flags REC_OFFS_COMPACT and REC_OFFS_EXTERNAL rec_offs_base()[i]: these have type offset_t now. Two upper bits contains type.
Diffstat (limited to 'storage/innobase/rem')
-rw-r--r--storage/innobase/rem/rem0cmp.cc24
-rw-r--r--storage/innobase/rem/rem0rec.cc120
2 files changed, 73 insertions, 71 deletions
diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc
index 9449274321e..48927b02963 100644
--- a/storage/innobase/rem/rem0cmp.cc
+++ b/storage/innobase/rem/rem0cmp.cc
@@ -546,7 +546,7 @@ cmp_dtuple_rec_with_gis(
dtuple in some of the common fields, or which
has an equal number or more fields than
dtuple */
- const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */
page_cur_mode_t mode) /*!< in: compare mode */
{
const dfield_t* dtuple_field; /* current field in logical record */
@@ -579,7 +579,7 @@ int
cmp_dtuple_rec_with_gis_internal(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets)
+ const offset_t* offsets)
{
const dfield_t* dtuple_field; /* current field in logical record */
ulint dtuple_f_len; /* the length of the current field
@@ -650,7 +650,7 @@ int
cmp_dtuple_rec_with_match_low(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets,
+ const offset_t* offsets,
ulint n_cmp,
ulint* matched_fields)
{
@@ -779,7 +779,7 @@ cmp_dtuple_rec_with_match_bytes(
const dtuple_t* dtuple,
const rec_t* rec,
const dict_index_t* index,
- const ulint* offsets,
+ const offset_t* offsets,
ulint* matched_fields,
ulint* matched_bytes)
{
@@ -942,7 +942,7 @@ int
cmp_dtuple_rec(
const dtuple_t* dtuple,
const rec_t* rec,
- const ulint* offsets)
+ const offset_t* offsets)
{
ulint matched_fields = 0;
@@ -960,7 +960,7 @@ cmp_dtuple_is_prefix_of_rec(
/*========================*/
const dtuple_t* dtuple, /*!< in: data tuple */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint n_fields;
ulint matched_fields = 0;
@@ -988,8 +988,8 @@ cmp_rec_rec_simple_field(
/*=====================*/
const rec_t* rec1, /*!< in: physical record */
const rec_t* rec2, /*!< in: physical record */
- const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
- const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
+ const offset_t* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
+ const offset_t* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
const dict_index_t* index, /*!< in: data dictionary index */
ulint n) /*!< in: field to compare */
{
@@ -1019,8 +1019,8 @@ cmp_rec_rec_simple(
/*===============*/
const rec_t* rec1, /*!< in: physical record */
const rec_t* rec2, /*!< in: physical record */
- const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
- const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
+ const offset_t* offsets1,/*!< in: rec_get_offsets(rec1, ...) */
+ const offset_t* offsets2,/*!< in: rec_get_offsets(rec2, ...) */
const dict_index_t* index, /*!< in: data dictionary index */
struct TABLE* table) /*!< in: MySQL table, for reporting
duplicate key value if applicable,
@@ -1105,8 +1105,8 @@ int
cmp_rec_rec_with_match(
const rec_t* rec1,
const rec_t* rec2,
- const ulint* offsets1,
- const ulint* offsets2,
+ const offset_t* offsets1,
+ const offset_t* offsets2,
const dict_index_t* index,
bool nulls_unequal,
ulint* matched_fields)
diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc
index b0fb4e0f113..1d7f9880240 100644
--- a/storage/innobase/rem/rem0rec.cc
+++ b/storage/innobase/rem/rem0rec.cc
@@ -242,12 +242,12 @@ rec_init_offsets_comp_ordinary(
format for temporary files in
index creation */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ offset_t* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
- ulint offs = 0;
- ulint any_ext = 0;
+ offset_t offs = 0;
+ offset_t any_ext = 0;
ulint n_null = index->n_nullable;
const byte* nulls = temp
? rec - 1
@@ -259,8 +259,8 @@ rec_init_offsets_comp_ordinary(
/* We cannot invoke rec_offs_make_valid() here if temp=true.
Similarly, rec_offs_validate() will fail in that case, because
it invokes rec_get_status(). */
- offsets[2] = (ulint) rec;
- offsets[3] = (ulint) index;
+ memcpy(&offsets[RECORD_OFFSET], &rec, sizeof(rec));
+ memcpy(&offsets[INDEX_OFFSET], &index, sizeof(index));
#endif /* UNIV_DEBUG */
ut_ad(temp || dict_table_is_comp(index->table));
@@ -277,7 +277,7 @@ rec_init_offsets_comp_ordinary(
= dict_index_get_nth_field(index, i);
const dict_col_t* col
= dict_field_get_col(field);
- ulint len;
+ offset_t len;
if (!(col->prtype & DATA_NOT_NULL)) {
/* nullable field => read the null flag */
@@ -294,7 +294,7 @@ rec_init_offsets_comp_ordinary(
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
- len = offs | REC_OFFS_SQL_NULL;
+ len = combine(offs, SQL_NULL);
goto resolved;
}
null_mask <<= 1;
@@ -317,14 +317,14 @@ rec_init_offsets_comp_ordinary(
len <<= 8;
len |= *lens--;
- offs += len & 0x3fff;
+ offs += get_value(len);
if (UNIV_UNLIKELY(len
& 0x4000)) {
ut_ad(dict_index_is_clust
(index));
any_ext = REC_OFFS_EXTERNAL;
- len = offs
- | REC_OFFS_EXTERNAL;
+ len = combine(offs,
+ STORED_OFFPAGE);
} else {
len = offs;
}
@@ -341,8 +341,8 @@ resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
- *rec_offs_base(offsets)
- = (rec - (lens + 1)) | REC_OFFS_COMPACT | any_ext;
+ *rec_offs_base(offsets) = static_cast<offset_t>(rec - (lens + 1))
+ | REC_OFFS_COMPACT | any_ext;
}
/******************************************************//**
@@ -355,21 +355,20 @@ to the extra size (if REC_OFFS_COMPACT is set, the record is in the
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
-high-order bit of the offset at [i+1] is set (REC_OFFS_EXTERNAL), the
-field i is being stored externally. */
+fields 1..n_fields+1. When the type of the offset at [i+1]
+is (SQL_NULL), the field i is NULL. When the type of the offset at [i+1]
+is (STORED_OFFPAGE), the field i is stored externally. */
static
void
rec_init_offsets(
/*=============*/
const rec_t* rec, /*!< in: physical record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ offset_t* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
- ulint offs;
+ offset_t offs;
rec_offs_make_valid(rec, index, offsets);
@@ -407,7 +406,7 @@ rec_init_offsets(
/* read the lengths of fields 0..n */
do {
- ulint len;
+ offset_t len;
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
len = offs += REC_NODE_PTR_SIZE;
goto resolved;
@@ -429,7 +428,7 @@ rec_init_offsets(
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
- len = offs | REC_OFFS_SQL_NULL;
+ len = combine(offs, SQL_NULL);
goto resolved;
}
null_mask <<= 1;
@@ -461,7 +460,7 @@ rec_init_offsets(
stored columns. Thus
the "e" flag must be 0. */
ut_a(!(len & 0x4000));
- offs += len & 0x3fff;
+ offs += get_value(len);
len = offs;
goto resolved;
@@ -476,8 +475,8 @@ resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
- *rec_offs_base(offsets)
- = (rec - (lens + 1)) | REC_OFFS_COMPACT;
+ *rec_offs_base(offsets) = static_cast<offset_t>(
+ (rec - (lens + 1)) | REC_OFFS_COMPACT);
} else {
/* Old-style record: determine extra size and end offsets */
offs = REC_N_OLD_EXTRA_BYTES;
@@ -489,23 +488,25 @@ resolved:
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;
+ set_type(offs, SQL_NULL);
}
rec_offs_base(offsets)[1 + i] = offs;
} while (++i < rec_offs_n_fields(offsets));
} else {
- offs += 2 * rec_offs_n_fields(offsets);
+ offs += 2
+ * static_cast<offset_t>(
+ rec_offs_n_fields(offsets));
*rec_offs_base(offsets) = 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;
- offs |= REC_OFFS_SQL_NULL;
+ set_type(offs, SQL_NULL);
}
if (offs & REC_2BYTE_EXTERN_MASK) {
offs &= ~REC_2BYTE_EXTERN_MASK;
- offs |= REC_OFFS_EXTERNAL;
+ set_type(offs, STORED_OFFPAGE);
*rec_offs_base(offsets) |= REC_OFFS_EXTERNAL;
}
rec_offs_base(offsets)[1 + i] = offs;
@@ -524,11 +525,11 @@ resolved:
(ULINT_UNDEFINED to compute all offsets)
@param[in,out] heap memory heap
@return the new offsets */
-ulint*
+offset_t*
rec_get_offsets_func(
const rec_t* rec,
const dict_index_t* index,
- ulint* offsets,
+ offset_t* offsets,
#ifdef UNIV_DEBUG
bool leaf,
#endif /* UNIV_DEBUG */
@@ -606,11 +607,11 @@ rec_get_offsets_func(
if (UNIV_UNLIKELY(!offsets)
|| UNIV_UNLIKELY(rec_offs_get_n_alloc(offsets) < size)) {
if (UNIV_UNLIKELY(!*heap)) {
- *heap = mem_heap_create_at(size * sizeof(ulint),
+ *heap = mem_heap_create_at(size * sizeof(*offsets),
file, line);
}
- offsets = static_cast<ulint*>(
- mem_heap_alloc(*heap, size * sizeof(ulint)));
+ offsets = static_cast<offset_t*>(
+ mem_heap_alloc(*heap, size * sizeof(*offsets)));
rec_offs_set_n_alloc(offsets, size);
}
@@ -633,13 +634,13 @@ rec_get_offsets_reverse(
const dict_index_t* index, /*!< in: record descriptor */
ulint node_ptr,/*!< in: nonzero=node pointer,
0=leaf node */
- ulint* offsets)/*!< in/out: array consisting of
+ offset_t* offsets)/*!< in/out: array consisting of
offsets[0] allocated elements */
{
ulint n;
ulint i;
- ulint offs;
- ulint any_ext;
+ offset_t offs;
+ offset_t any_ext = 0;
const byte* nulls;
const byte* lens;
dict_field_t* field;
@@ -664,11 +665,10 @@ rec_get_offsets_reverse(
lens = nulls + UT_BITS_IN_BYTES(index->n_nullable);
i = offs = 0;
null_mask = 1;
- any_ext = 0;
/* read the lengths of fields 0..n */
do {
- ulint len;
+ offset_t len;
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
len = offs += REC_NODE_PTR_SIZE;
goto resolved;
@@ -689,7 +689,7 @@ rec_get_offsets_reverse(
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
- len = offs | REC_OFFS_SQL_NULL;
+ len = combine(offs, SQL_NULL);
goto resolved;
}
null_mask <<= 1;
@@ -713,10 +713,11 @@ rec_get_offsets_reverse(
len <<= 8;
len |= *lens++;
- offs += len & 0x3fff;
+ offs += get_value(len);
if (UNIV_UNLIKELY(len & 0x4000)) {
any_ext = REC_OFFS_EXTERNAL;
- len = offs | REC_OFFS_EXTERNAL;
+ len = combine(offs,
+ STORED_OFFPAGE);
} else {
len = offs;
}
@@ -727,15 +728,16 @@ rec_get_offsets_reverse(
len = offs += len;
} else {
- len = offs += field->fixed_len;
+ len = offs += static_cast<offset_t>(field->fixed_len);
}
resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
ut_ad(lens >= extra);
- *rec_offs_base(offsets) = (lens - extra + REC_N_NEW_EXTRA_BYTES)
- | REC_OFFS_COMPACT | any_ext;
+ *rec_offs_base(offsets)
+ = static_cast<offset_t>((lens - extra + REC_N_NEW_EXTRA_BYTES)
+ | REC_OFFS_COMPACT | any_ext);
}
/************************************************************//**
@@ -1397,7 +1399,7 @@ rec_init_offsets_temp(
/*==================*/
const rec_t* rec, /*!< in: temporary file record */
const dict_index_t* index, /*!< in: record descriptor */
- ulint* offsets)/*!< in/out: array of offsets;
+ offset_t* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
rec_init_offsets_comp_ordinary(rec, true, index, offsets);
@@ -1436,8 +1438,8 @@ rec_copy_prefix_to_dtuple_func(
ulint n_fields,
mem_heap_t* heap)
{
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
+ offset_t offsets_[REC_OFFS_NORMAL_SIZE];
+ offset_t* offsets = offsets_;
rec_offs_init(offsets_);
ut_ad(is_leaf || n_fields
@@ -1697,7 +1699,7 @@ ibool
rec_validate(
/*=========*/
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint len;
ulint n_fields;
@@ -1799,7 +1801,7 @@ rec_print_comp(
/*===========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
{
ulint i;
@@ -1919,7 +1921,7 @@ rec_print_mbr_rec(
/*==============*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -1986,7 +1988,7 @@ rec_print_new(
/*==========*/
FILE* file, /*!< in: file where to print */
const rec_t* rec, /*!< in: physical record */
- const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
+ const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */
{
ut_ad(rec_offs_validate(rec, NULL, offsets));
@@ -2026,7 +2028,7 @@ rec_print(
return;
} else {
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
+ offset_t offsets_[REC_OFFS_NORMAL_SIZE];
rec_offs_init(offsets_);
rec_print_new(file, rec,
@@ -2049,7 +2051,7 @@ rec_print(
std::ostream& o,
const rec_t* rec,
ulint info,
- const ulint* offsets)
+ const offset_t* offsets)
{
const ulint comp = rec_offs_comp(offsets);
const ulint n = rec_offs_n_fields(offsets);
@@ -2101,7 +2103,7 @@ std::ostream&
operator<<(std::ostream& o, const rec_index_print& r)
{
mem_heap_t* heap = NULL;
- ulint* offsets = rec_get_offsets(
+ offset_t* offsets = rec_get_offsets(
r.m_rec, r.m_index, NULL, page_rec_is_leaf(r.m_rec),
ULINT_UNDEFINED, &heap);
rec_print(o, r.m_rec,
@@ -2139,9 +2141,9 @@ rec_get_trx_id(
const byte* trx_id;
ulint len;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
+ offset_t offsets_[REC_OFFS_HEADER_SIZE + MAX_REF_PARTS + 2];
rec_offs_init(offsets_);
- ulint* offsets = offsets_;
+ offset_t* offsets = offsets_;
ut_ad(trx_id_col <= MAX_REF_PARTS);
ut_ad(dict_index_is_clust(index));
@@ -2168,11 +2170,11 @@ rec_get_trx_id(
@param[in] n nth field */
void
rec_offs_make_nth_extern(
- ulint* offsets,
+ offset_t* offsets,
const ulint n)
{
ut_ad(!rec_offs_nth_sql_null(offsets, n));
- rec_offs_base(offsets)[1 + n] |= REC_OFFS_EXTERNAL;
+ set_type(rec_offs_base(offsets)[1 +n ], STORED_OFFPAGE);
}
#ifdef WITH_WSREP
# include "ha_prototypes.h"
@@ -2192,8 +2194,8 @@ wsrep_rec_get_foreign_key(
ulint i;
uint key_parts;
mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- const ulint* offsets;
+ offset_t offsets_[REC_OFFS_NORMAL_SIZE];
+ const offset_t* offsets;
ut_ad(index_for);
ut_ad(index_ref);