📄 rem0rec.ic
字号:
{ ut_ad(rec); ut_ad((bits & ~REC_INFO_BITS_MASK) == 0); rec_set_bit_field_1(rec, bits, comp ? REC_NEW_INFO_BITS : REC_OLD_INFO_BITS, REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT);}/**********************************************************The following function is used to set the status bits of a new-style record. */UNIV_INLINEvoidrec_set_status(/*===========*/ rec_t* rec, /* in: physical record */ ulint bits) /* in: info bits */{ ut_ad(rec); ut_ad((bits & ~REC_NEW_STATUS_MASK) == 0); rec_set_bit_field_1(rec, bits, REC_NEW_STATUS, REC_NEW_STATUS_MASK, REC_NEW_STATUS_SHIFT);}/**********************************************************The following function is used to retrieve the info and statusbits of a record. (Only compact records have status bits.) */UNIV_INLINEulintrec_get_info_and_status_bits(/*=========================*/ /* out: info bits */ rec_t* rec, /* in: physical record */ 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 (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); ut_ad(!(bits & ~(REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT))); } return(bits);}/**********************************************************The following function is used to set the info and statusbits of a record. (Only compact records have status bits.) */UNIV_INLINEvoidrec_set_info_and_status_bits(/*=========================*/ rec_t* rec, /* in: physical record */ ulint comp, /* in: nonzero=compact page format */ ulint bits) /* in: info 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) { rec_set_status(rec, bits & REC_NEW_STATUS_MASK); } else { ut_ad(!(bits & ~(REC_INFO_BITS_MASK >> REC_INFO_BITS_SHIFT))); } rec_set_info_bits(rec, comp, bits & ~REC_NEW_STATUS_MASK);}/**********************************************************The following function tells if record is delete marked. */UNIV_INLINEulintrec_get_deleted_flag(/*=================*/ /* out: nonzero if delete marked */ rec_t* rec, /* in: physical record */ ulint comp) /* in: nonzero=compact page format */{ if (UNIV_EXPECT(comp, REC_OFFS_COMPACT)) { return(UNIV_UNLIKELY(rec_get_bit_field_1(rec, REC_NEW_INFO_BITS, REC_INFO_DELETED_FLAG, REC_INFO_BITS_SHIFT))); } else { return(UNIV_UNLIKELY(rec_get_bit_field_1(rec, REC_OLD_INFO_BITS, REC_INFO_DELETED_FLAG, REC_INFO_BITS_SHIFT))); }}/**********************************************************The following function is used to set the deleted bit. */UNIV_INLINEvoidrec_set_deleted_flag(/*=================*/ rec_t* rec, /* in: physical record */ ulint comp, /* in: nonzero=compact page format */ ulint flag) /* in: nonzero if delete marked */{ ulint val; val = rec_get_info_bits(rec, comp); if (flag) { val |= REC_INFO_DELETED_FLAG; } else { val &= ~REC_INFO_DELETED_FLAG; } rec_set_info_bits(rec, comp, val);}/**********************************************************The following function tells if a new-style record is a node pointer. */UNIV_INLINEiboolrec_get_node_ptr_flag(/*=================*/ /* out: TRUE if node pointer */ rec_t* rec) /* in: physical record */{ return(REC_STATUS_NODE_PTR == rec_get_status(rec));}/**********************************************************The following function is used to get the order number of the record in theheap of the index page. */UNIV_INLINEulintrec_get_heap_no(/*=============*/ /* out: heap order number */ rec_t* rec, /* in: physical record */ ulint comp) /* in: nonzero=compact page format */{ ulint ret; ut_ad(rec); ret = rec_get_bit_field_2(rec, comp ? REC_NEW_HEAP_NO : REC_OLD_HEAP_NO, REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT); ut_ad(ret <= REC_MAX_HEAP_NO); return(ret);} /**********************************************************The following function is used to set the heap number field in the record. */UNIV_INLINEvoidrec_set_heap_no(/*=============*/ rec_t* rec, /* in: physical record */ ulint comp, /* in: nonzero=compact page format */ ulint heap_no)/* in: the heap number */{ ut_ad(heap_no <= REC_MAX_HEAP_NO); rec_set_bit_field_2(rec, heap_no, comp ? REC_NEW_HEAP_NO : REC_OLD_HEAP_NO, REC_HEAP_NO_MASK, REC_HEAP_NO_SHIFT);}/**********************************************************The following function is used to test whether the data offsets in the recordare stored in one-byte or two-byte format. */UNIV_INLINEiboolrec_get_1byte_offs_flag(/*====================*/ /* out: TRUE if 1-byte form */ rec_t* rec) /* in: physical record */{#if TRUE != 1#error "TRUE != 1"#endif return(rec_get_bit_field_1(rec, REC_OLD_SHORT, REC_OLD_SHORT_MASK, REC_OLD_SHORT_SHIFT));}/**********************************************************The following function is used to set the 1-byte offsets flag. */UNIV_INLINEvoidrec_set_1byte_offs_flag(/*====================*/ rec_t* rec, /* in: physical record */ ibool flag) /* in: TRUE if 1byte form */{#if TRUE != 1#error "TRUE != 1"#endif ut_ad(flag <= TRUE); rec_set_bit_field_1(rec, flag, REC_OLD_SHORT, REC_OLD_SHORT_MASK, REC_OLD_SHORT_SHIFT);}/**********************************************************Returns the offset of nth field end if the record is stored in the 1-byteoffsets form. If the field is SQL null, the flag is ORed in the returnedvalue. */UNIV_INLINEulintrec_1_get_field_end_info(/*=====================*/ /* out: offset of the start of the field, SQL null flag ORed */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(rec_get_1byte_offs_flag(rec)); ut_ad(n < rec_get_n_fields_old(rec)); return(mach_read_from_1(rec - (REC_N_OLD_EXTRA_BYTES + n + 1)));} /**********************************************************Returns the offset of nth field end if the record is stored in the 2-byteoffsets form. If the field is SQL null, the flag is ORed in the returnedvalue. */UNIV_INLINEulintrec_2_get_field_end_info(/*=====================*/ /* out: offset of the start of the field, SQL null flag and extern storage flag ORed */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(!rec_get_1byte_offs_flag(rec)); ut_ad(n < rec_get_n_fields_old(rec)); return(mach_read_from_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n + 2)));}#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#endif /* UNIV_DEBUG *//* Get the base address of offsets. The extra_size is stored atthis position, and following positions hold the end offsets ofthe fields. */#define rec_offs_base(offsets) (offsets + REC_OFFS_HEADER_SIZE)/************************************************************** The following function returns the number of allocated elementsfor an array of offsets. */UNIV_INLINEulintrec_offs_get_n_alloc(/*=================*/ /* out: number of elements */ const ulint* offsets)/* in: array for rec_get_offsets() */{ ulint n_alloc; ut_ad(offsets); n_alloc = offsets[0]; ut_ad(n_alloc > 0); return(n_alloc);}/************************************************************** The following function sets the number of allocated elementsfor an array of offsets. */UNIV_INLINEvoidrec_offs_set_n_alloc(/*=================*/ ulint* offsets, /* in: array for rec_get_offsets() */ ulint n_alloc) /* in: number of elements */{ ut_ad(offsets); ut_ad(n_alloc > 0); offsets[0] = n_alloc;}/************************************************************** The following function returns the number of fields in a record. */UNIV_INLINEulintrec_offs_n_fields(/*===============*/ /* out: number of fields */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint n_fields; ut_ad(offsets); n_fields = offsets[1]; ut_ad(n_fields > 0); ut_ad(n_fields <= REC_MAX_N_FIELDS); ut_ad(n_fields + REC_OFFS_HEADER_SIZE <= rec_offs_get_n_alloc(offsets)); return(n_fields);}/****************************************************************Validates offsets returned by rec_get_offsets(). */UNIV_INLINEiboolrec_offs_validate(/*==============*/ /* out: TRUE if valid */ rec_t* rec, /* in: record or NULL */ dict_index_t* index, /* in: record descriptor or NULL */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint i = rec_offs_n_fields(offsets); ulint last = ULINT_MAX; ulint comp = *rec_offs_base(offsets) & REC_OFFS_COMPACT; if (rec) { ut_ad((ulint) rec == offsets[2]); if (!comp) { ut_a(rec_get_n_fields_old(rec) >= i); } } if (index) { ulint max_n_fields; ut_ad((ulint) index == offsets[3]); max_n_fields = ut_max( dict_index_get_n_fields(index), dict_index_get_n_unique_in_tree(index) + 1); if (comp && rec) { switch (rec_get_status(rec)) { case REC_STATUS_ORDINARY: break; case REC_STATUS_NODE_PTR: max_n_fields = dict_index_get_n_unique_in_tree(index) + 1; break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: max_n_fields = 1; break; default: ut_error; } } /* index->n_def == 0 for dummy indexes if !comp */ ut_a(!comp || index->n_def); ut_a(!index->n_def || i <= max_n_fields); } while (i--) { ulint curr = rec_offs_base(offsets)[1 + i] & REC_OFFS_MASK; ut_a(curr <= last); last = curr; } return(TRUE);}/****************************************************************Updates debug data in offsets, in order to avoid bogusrec_offs_validate() failures. */UNIV_INLINEvoidrec_offs_make_valid(/*================*/ rec_t* rec __attribute__((unused)), /* in: record */ dict_index_t* index __attribute__((unused)), /* in: record descriptor */ ulint* offsets __attribute__((unused))) /* in: array returned by rec_get_offsets() */{#ifdef UNIV_DEBUG ut_ad(rec_get_n_fields(rec, index) >= rec_offs_n_fields(offsets)); offsets[2] = (ulint) rec; offsets[3] = (ulint) index;#endif /* UNIV_DEBUG */}/****************************************************************The following function is used to get a pointer to the nthdata field in a record. */UNIV_INLINEbyte*rec_get_nth_field(/*==============*/ /* out: pointer to the field */ rec_t* rec, /* in: record */ const ulint* 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 */{ byte* field; ulint length; ut_ad(rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(n < rec_offs_n_fields(offsets)); ut_ad(len); if (UNIV_UNLIKELY(n == 0)) { field = rec; } else { field = rec + (rec_offs_base(offsets)[n] & REC_OFFS_MASK); } length = rec_offs_base(offsets)[1 + n]; if (length & REC_OFFS_SQL_NULL) { length = UNIV_SQL_NULL; } else { length &= REC_OFFS_MASK; length -= field - rec; } *len = length; return(field);}/**********************************************************Determine if the offsets are for a record in the newcompact format. */UNIV_INLINEulintrec_offs_comp(/*==========*/ /* out: nonzero if compact format */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ut_ad(rec_offs_validate(NULL, NULL, offsets)); return(*rec_offs_base(offsets) & REC_OFFS_COMPACT);}/**********************************************************Returns nonzero if the extern bit is set in nth field of rec. */UNIV_INLINEulintrec_offs_nth_extern(/*================*/ /* out: nonzero if externally stored */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint n) /* in: nth field */{ ut_ad(rec_offs_validate(NULL, NULL, offsets)); ut_ad(n < rec_offs_n_fields(offsets)); return(UNIV_UNLIKELY(rec_offs_base(offsets)[1 + n] & REC_OFFS_EXTERNAL));}/**********************************************************Returns nonzero if the SQL NULL bit is set in nth field of rec. */UNIV_INLINEulintrec_offs_nth_sql_null(/*==================*/ /* out: nonzero if SQL NULL */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint n) /* in: nth field */{ ut_ad(rec_offs_validate(NULL, NULL, offsets)); ut_ad(n < rec_offs_n_fields(offsets)); return(UNIV_UNLIKELY(rec_offs_base(offsets)[1 + n] & REC_OFFS_SQL_NULL));}/**********************************************************Gets the physical size of a field. */UNIV_INLINEulintrec_offs_nth_size(/*==============*/ /* out: length of field */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint n) /* in: nth field */{ ut_ad(rec_offs_validate(NULL, NULL, offsets)); ut_ad(n < rec_offs_n_fields(offsets)); return((rec_offs_base(offsets)[1 + n] - rec_offs_base(offsets)[n]) & REC_OFFS_MASK);}/**********************************************************Returns TRUE if the extern bit is set in any of the fieldsof an old-style record. */UNIV_INLINEiboolrec_offs_any_extern(/*================*/ /* out: TRUE if a field is stored externally */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint i; for (i = rec_offs_n_fields(offsets); i--; ) { if (rec_offs_nth_extern(offsets, i)) { return(TRUE); } } return(FALSE);}/***************************************************************Sets the value of the ith field extern storage bit. */UNIV_INLINE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -