diff options
Diffstat (limited to 'storage/innobase/include/rem0rec.h')
-rw-r--r-- | storage/innobase/include/rem0rec.h | 209 |
1 files changed, 115 insertions, 94 deletions
diff --git a/storage/innobase/include/rem0rec.h b/storage/innobase/include/rem0rec.h index 29923839ce1..bd6bb563192 100644 --- a/storage/innobase/include/rem0rec.h +++ b/storage/innobase/include/rem0rec.h @@ -61,45 +61,86 @@ The status is stored in the low-order bits. */ /* Length of a B-tree node pointer, in bytes */ #define REC_NODE_PTR_SIZE 4 +#ifndef UNIV_INNOCHECKSUM /** SQL null flag in a 1-byte offset of ROW_FORMAT=REDUNDANT records */ -#define REC_1BYTE_SQL_NULL_MASK 0x80UL +static const offset_t REC_1BYTE_SQL_NULL_MASK= 0x80; /** SQL null flag in a 2-byte offset of ROW_FORMAT=REDUNDANT records */ -#define REC_2BYTE_SQL_NULL_MASK 0x8000UL +static const offset_t REC_2BYTE_SQL_NULL_MASK= 0x8000; /** In a 2-byte offset of ROW_FORMAT=REDUNDANT records, the second most significant bit denotes that the tail of a field is stored off-page. */ -#define REC_2BYTE_EXTERN_MASK 0x4000UL +static const offset_t REC_2BYTE_EXTERN_MASK= 0x4000; + +static const size_t RECORD_OFFSET= 2; +static const size_t INDEX_OFFSET= + RECORD_OFFSET + sizeof(rec_t *) / sizeof(offset_t); +#endif /* UNIV_INNOCHECKSUM */ -#ifdef UNIV_DEBUG -/* Length of the rec_get_offsets() header */ -# define REC_OFFS_HEADER_SIZE 4 -#else /* UNIV_DEBUG */ /* Length of the rec_get_offsets() header */ -# define REC_OFFS_HEADER_SIZE 2 +static const size_t REC_OFFS_HEADER_SIZE= +#ifdef UNIV_DEBUG +#ifndef UNIV_INNOCHECKSUM + sizeof(rec_t *) / sizeof(offset_t) + + sizeof(dict_index_t *) / sizeof(offset_t) + +#endif /* UNIV_INNOCHECKSUM */ #endif /* UNIV_DEBUG */ + 2; /* Number of elements that should be initially allocated for the offsets[] array, first passed to rec_get_offsets() */ -#define REC_OFFS_NORMAL_SIZE OFFS_IN_REC_NORMAL_SIZE -#define REC_OFFS_SMALL_SIZE 10 +static const size_t REC_OFFS_NORMAL_SIZE= 300; +static const size_t REC_OFFS_SMALL_SIZE= 18; +static const size_t REC_OFFS_SEC_INDEX_SIZE= + /* PK max key parts */ 16 + /* sec idx max key parts */ 16 + + /* child page number for non-leaf pages */ 1; /** Get the base address of offsets. The extra_size is stored at this position, and following positions hold the end offsets of the fields. */ #define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE) +#ifndef UNIV_INNOCHECKSUM +/* Offset consists of two parts: 2 upper bits is type and all other bits is +value */ + +/** Only 4 different values is possible! */ +enum field_type_t +{ + /** normal field */ + STORED_IN_RECORD= 0 << 14, + /** this field is stored off-page */ + STORED_OFFPAGE= 1 << 14, + /** just an SQL NULL */ + SQL_NULL= 2 << 14, + /** instantly added field */ + DEFAULT= 3 << 14, +}; + +/** without 2 upper bits */ +static const offset_t DATA_MASK= 0x3fff; +/** 2 upper bits */ +static const offset_t TYPE_MASK= ~DATA_MASK; +inline field_type_t get_type(offset_t n) +{ + return static_cast<field_type_t>(n & TYPE_MASK); +} +inline void set_type(offset_t &n, field_type_t type) +{ + n= (n & DATA_MASK) | static_cast<offset_t>(type); +} +inline offset_t get_value(offset_t n) { return n & DATA_MASK; } +inline offset_t combine(offset_t value, field_type_t type) +{ + return get_value(value) | static_cast<offset_t>(type); +} + /** Compact flag ORed to the extra size returned by rec_get_offsets() */ -const ulint REC_OFFS_COMPACT = ~(ulint(~0) >> 1); -/** SQL NULL flag in offsets returned by rec_get_offsets() */ -const ulint REC_OFFS_SQL_NULL = REC_OFFS_COMPACT; +const offset_t REC_OFFS_COMPACT= ~(offset_t(~0) >> 1); /** External flag in offsets returned by rec_get_offsets() */ -const ulint REC_OFFS_EXTERNAL = REC_OFFS_COMPACT >> 1; +const offset_t REC_OFFS_EXTERNAL= REC_OFFS_COMPACT >> 1; /** Default value flag in offsets returned by rec_get_offsets() */ -const ulint REC_OFFS_DEFAULT = REC_OFFS_COMPACT >> 2; -/** Mask for offsets returned by rec_get_offsets() */ -const ulint REC_OFFS_MASK = REC_OFFS_DEFAULT - 1; - -#ifndef UNIV_INNOCHECKSUM +const offset_t REC_OFFS_DEFAULT= REC_OFFS_COMPACT >> 2; +const offset_t REC_OFFS_MASK= REC_OFFS_DEFAULT - 1; /******************************************************//** The following function is used to get the pointer of the next chained record on the same page. @@ -452,7 +493,7 @@ offsets form. If the field is SQL null, the flag is ORed in the returned value. @return offset of the start of the field, SQL null flag ORed */ UNIV_INLINE -ulint +uint8_t rec_1_get_field_end_info( /*=====================*/ const rec_t* rec, /*!< in: record */ @@ -466,7 +507,7 @@ value. @return offset of the start of the field, SQL null flag and extern storage flag ORed */ UNIV_INLINE -ulint +uint16_t rec_2_get_field_end_info( /*=====================*/ const rec_t* rec, /*!< in: record */ @@ -507,11 +548,11 @@ rec_get_n_extern_new( (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, bool leaf, ulint n_fields, #ifdef UNIV_DEBUG @@ -546,7 +587,7 @@ 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 */ MY_ATTRIBUTE((nonnull)); #ifdef UNIV_DEBUG @@ -559,7 +600,7 @@ bool rec_offs_validate( const rec_t* rec, const dict_index_t* index, - const ulint* offsets) + const offset_t* offsets) MY_ATTRIBUTE((nonnull(3), warn_unused_result)); /** Update debug data in offsets, in order to tame rec_offs_validate(). @param[in] rec record @@ -571,7 +612,7 @@ rec_offs_make_valid( const rec_t* rec, const dict_index_t* index, bool leaf, - ulint* offsets) + offset_t* offsets) MY_ATTRIBUTE((nonnull)); #else # define rec_offs_make_valid(rec, index, leaf, offsets) @@ -608,17 +649,16 @@ The following function is used to get an offset to the nth data field in a record. @return offset from the origin of rec */ UNIV_INLINE -ulint +offset_t rec_get_nth_field_offs( /*===================*/ - const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */ ulint n, /*!< in: index of the field */ ulint* len) /*!< out: length of the field; UNIV_SQL_NULL if SQL null */ MY_ATTRIBUTE((nonnull)); #define rec_get_nth_field(rec, offsets, n, len) \ ((rec) + rec_get_nth_field_offs(offsets, n, len)) - /******************************************************//** Determine if the offsets are for a record containing null BLOB pointers. @return first field containing a null BLOB pointer, or NULL if none found */ @@ -627,7 +667,7 @@ const byte* rec_offs_any_null_extern( /*=====================*/ const rec_t* rec, /*!< in: record */ - const ulint* offsets) /*!< in: rec_get_offsets(rec) */ + const offset_t* offsets) /*!< in: rec_get_offsets(rec) */ MY_ATTRIBUTE((warn_unused_result)); /** Mark the nth field as externally stored. @@ -635,7 +675,7 @@ rec_offs_any_null_extern( @param[in] n nth field */ void rec_offs_make_nth_extern( - ulint* offsets, + offset_t* offsets, const ulint n); /** Determine the number of allocated elements for an array of offsets. @@ -643,7 +683,7 @@ rec_offs_make_nth_extern( @return number of elements */ inline ulint -rec_offs_get_n_alloc(const ulint* offsets) +rec_offs_get_n_alloc(const offset_t* offsets) { ulint n_alloc; ut_ad(offsets); @@ -658,7 +698,7 @@ rec_offs_get_n_alloc(const ulint* offsets) @return number of fields */ inline ulint -rec_offs_n_fields(const ulint* offsets) +rec_offs_n_fields(const offset_t* offsets) { ulint n_fields; ut_ad(offsets); @@ -674,19 +714,12 @@ rec_offs_n_fields(const ulint* offsets) @param[in] offsets rec_get_offsets() @param[in] n nth field @param[in] flag flag to extract -@return the flag of the record field */ -inline -ulint -rec_offs_nth_flag(const ulint* offsets, ulint n, ulint flag) +@return type of the record field */ +inline field_type_t rec_offs_nth_type(const offset_t *offsets, ulint n) { - ut_ad(rec_offs_validate(NULL, NULL, offsets)); - ut_ad(n < rec_offs_n_fields(offsets)); - /* The DEFAULT, NULL, EXTERNAL flags are mutually exclusive. */ - ut_ad(ut_is_2pow(rec_offs_base(offsets)[1 + n] - & (REC_OFFS_DEFAULT - | REC_OFFS_SQL_NULL - | REC_OFFS_EXTERNAL))); - return rec_offs_base(offsets)[1 + n] & flag; + ut_ad(rec_offs_validate(NULL, NULL, offsets)); + ut_ad(n < rec_offs_n_fields(offsets)); + return get_type(rec_offs_base(offsets)[1 + n]); } /** Determine if a record field is missing @@ -694,11 +727,9 @@ rec_offs_nth_flag(const ulint* offsets, ulint n, ulint flag) @param[in] offsets rec_get_offsets() @param[in] n nth field @return nonzero if default bit is set */ -inline -ulint -rec_offs_nth_default(const ulint* offsets, ulint n) +inline ulint rec_offs_nth_default(const offset_t *offsets, ulint n) { - return rec_offs_nth_flag(offsets, n, REC_OFFS_DEFAULT); + return rec_offs_nth_type(offsets, n) == DEFAULT; } /** Determine if a record field is SQL NULL @@ -706,11 +737,9 @@ rec_offs_nth_default(const ulint* offsets, ulint n) @param[in] offsets rec_get_offsets() @param[in] n nth field @return nonzero if SQL NULL set */ -inline -ulint -rec_offs_nth_sql_null(const ulint* offsets, ulint n) +inline ulint rec_offs_nth_sql_null(const offset_t *offsets, ulint n) { - return rec_offs_nth_flag(offsets, n, REC_OFFS_SQL_NULL); + return rec_offs_nth_type(offsets, n) == SQL_NULL; } /** Determine if a record field is stored off-page. @@ -718,54 +747,46 @@ rec_offs_nth_sql_null(const ulint* offsets, ulint n) @param[in] n nth field Returns nonzero if the extern bit is set in nth field of rec. @return nonzero if externally stored */ -inline -ulint -rec_offs_nth_extern(const ulint* offsets, ulint n) +inline ulint rec_offs_nth_extern(const offset_t *offsets, ulint n) { - return rec_offs_nth_flag(offsets, n, REC_OFFS_EXTERNAL); + return rec_offs_nth_type(offsets, n) == STORED_OFFPAGE; } /** Get a global flag of a record. @param[in] offsets rec_get_offsets() @param[in] flag flag to extract @return the flag of the record field */ -inline -ulint -rec_offs_any_flag(const ulint* offsets, ulint flag) +inline ulint rec_offs_any_flag(const offset_t *offsets, ulint flag) { - ut_ad(rec_offs_validate(NULL, NULL, offsets)); - return *rec_offs_base(offsets) & flag; + ut_ad(rec_offs_validate(NULL, NULL, offsets)); + return *rec_offs_base(offsets) & flag; } /** Determine if the offsets are for a record containing off-page columns. @param[in] offsets rec_get_offsets() @return nonzero if any off-page columns exist */ -inline bool rec_offs_any_extern(const ulint* offsets) +inline bool rec_offs_any_extern(const offset_t *offsets) { - return rec_offs_any_flag(offsets, REC_OFFS_EXTERNAL); + return rec_offs_any_flag(offsets, REC_OFFS_EXTERNAL); } /** Determine if the offsets are for a record that is missing fields. @param[in] offsets rec_get_offsets() @return nonzero if any fields need to be replaced with dict_index_t::instant_field_value() */ -inline -ulint -rec_offs_any_default(const ulint* offsets) +inline ulint rec_offs_any_default(const offset_t *offsets) { - return rec_offs_any_flag(offsets, REC_OFFS_DEFAULT); + return rec_offs_any_flag(offsets, REC_OFFS_DEFAULT); } /** Determine if the offsets are for other than ROW_FORMAT=REDUNDANT. @param[in] offsets rec_get_offsets() @return nonzero if ROW_FORMAT is COMPACT,DYNAMIC or COMPRESSED @retval 0 if ROW_FORMAT=REDUNDANT */ -inline -ulint -rec_offs_comp(const ulint* offsets) +inline ulint rec_offs_comp(const offset_t *offsets) { - ut_ad(rec_offs_validate(NULL, NULL, offsets)); - return(*rec_offs_base(offsets) & REC_OFFS_COMPACT); + ut_ad(rec_offs_validate(NULL, NULL, offsets)); + return (*rec_offs_base(offsets) & REC_OFFS_COMPACT); } /** Determine if the record is the metadata pseudo-record @@ -864,7 +885,7 @@ const byte* rec_get_nth_cfield( const rec_t* rec, const dict_index_t* index, - const ulint* offsets, + const offset_t* offsets, ulint n, ulint* len) { @@ -883,7 +904,7 @@ UNIV_INLINE ulint rec_offs_nth_size( /*==============*/ - const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */ ulint n) /*!< in: nth field */ MY_ATTRIBUTE((warn_unused_result)); @@ -894,7 +915,7 @@ UNIV_INLINE ulint rec_offs_n_extern( /*==============*/ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */ MY_ATTRIBUTE((warn_unused_result)); /***********************************************************//** This is used to modify the value of an already existing field in a record. @@ -907,7 +928,7 @@ void rec_set_nth_field( /*==============*/ rec_t* rec, /*!< in: record */ - const ulint* offsets,/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets,/*!< in: array returned by rec_get_offsets() */ ulint n, /*!< in: index number of the field */ const void* data, /*!< in: pointer to the data if not SQL null */ ulint len) /*!< in: length of the data or UNIV_SQL_NULL. @@ -935,7 +956,7 @@ UNIV_INLINE void rec_offs_set_n_alloc( /*=================*/ - ulint* offsets, /*!< out: array for rec_get_offsets(), + offset_t*offsets, /*!< out: array for rec_get_offsets(), must be allocated */ ulint n_alloc) /*!< in: number of elements */ MY_ATTRIBUTE((nonnull)); @@ -951,7 +972,7 @@ UNIV_INLINE ulint rec_offs_data_size( /*===============*/ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */ MY_ATTRIBUTE((warn_unused_result)); /**********************************************************//** Returns the total size of record minus data size of record. @@ -962,7 +983,7 @@ UNIV_INLINE ulint rec_offs_extra_size( /*================*/ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */ MY_ATTRIBUTE((warn_unused_result)); /**********************************************************//** Returns the total size of a physical record. @@ -971,7 +992,7 @@ UNIV_INLINE ulint rec_offs_size( /*==========*/ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */ MY_ATTRIBUTE((warn_unused_result)); #ifdef UNIV_DEBUG /**********************************************************//** @@ -982,7 +1003,7 @@ byte* rec_get_start( /*==========*/ const rec_t* rec, /*!< in: pointer to record */ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */ MY_ATTRIBUTE((warn_unused_result)); /**********************************************************//** Returns a pointer to the end of the record. @@ -992,7 +1013,7 @@ byte* rec_get_end( /*========*/ const rec_t* rec, /*!< in: pointer to record */ - const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + const offset_t* offsets)/*!< in: array returned by rec_get_offsets() */ MY_ATTRIBUTE((warn_unused_result)); #else /* UNIV_DEBUG */ # define rec_get_start(rec, offsets) ((rec) - rec_offs_extra_size(offsets)) @@ -1009,7 +1030,7 @@ rec_t* rec_copy( void* buf, const rec_t* rec, - const ulint* offsets); + const offset_t* offsets); /** Determine the size of a data tuple prefix in a temporary file. @param[in] index clustered or secondary index @@ -1038,7 +1059,7 @@ void rec_init_offsets_temp( const rec_t* rec, const dict_index_t* index, - ulint* offsets, + offset_t* offsets, ulint n_core, const dict_col_t::def_t*def_val, rec_comp_status_t status = REC_STATUS_ORDINARY) @@ -1052,7 +1073,7 @@ void rec_init_offsets_temp( const rec_t* rec, const dict_index_t* index, - ulint* offsets) + offset_t* offsets) MY_ATTRIBUTE((nonnull)); /** Convert a data tuple prefix to the temporary file format. @@ -1172,7 +1193,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() */ MY_ATTRIBUTE((nonnull)); /***************************************************************//** Prints an old-style physical record. */ @@ -1189,7 +1210,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() */ MY_ATTRIBUTE((nonnull)); /***************************************************************//** Prints a physical record. */ @@ -1198,7 +1219,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() */ MY_ATTRIBUTE((nonnull)); /***************************************************************//** Prints a physical record. */ @@ -1220,7 +1241,7 @@ rec_print( std::ostream& o, const rec_t* rec, ulint info, - const ulint* offsets); + const offset_t* offsets); /** Wrapper for pretty-printing a record */ struct rec_index_print @@ -1247,14 +1268,14 @@ operator<<(std::ostream& o, const rec_index_print& r); struct rec_offsets_print { /** Constructor */ - rec_offsets_print(const rec_t* rec, const ulint* offsets) : + rec_offsets_print(const rec_t* rec, const offset_t* offsets) : m_rec(rec), m_offsets(offsets) {} /** Record */ const rec_t* m_rec; /** Offsets to each field */ - const ulint* m_offsets; + const offset_t* m_offsets; }; /** Display a record. @@ -1271,7 +1292,7 @@ public: /** Construct a pretty-printed record. @param rec record with header @param offsets rec_get_offsets(rec, ...) */ - rec_printer(const rec_t* rec, const ulint* offsets) + rec_printer(const rec_t* rec, const offset_t* offsets) : std::ostringstream () { @@ -1284,7 +1305,7 @@ public: @param rec record, possibly lacking header @param info rec_get_info_bits(rec) @param offsets rec_get_offsets(rec, ...) */ - rec_printer(const rec_t* rec, ulint info, const ulint* offsets) + rec_printer(const rec_t* rec, ulint info, const offset_t* offsets) : std::ostringstream () { |