1 /*****************************************************************************
2 
3 Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/fut0lst.h
28  File-based list utilities
29 
30  Created 11/28/1995 Heikki Tuuri
31  ***********************************************************************/
32 
33 #ifndef fut0lst_h
34 #define fut0lst_h
35 
36 #include "univ.i"
37 
38 #include "fil0fil.h"
39 #include "mtr0mtr.h"
40 
41 /* The C 'types' of base node and list node: these should be used to
42 write self-documenting code. Of course, the sizeof macro cannot be
43 applied to these types! */
44 
45 typedef byte flst_base_node_t;
46 typedef byte flst_node_t;
47 
48 /* The physical size of a list base node in bytes */
49 constexpr ulint FLST_BASE_NODE_SIZE = 4 + 2 * FIL_ADDR_SIZE;
50 
51 /* The physical size of a list node in bytes */
52 constexpr ulint FLST_NODE_SIZE = 2 * FIL_ADDR_SIZE;
53 
54 /** Initializes a list base node.
55 @param[in]	base	pointer to base node
56 @param[in]	mtr	mini-transaction handle */
57 UNIV_INLINE
58 void flst_init(flst_base_node_t *base, mtr_t *mtr);
59 
60 /** Adds a node as the last node in a list. */
61 void flst_add_last(
62     flst_base_node_t *base, /*!< in: pointer to base node of list */
63     flst_node_t *node,      /*!< in: node to add */
64     mtr_t *mtr);            /*!< in: mini-transaction handle */
65 /** Adds a node as the first node in a list. */
66 void flst_add_first(
67     flst_base_node_t *base, /*!< in: pointer to base node of list */
68     flst_node_t *node,      /*!< in: node to add */
69     mtr_t *mtr);            /*!< in: mini-transaction handle */
70 /** Removes a node. */
71 void flst_remove(
72     flst_base_node_t *base, /*!< in: pointer to base node of list */
73     flst_node_t *node2,     /*!< in: node to remove */
74     mtr_t *mtr);            /*!< in: mini-transaction handle */
75 /** Get the length of a list.
76 @param[in]	base	base node
77 @return length */
78 UNIV_INLINE
79 ulint flst_get_len(const flst_base_node_t *base);
80 
81 /** Gets list first node address.
82 @param[in]	base	pointer to base node
83 @param[in]	mtr	mini-transaction handle
84 @return file address */
85 UNIV_INLINE
86 fil_addr_t flst_get_first(const flst_base_node_t *base, mtr_t *mtr);
87 
88 /** Gets list last node address.
89 @param[in]	base	pointer to base node
90 @param[in]	mtr	mini-transaction handle
91 @return file address */
92 UNIV_INLINE
93 fil_addr_t flst_get_last(const flst_base_node_t *base, mtr_t *mtr);
94 
95 /** Gets list next node address.
96 @param[in]	node	pointer to node
97 @param[in]	mtr	mini-transaction handle
98 @return file address */
99 UNIV_INLINE
100 fil_addr_t flst_get_next_addr(const flst_node_t *node, mtr_t *mtr);
101 
102 /** Gets list prev node address.
103 @param[in]	node	pointer to node
104 @param[in]	mtr	mini-transaction handle
105 @return file address */
106 UNIV_INLINE
107 fil_addr_t flst_get_prev_addr(const flst_node_t *node, mtr_t *mtr);
108 
109 /** Writes a file address.
110 @param[in]	faddr	pointer to file faddress
111 @param[in]	addr	file address
112 @param[in]	mtr	mini-transaction handle */
113 UNIV_INLINE
114 void flst_write_addr(fil_faddr_t *faddr, fil_addr_t addr, mtr_t *mtr);
115 
116 /** Reads a file address.
117 @param[in]	faddr	pointer to file faddress
118 @param[in]	mtr	mini-transaction handle
119 @return file address */
120 UNIV_INLINE
121 fil_addr_t flst_read_addr(const fil_faddr_t *faddr, mtr_t *mtr);
122 
123 /** Validates a file-based list.
124  @return true if ok */
125 ibool flst_validate(
126     const flst_base_node_t *base, /*!< in: pointer to base node of list */
127     mtr_t *mtr1);                 /*!< in: mtr */
128 
129 /** Inserts a node after another in a list.
130 @param[in]	base	pointer to base node of list
131 @param[in]	node1	node to insert after
132 @param[in]	node2	node to add
133 @param[in]	mtr	mini-transaction handle. */
134 void flst_insert_after(flst_base_node_t *base, flst_node_t *node1,
135                        flst_node_t *node2, mtr_t *mtr);
136 
137 /** Inserts a node before another in a list.
138 @param[in]	base	pointer to base node of list
139 @param[in]	node2	node to insert
140 @param[in]	node3	node to insert before
141 @param[in]	mtr	mini-transaction handle. */
142 void flst_insert_before(flst_base_node_t *base, flst_node_t *node2,
143                         flst_node_t *node3, mtr_t *mtr);
144 
145 #include "fut0lst.ic"
146 
147 /** In-memory representation of flst_base_node_t */
148 struct flst_bnode_t {
149   ulint len;
150   fil_addr_t first;
151   fil_addr_t last;
152 
flst_bnode_tflst_bnode_t153   flst_bnode_t() : len(0) {}
154 
flst_bnode_tflst_bnode_t155   flst_bnode_t(const flst_base_node_t *base, mtr_t *mtr)
156       : len(flst_get_len(base)),
157         first(flst_get_first(base, mtr)),
158         last(flst_get_last(base, mtr)) {}
159 
setflst_bnode_t160   void set(const flst_base_node_t *base, mtr_t *mtr) {
161     len = flst_get_len(base);
162     first = flst_get_first(base, mtr);
163     last = flst_get_last(base, mtr);
164   }
165 
resetflst_bnode_t166   void reset() {
167     len = 0;
168     first = fil_addr_null;
169     last = fil_addr_null;
170   }
171 
printflst_bnode_t172   std::ostream &print(std::ostream &out) const {
173     out << "[flst_base_node_t: len=" << len << ", first=" << first
174         << ", last=" << last << "]";
175     return (out);
176   }
177 };
178 
179 inline std::ostream &operator<<(std::ostream &out, const flst_bnode_t &obj) {
180   return (obj.print(out));
181 }
182 
183 #endif /* fut0lst_h */
184