1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1995, 2014, 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 as published by the Free Software |
7 | Foundation; version 2 of the License. |
8 | |
9 | This program is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
11 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License along with |
14 | this program; if not, write to the Free Software Foundation, Inc., |
15 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
16 | |
17 | *****************************************************************************/ |
18 | |
19 | /******************************************************************//** |
20 | @file include/fut0lst.ic |
21 | File-based list utilities |
22 | |
23 | Created 11/28/1995 Heikki Tuuri |
24 | ***********************************************************************/ |
25 | |
26 | #include "fut0fut.h" |
27 | #include "mtr0log.h" |
28 | #include "buf0buf.h" |
29 | |
30 | /* We define the field offsets of a node for the list */ |
31 | #define FLST_PREV 0 /* 6-byte address of the previous list element; |
32 | the page part of address is FIL_NULL, if no |
33 | previous element */ |
34 | #define FLST_NEXT FIL_ADDR_SIZE /* 6-byte address of the next |
35 | list element; the page part of address |
36 | is FIL_NULL, if no next element */ |
37 | |
38 | /* We define the field offsets of a base node for the list */ |
39 | #define FLST_LEN 0 /* 32-bit list length field */ |
40 | #define FLST_FIRST 4 /* 6-byte address of the first element |
41 | of the list; undefined if empty list */ |
42 | #define FLST_LAST (4 + FIL_ADDR_SIZE) /* 6-byte address of the |
43 | last element of the list; undefined |
44 | if empty list */ |
45 | |
46 | /********************************************************************//** |
47 | Writes a file address. */ |
48 | UNIV_INLINE |
49 | void |
50 | flst_write_addr( |
51 | /*============*/ |
52 | fil_faddr_t* faddr, /*!< in: pointer to file faddress */ |
53 | fil_addr_t addr, /*!< in: file address */ |
54 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
55 | { |
56 | ut_ad(faddr && mtr); |
57 | ut_ad(mtr_memo_contains_page_flagged(mtr, faddr, |
58 | MTR_MEMO_PAGE_X_FIX |
59 | | MTR_MEMO_PAGE_SX_FIX)); |
60 | ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA); |
61 | ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); |
62 | |
63 | mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr); |
64 | mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset, |
65 | MLOG_2BYTES, mtr); |
66 | } |
67 | |
68 | /********************************************************************//** |
69 | Reads a file address. |
70 | @return file address */ |
71 | UNIV_INLINE |
72 | fil_addr_t |
73 | flst_read_addr( |
74 | /*===========*/ |
75 | const fil_faddr_t* faddr, /*!< in: pointer to file faddress */ |
76 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
77 | { |
78 | fil_addr_t addr; |
79 | |
80 | ut_ad(faddr && mtr); |
81 | |
82 | addr.page = mtr_read_ulint(faddr + FIL_ADDR_PAGE, MLOG_4BYTES, mtr); |
83 | addr.boffset = mtr_read_ulint(faddr + FIL_ADDR_BYTE, MLOG_2BYTES, |
84 | mtr); |
85 | ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA); |
86 | ut_a(ut_align_offset(faddr, srv_page_size) >= FIL_PAGE_DATA); |
87 | return(addr); |
88 | } |
89 | |
90 | /********************************************************************//** |
91 | Initializes a list base node. */ |
92 | UNIV_INLINE |
93 | void |
94 | flst_init( |
95 | /*======*/ |
96 | flst_base_node_t* base, /*!< in: pointer to base node */ |
97 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
98 | { |
99 | ut_ad(mtr_memo_contains_page_flagged(mtr, base, |
100 | MTR_MEMO_PAGE_X_FIX |
101 | | MTR_MEMO_PAGE_SX_FIX)); |
102 | |
103 | mlog_write_ulint(base + FLST_LEN, 0, MLOG_4BYTES, mtr); |
104 | flst_write_addr(base + FLST_FIRST, fil_addr_null, mtr); |
105 | flst_write_addr(base + FLST_LAST, fil_addr_null, mtr); |
106 | } |
107 | |
108 | /** Get the length of a list. |
109 | @param[in] base base node |
110 | @return length */ |
111 | UNIV_INLINE |
112 | ulint |
113 | flst_get_len( |
114 | const flst_base_node_t* base) |
115 | { |
116 | return(mach_read_from_4(base + FLST_LEN)); |
117 | } |
118 | |
119 | /********************************************************************//** |
120 | Gets list first node address. |
121 | @return file address */ |
122 | UNIV_INLINE |
123 | fil_addr_t |
124 | flst_get_first( |
125 | /*===========*/ |
126 | const flst_base_node_t* base, /*!< in: pointer to base node */ |
127 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
128 | { |
129 | return(flst_read_addr(base + FLST_FIRST, mtr)); |
130 | } |
131 | |
132 | /********************************************************************//** |
133 | Gets list last node address. |
134 | @return file address */ |
135 | UNIV_INLINE |
136 | fil_addr_t |
137 | flst_get_last( |
138 | /*==========*/ |
139 | const flst_base_node_t* base, /*!< in: pointer to base node */ |
140 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
141 | { |
142 | return(flst_read_addr(base + FLST_LAST, mtr)); |
143 | } |
144 | |
145 | /********************************************************************//** |
146 | Gets list next node address. |
147 | @return file address */ |
148 | UNIV_INLINE |
149 | fil_addr_t |
150 | flst_get_next_addr( |
151 | /*===============*/ |
152 | const flst_node_t* node, /*!< in: pointer to node */ |
153 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
154 | { |
155 | return(flst_read_addr(node + FLST_NEXT, mtr)); |
156 | } |
157 | |
158 | /********************************************************************//** |
159 | Gets list prev node address. |
160 | @return file address */ |
161 | UNIV_INLINE |
162 | fil_addr_t |
163 | flst_get_prev_addr( |
164 | /*===============*/ |
165 | const flst_node_t* node, /*!< in: pointer to node */ |
166 | mtr_t* mtr) /*!< in: mini-transaction handle */ |
167 | { |
168 | return(flst_read_addr(node + FLST_PREV, mtr)); |
169 | } |
170 | |