diff options
Diffstat (limited to 'storage/innobase/include/fut0lst.h')
-rw-r--r-- | storage/innobase/include/fut0lst.h | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/storage/innobase/include/fut0lst.h b/storage/innobase/include/fut0lst.h new file mode 100644 index 00000000..746dab80 --- /dev/null +++ b/storage/innobase/include/fut0lst.h @@ -0,0 +1,156 @@ +/***************************************************************************** + +Copyright (c) 1995, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, 2022, MariaDB Corporation. + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +/******************************************************************//** +@file include/fut0lst.h +File-based list utilities + +Created 11/28/1995 Heikki Tuuri +***********************************************************************/ + +#pragma once + +/* The physical size of a list base node in bytes */ +#define FLST_BASE_NODE_SIZE (4 + 2 * FIL_ADDR_SIZE) +/* The physical size of a list node in bytes */ +#define FLST_NODE_SIZE (2 * FIL_ADDR_SIZE) + +#ifdef UNIV_INNOCHECKSUM +# include "fil0fil.h" +#else +# include "mtr0log.h" + +typedef byte flst_base_node_t; +typedef byte flst_node_t; + +/* We define the field offsets of a node for the list */ +#define FLST_PREV 0 /* 6-byte address of the previous list element; + the page part of address is FIL_NULL, if no + previous element */ +#define FLST_NEXT FIL_ADDR_SIZE /* 6-byte address of the next + list element; the page part of address + is FIL_NULL, if no next element */ + +/* We define the field offsets of a base node for the list */ +#define FLST_LEN 0 /* 32-bit list length field */ +#define FLST_FIRST 4 /* 6-byte address of the first element + of the list; undefined if empty list */ +#define FLST_LAST (4 + FIL_ADDR_SIZE) /* 6-byte address of the + last element of the list; undefined + if empty list */ + +/** Initialize a zero-initialized list base node. +@param[in,out] block file page +@param[in] ofs byte offset of the list base node +@param[in,out] mtr mini-transaction */ +inline void flst_init(const buf_block_t* block, uint16_t ofs, mtr_t* mtr) +{ + ut_d(const page_t *page= block->page.frame); + ut_ad(!mach_read_from_2(FLST_LEN + ofs + page)); + ut_ad(!mach_read_from_2(FLST_FIRST + FIL_ADDR_BYTE + ofs + page)); + ut_ad(!mach_read_from_2(FLST_LAST + FIL_ADDR_BYTE + ofs + page)); + compile_time_assert(FIL_NULL == 0xffU * 0x1010101U); + mtr->memset(block, FLST_FIRST + FIL_ADDR_PAGE + ofs, 4, 0xff); + mtr->memset(block, FLST_LAST + FIL_ADDR_PAGE + ofs, 4, 0xff); +} + +/** Initialize a list base node. +@param[in] block file page +@param[in,out] base base node +@param[in,out] mtr mini-transaction */ +void flst_init(const buf_block_t &block, byte *base, mtr_t *mtr) + MY_ATTRIBUTE((nonnull)); + +/** Append a file list node to a list. +@param[in,out] base base node block +@param[in] boffset byte offset of the base node +@param[in,out] add block to be added +@param[in] aoffset byte offset of the node to be added +@param[in,out] mtr mini-transaction +@return error code */ +dberr_t flst_add_last(buf_block_t *base, uint16_t boffset, + buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Prepend a file list node to a list. +@param[in,out] base base node block +@param[in] boffset byte offset of the base node +@param[in,out] add block to be added +@param[in] aoffset byte offset of the node to be added +@param[in,out] mtr mini-transaction +@return error code */ +dberr_t flst_add_first(buf_block_t *base, uint16_t boffset, + buf_block_t *add, uint16_t aoffset, mtr_t *mtr) + MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Remove a file list node. +@param[in,out] base base node block +@param[in] boffset byte offset of the base node +@param[in,out] cur block to be removed +@param[in] coffset byte offset of the current record to be removed +@param[in,out] mtr mini-transaction +@return error code */ +dberr_t flst_remove(buf_block_t *base, uint16_t boffset, + buf_block_t *cur, uint16_t coffset, mtr_t *mtr) + MY_ATTRIBUTE((nonnull, warn_unused_result)); + +/** @return the length of a list */ +inline uint32_t flst_get_len(const flst_base_node_t *base) +{ + return mach_read_from_4(base + FLST_LEN); +} + +/** @return a file address */ +inline fil_addr_t flst_read_addr(const byte *faddr) +{ + fil_addr_t addr= { mach_read_from_4(faddr + FIL_ADDR_PAGE), + mach_read_from_2(faddr + FIL_ADDR_BYTE) }; + ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA); + ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); + return addr; +} + +/** @return list first node address */ +inline fil_addr_t flst_get_first(const flst_base_node_t *base) +{ + return flst_read_addr(base + FLST_FIRST); +} + +/** @return list last node address */ +inline fil_addr_t flst_get_last(const flst_base_node_t *base) +{ + return flst_read_addr(base + FLST_LAST); +} + +/** @return list next node address */ +inline fil_addr_t flst_get_next_addr(const flst_node_t* node) +{ + return flst_read_addr(node + FLST_NEXT); +} + +/** @return list prev node address */ +inline fil_addr_t flst_get_prev_addr(const flst_node_t *node) +{ + return flst_read_addr(node + FLST_PREV); +} + +# ifdef UNIV_DEBUG +/** Validate a file-based list. */ +void flst_validate(const buf_block_t *base, uint16_t boffset, mtr_t *mtr); +# endif + +#endif /* !UNIV_INNOCHECKSUM */ |