1455.3.1
by Vladimir Kolesnikov
lp:drizzle + pbxt 1.1 + test results |
1 |
/* Copyright (c) 2007 PrimeBase Technologies GmbH
|
2 |
*
|
|
3 |
* PrimeBase XT
|
|
4 |
*
|
|
5 |
* This program is free software; you can redistribute it and/or modify
|
|
6 |
* it under the terms of the GNU General Public License as published by
|
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
|
8 |
* (at your option) any later version.
|
|
9 |
*
|
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13 |
* GNU General Public License for more details.
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License
|
|
16 |
* along with this program; if not, write to the Free Software
|
|
17 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18 |
*
|
|
19 |
* 2007-10-31 Paul McCullagh
|
|
20 |
*
|
|
21 |
* H&G2JCtL
|
|
22 |
*
|
|
23 |
* The new table cache. Caches all non-index data. This includes the data
|
|
24 |
* files and the row pointer files.
|
|
25 |
*/
|
|
26 |
||
27 |
#ifndef __xactlog_xt_h__
|
|
28 |
#define __xactlog_xt_h__
|
|
29 |
||
30 |
#include "pthread_xt.h" |
|
31 |
#include "filesys_xt.h" |
|
32 |
#include "sortedlist_xt.h" |
|
33 |
||
34 |
struct XTThread; |
|
35 |
struct XTOpenTable; |
|
36 |
struct XTDatabase; |
|
37 |
||
38 |
#ifdef DEBUG
|
|
39 |
//#define XT_USE_CACHE_DEBUG_SIZES
|
|
40 |
#endif
|
|
41 |
||
42 |
#ifdef XT_USE_CACHE_DEBUG_SIZES
|
|
43 |
#define XT_XLC_BLOCK_SHIFTS 5
|
|
44 |
#define XT_XLC_FILE_SLOTS 7
|
|
45 |
#define XT_XLC_SEGMENT_SHIFTS 1
|
|
46 |
#define XT_XLC_MAX_FLUSH_SEG_COUNT 10
|
|
47 |
#define XT_XLC_MAX_FREE_COUNT 10
|
|
48 |
#else
|
|
49 |
/* Block size is determined by the number of shifts 1 << 15 = 32K */
|
|
50 |
#define XT_XLC_BLOCK_SHIFTS 15
|
|
51 |
#define XT_XLC_FILE_SLOTS 71
|
|
52 |
/* The number of segments are determined by the segment shifts 1 << 3 = 8 */
|
|
53 |
#define XT_XLC_SEGMENT_SHIFTS 3
|
|
54 |
#define XT_XLC_MAX_FLUSH_SEG_COUNT 250
|
|
55 |
#define XT_XLC_MAX_FREE_COUNT 100
|
|
56 |
#endif
|
|
57 |
||
58 |
#define XT_XLC_BLOCK_SIZE (1 << XT_XLC_BLOCK_SHIFTS)
|
|
59 |
#define XT_XLC_BLOCK_MASK (XT_XLC_BLOCK_SIZE - 1)
|
|
60 |
||
61 |
#define XT_TIME_DIFF(start, now) (\
|
|
62 |
((xtWord4) (now) < (xtWord4) (start)) ? \
|
|
63 |
((xtWord4) 0XFFFFFFFF - ((xtWord4) (start) - (xtWord4) (now))) : \
|
|
64 |
((xtWord4) (now) - (xtWord4) (start)))
|
|
65 |
||
66 |
#define XLC_SEGMENT_COUNT ((off_t) 1 << XT_XLC_SEGMENT_SHIFTS)
|
|
67 |
#define XLC_SEGMENT_MASK (XLC_SEGMENT_COUNT - 1)
|
|
68 |
#define XLC_MAX_FLUSH_COUNT (XT_XLC_MAX_FLUSH_SEG_COUNT * XLC_SEGMENT_COUNT)
|
|
69 |
||
70 |
#define XLC_BLOCK_FREE 0
|
|
71 |
#define XLC_BLOCK_READING 1
|
|
72 |
#define XLC_BLOCK_CLEAN 2
|
|
73 |
||
74 |
#define XT_RECYCLE_LOGS 0
|
|
75 |
#define XT_DELETE_LOGS 1
|
|
76 |
#define XT_KEEP_LOGS 2
|
|
77 |
||
78 |
#define XT_XLOG_NO_WRITE_NO_FLUSH 0
|
|
79 |
#define XT_XLOG_WRITE_AND_FLUSH 1
|
|
80 |
#define XT_XLOG_WRITE_AND_NO_FLUSH 2
|
|
81 |
||
82 |
/* LOG CACHE ---------------------------------------------------- */
|
|
83 |
||
84 |
typedef struct XTXLogBlock { |
|
85 |
off_t xlb_address; /* The block address. */ |
|
86 |
xtLogID xlb_log_id; /* The log id of the block. */ |
|
87 |
xtWord4 xlb_state; /* Block status. */ |
|
88 |
struct XTXLogBlock *xlb_next; /* Pointer to next block on hash list, or next free block on free list. */ |
|
89 |
xtWord1 xlb_data[XT_XLC_BLOCK_SIZE]; |
|
90 |
} XTXLogBlockRec, *XTXLogBlockPtr; |
|
91 |
||
92 |
/* A disk cache segment. The cache is divided into a number of segments
|
|
93 |
* to improve concurrency.
|
|
94 |
*/
|
|
95 |
typedef struct XTXLogCacheSeg { |
|
96 |
xt_mutex_type lcs_lock; /* The cache segment lock. */ |
|
97 |
xt_cond_type lcs_cond; |
|
98 |
XTXLogBlockPtr *lcs_hash_table; |
|
99 |
} XTXLogCacheSegRec, *XTXLogCacheSegPtr; |
|
100 |
||
101 |
typedef struct XTXLogCache { |
|
102 |
xt_mutex_type xlc_lock; /* The public cache lock. */ |
|
103 |
xt_cond_type xlc_cond; /* The public cache wait condition. */ |
|
104 |
XTXLogCacheSegRec xlc_segment[XLC_SEGMENT_COUNT]; |
|
105 |
XTXLogBlockPtr xlc_blocks; |
|
106 |
XTXLogBlockPtr xlc_blocks_end; |
|
107 |
XTXLogBlockPtr xlc_next_to_free; |
|
108 |
xtWord4 xlc_free_count; |
|
109 |
xtWord4 xlc_hash_size; |
|
110 |
xtWord4 xlc_block_count; |
|
111 |
xtWord8 xlc_upper_limit; |
|
112 |
} XTXLogCacheRec; |
|
113 |
||
114 |
/* LOG ENTRIES ---------------------------------------------------- */
|
|
115 |
||
116 |
#define XT_LOG_ENT_EOF 0
|
|
117 |
#define XT_LOG_ENT_HEADER 1
|
|
118 |
#define XT_LOG_ENT_NEW_LOG 2 /* Move to the next log! NOTE!! May not appear in a group!! */ |
|
119 |
#define XT_LOG_ENT_DEL_LOG 3 /* Delete the given transaction/data log. */ |
|
120 |
#define XT_LOG_ENT_NEW_TAB 4 /* This record indicates a new table was created. */ |
|
121 |
||
122 |
#define XT_LOG_ENT_COMMIT 5 /* Transaction was committed. */ |
|
123 |
#define XT_LOG_ENT_ABORT 6 /* Transaction was aborted. */ |
|
124 |
#define XT_LOG_ENT_CLEANUP 7 /* Written after a cleanup. */ |
|
125 |
||
126 |
#define XT_LOG_ENT_REC_MODIFIED 8 /* This records has been modified by the transaction. */ |
|
127 |
#define XT_LOG_ENT_UPDATE 9
|
|
128 |
#define XT_LOG_ENT_UPDATE_BG 10
|
|
129 |
#define XT_LOG_ENT_UPDATE_FL 11
|
|
130 |
#define XT_LOG_ENT_UPDATE_FL_BG 12
|
|
131 |
#define XT_LOG_ENT_INSERT 13
|
|
132 |
#define XT_LOG_ENT_INSERT_BG 14
|
|
133 |
#define XT_LOG_ENT_INSERT_FL 15
|
|
134 |
#define XT_LOG_ENT_INSERT_FL_BG 16
|
|
135 |
#define XT_LOG_ENT_DELETE 17
|
|
136 |
#define XT_LOG_ENT_DELETE_BG 18
|
|
137 |
#define XT_LOG_ENT_DELETE_FL 19
|
|
138 |
#define XT_LOG_ENT_DELETE_FL_BG 20
|
|
139 |
||
140 |
#define XT_DEFUNKT_REC_FREED 21 /* This record has been placed in the free list. */ |
|
141 |
#define XT_DEFUNKT_REC_REMOVED 22 /* Free record and dependecies: index references, blob references. */ |
|
142 |
#define XT_DEFUNKT_REC_REMOVED_EXT 23 /* Free record and dependecies: index references, extended data, blob references. */ |
|
143 |
#define XT_LOG_ENT_REC_REMOVED_BI 38 /* Free record and dependecies: includes before image of record, for freeing index, etc. */ |
|
144 |
#define XT_LOG_ENT_REC_REMOVED_BI_L 40 /* Free record and dependecies: as above, but link the record into the free list. */ |
|
145 |
||
146 |
#define XT_LOG_ENT_REC_MOVED 24 /* The record has been moved by the compactor. */ |
|
147 |
#define XT_LOG_ENT_REC_CLEANED 25 /* This record has been cleaned by the sweeper. */ |
|
148 |
#define XT_LOG_ENT_REC_CLEANED_1 26 /* This record has been cleaned by the sweeper (short form). */ |
|
149 |
#define XT_LOG_ENT_REC_UNLINKED 27 /* The record after this record is unlinked from the variation list. */ |
|
150 |
||
151 |
#define XT_LOG_ENT_ROW_NEW 28 /* Row allocated from the EOF. */ |
|
152 |
#define XT_LOG_ENT_ROW_NEW_FL 29 /* Row allocated from the free list. */ |
|
153 |
#define XT_LOG_ENT_ROW_ADD_REC 30 /* Record added to the row. */ |
|
154 |
#define XT_LOG_ENT_ROW_SET 31
|
|
155 |
#define XT_LOG_ENT_ROW_FREED 32
|
|
156 |
||
157 |
#define XT_LOG_ENT_OP_SYNC 33 /* Operations syncronised. */ |
|
158 |
#define XT_LOG_ENT_EXT_REC_OK 34 /* An extended record */ |
|
159 |
#define XT_LOG_ENT_EXT_REC_DEL 35 /* A deleted extended record */ |
|
160 |
||
161 |
#define XT_LOG_ENT_NO_OP 36 /* If write to the database fails, we still try to log the |
|
162 |
* op code, in an attempt to continue, if writting to log
|
|
163 |
* still works.
|
|
164 |
*/
|
|
165 |
#define XT_LOG_ENT_END_OF_LOG 37 /* This is a record that indicates the end of the log, and |
|
166 |
* fills to the end of a 512 byte block.
|
|
167 |
*/
|
|
168 |
#define XT_LOG_ENT_PREPARE 39 /* XA prepare log entry. */ |
|
169 |
||
170 |
#define XT_LOG_FILE_MAGIC 0xAE88FE12
|
|
171 |
#define XT_LOG_VERSION_NO 1
|
|
172 |
||
173 |
typedef struct XTXactLogHeader { |
|
174 |
xtWord1 xh_status_1; /* XT_LOG_ENT_HEADER */ |
|
175 |
xtWord1 xh_checksum_1; |
|
176 |
XTDiskValue4 xh_size_4; /* Must be set to sizeof(XTXactLogHeaderDRec). */ |
|
177 |
XTDiskValue8 xh_free_space_8; /* The accumulated free space in this file. */ |
|
178 |
XTDiskValue8 xh_file_len_8; /* The last confirmed correct file length (always set on close). */ |
|
179 |
XTDiskValue8 xh_comp_pos_8; /* Compaction position (XT_DL_STATUS_CO_SOURCE only). */ |
|
180 |
xtWord1 xh_comp_stat_1; /* The compaction status XT_DL_STATUS_CO_SOURCE/XT_DL_STATUS_CO_TARGET */ |
|
181 |
XTDiskValue4 xh_log_id_4; |
|
182 |
XTDiskValue2 xh_version_2; /* XT_LOG_VERSION_NO */ |
|
183 |
XTDiskValue2 xh_unused_2; /* Set to zero (added because xh_version_2 was XTDiskValue4), but treated as 2 */ |
|
184 |
XTDiskValue4 xh_magic_4; /* MUST always be at the end of the structure!! */ |
|
185 |
} XTXactLogHeaderDRec, *XTXactLogHeaderDPtr; |
|
186 |
||
187 |
/* This is the original log head size (don't change): */
|
|
188 |
#define XT_MIN_LOG_HEAD_SIZE (offsetof(XTXactLogHeaderDRec, xh_log_id_4) + 4)
|
|
189 |
#define XT_LOG_HEAD_MAGIC(b, l) XT_GET_DISK_4(((xtWord1 *) (b)) + (l) - 4)
|
|
190 |
||
191 |
typedef struct XTXactNewLogEntry { |
|
192 |
xtWord1 xl_status_1; /* XT_LOG_ENT_NEW_LOG, XT_LOG_ENT_DEL_LOG */ |
|
193 |
xtWord1 xl_checksum_1; |
|
194 |
XTDiskValue4 xl_log_id_4; /* Store the current table ID. */ |
|
195 |
} XTXactNewLogEntryDRec, *XTXactNewLogEntryDPtr; |
|
196 |
||
197 |
typedef struct XTXactNewTabEntry { |
|
198 |
xtWord1 xt_status_1; /* XT_LOG_ENT_NEW_TAB */ |
|
199 |
xtWord1 xt_checksum_1; |
|
200 |
XTDiskValue4 xt_tab_id_4; /* Store the current table ID. */ |
|
201 |
} XTXactNewTabEntryDRec, *XTXactNewTabEntryDPtr; |
|
202 |
||
203 |
/* This record must appear in a transaction group, and therefore has no transaction ID: */
|
|
204 |
typedef struct XTXactEndEntry { |
|
205 |
xtWord1 xe_status_1; /* XT_LOG_ENT_COMMIT, XT_LOG_ENT_ABORT */ |
|
206 |
xtWord1 xe_checksum_1; |
|
207 |
XTDiskValue4 xe_xact_id_4; /* The transaction. */ |
|
208 |
XTDiskValue4 xe_not_used_4; /* Was the end sequence number (no longer used - v1.0.04+), set to zero). */ |
|
209 |
} XTXactEndEntryDRec, *XTXactEndEntryDPtr; |
|
210 |
||
211 |
typedef struct XTXactPrepareEntry { |
|
212 |
xtWord1 xp_status_1; /* XT_LOG_ENT_PREPARE */ |
|
213 |
XTDiskValue2 xp_checksum_2; |
|
214 |
XTDiskValue4 xp_xact_id_4; /* The transaction. */ |
|
215 |
xtWord1 xp_xa_len_1; /* The length of the XA data. */ |
|
216 |
xtWord1 xp_xa_data[XT_MAX_XA_DATA_SIZE]; |
|
217 |
} XTXactPrepareEntryDRec, *XTXactPrepareEntryDPtr; |
|
218 |
||
219 |
typedef struct XTXactCleanupEntry { |
|
220 |
xtWord1 xc_status_1; /* XT_LOG_ENT_CLEANUP */ |
|
221 |
xtWord1 xc_checksum_1; |
|
222 |
XTDiskValue4 xc_xact_id_4; /* The transaction that was cleaned up. */ |
|
223 |
} XTXactCleanupEntryDRec, *XTXactCleanupEntryDPtr; |
|
224 |
||
225 |
typedef struct XTactUpdateEntry { |
|
226 |
xtWord1 xu_status_1; /* XT_LOG_ENT_REC_MODIFIED, XT_LOG_ENT_UPDATE, XT_LOG_ENT_INSERT, XT_LOG_ENT_DELETE */ |
|
227 |
/* XT_LOG_ENT_UPDATE_BG, XT_LOG_ENT_INSERT_BG, XT_LOG_ENT_DELETE_BG */
|
|
228 |
XTDiskValue2 xu_checksum_2; |
|
229 |
XTDiskValue4 xu_op_seq_4; /* Operation sequence number. */ |
|
230 |
XTDiskValue4 xu_tab_id_4; /* Table ID of the record. */ |
|
231 |
xtDiskRecordID4 xu_rec_id_4; /* Offset of the new updated record. */ |
|
232 |
XTDiskValue2 xu_size_2; /* Size of the record data. */ |
|
233 |
/* This is the start of the actual record data: */
|
|
234 |
xtWord1 xu_rec_type_1; /* Type of the record. */ |
|
235 |
xtWord1 xu_stat_id_1; |
|
236 |
xtDiskRecordID4 xu_prev_rec_id_4; /* The previous variation of this record. */ |
|
237 |
XTDiskValue4 xu_xact_id_4; /* The transaction ID. */ |
|
238 |
XTDiskValue4 xu_row_id_4; /* The row ID of this record. */ |
|
239 |
} XTactUpdateEntryDRec, *XTactUpdateEntryDPtr; |
|
240 |
||
241 |
typedef struct XTactUpdateFLEntry { |
|
242 |
xtWord1 xf_status_1; /* XT_LOG_ENT_UPDATE_FL, XT_LOG_ENT_INSERT_FL, XT_LOG_ENT_DELETE_FL */ |
|
243 |
/* XT_LOG_ENT_UPDATE_FL_BG, XT_LOG_ENT_INSERT_FL_BG, XT_LOG_ENT_DELETE_FL_BG */
|
|
244 |
XTDiskValue2 xf_checksum_2; |
|
245 |
XTDiskValue4 xf_op_seq_4; /* Operation sequence number. */ |
|
246 |
XTDiskValue4 xf_tab_id_4; /* Table ID of the record. */ |
|
247 |
xtDiskRecordID4 xf_rec_id_4; /* Offset of the new updated record. */ |
|
248 |
XTDiskValue2 xf_size_2; /* Size of the record data. */ |
|
249 |
xtDiskRecordID4 xf_free_rec_id_4; /* Update to the free list. */ |
|
250 |
/* This is the start of the actual record data: */
|
|
251 |
xtWord1 xf_rec_type_1; /* Type of the record. */ |
|
252 |
xtWord1 xf_stat_id_1; |
|
253 |
xtDiskRecordID4 xf_prev_rec_id_4; /* The previous variation of this record. */ |
|
254 |
XTDiskValue4 xf_xact_id_4; /* The transaction ID. */ |
|
255 |
XTDiskValue4 xf_row_id_4; /* The row ID of this record. */ |
|
256 |
} XTactUpdateFLEntryDRec, *XTactUpdateFLEntryDPtr; |
|
257 |
||
258 |
typedef struct XTactFreeRecEntry { |
|
259 |
xtWord1 fr_status_1; /* XT_DEFUNKT_REC_REMOVED, XT_DEFUNKT_REC_REMOVED_EXT, XT_DEFUNKT_REC_FREED */ |
|
260 |
xtWord1 fr_checksum_1; |
|
261 |
XTDiskValue4 fr_op_seq_4; /* Operation sequence number. */ |
|
262 |
XTDiskValue4 fr_tab_id_4; /* Table ID of the record. */ |
|
263 |
xtDiskRecordID4 fr_rec_id_4; /* Offset of the new written record. */ |
|
264 |
/* This data confirms the record state for release of
|
|
265 |
* attached resources (extended records, indexes and blobs)
|
|
266 |
*/
|
|
267 |
xtWord1 fr_stat_id_1; /* The statement ID of the record. */ |
|
268 |
XTDiskValue4 fr_xact_id_4; /* The transaction ID of the record. */ |
|
269 |
/* This is the start of the actual record data: */
|
|
270 |
xtWord1 fr_rec_type_1; |
|
271 |
xtWord1 fr_not_used_1; |
|
272 |
xtDiskRecordID4 fr_next_rec_id_4; /* The next block on the free list. */ |
|
273 |
} XTactFreeRecEntryDRec, *XTactFreeRecEntryDPtr; |
|
274 |
||
275 |
typedef struct XTactRemoveBIEntry { |
|
276 |
xtWord1 rb_status_1; /* XT_LOG_ENT_REC_REMOVED_BI */ |
|
277 |
XTDiskValue2 rb_checksum_2; |
|
278 |
XTDiskValue4 rb_op_seq_4; /* Operation sequence number. */ |
|
279 |
XTDiskValue4 rb_tab_id_4; /* Table ID of the record. */ |
|
280 |
xtDiskRecordID4 rb_rec_id_4; /* Offset of the new written record. */ |
|
281 |
XTDiskValue2 rb_size_2; /* Size of the record data. */ |
|
282 |
||
283 |
xtWord1 rb_new_rec_type_1; /* New type of the record (needed for below). */ |
|
284 |
||
285 |
/* This is the start of the record data, with some fields overwritten for the free: */
|
|
286 |
xtWord1 rb_rec_type_1; /* Type of the record. */ |
|
287 |
xtWord1 rb_stat_id_1; |
|
288 |
xtDiskRecordID4 rb_next_rec_id_4; /* The next block on the free list (overwritten). */ |
|
289 |
XTDiskValue4 rb_xact_id_4; /* The transaction ID. */ |
|
290 |
XTDiskValue4 rb_row_id_4; /* The row ID of this record. */ |
|
291 |
} XTactRemoveBIEntryDRec, *XTactRemoveBIEntryDPtr; |
|
292 |
||
293 |
typedef struct XTactRemoveBILEntry { |
|
294 |
xtWord1 bl_status_1; /* XT_LOG_ENT_REC_REMOVED_BI_L */ |
|
295 |
XTDiskValue2 bl_checksum_2; |
|
296 |
XTDiskValue4 bl_op_seq_4; /* Operation sequence number. */ |
|
297 |
XTDiskValue4 bl_tab_id_4; /* Table ID of the record. */ |
|
298 |
xtDiskRecordID4 bl_rec_id_4; /* Offset of the new written record. */ |
|
299 |
XTDiskValue2 bl_size_2; /* Size of the record data. */ |
|
300 |
||
301 |
xtWord1 bl_new_rec_type_1; /* New type of the record (needed for below). */ |
|
302 |
xtDiskRecordID4 bl_prev_rec_id_4; /* Offset of the new written record. */ |
|
303 |
||
304 |
/* This is the start of the record data, with some fields overwritten for the free: */
|
|
305 |
xtWord1 bl_rec_type_1; /* Type of the record. */ |
|
306 |
xtWord1 bl_stat_id_1; |
|
307 |
xtDiskRecordID4 bl_next_rec_id_4; /* The next block on the free list (overwritten). */ |
|
308 |
XTDiskValue4 bl_xact_id_4; /* The transaction ID. */ |
|
309 |
XTDiskValue4 bl_row_id_4; /* The row ID of this record. */ |
|
310 |
} XTactRemoveBILEntryDRec, *XTactRemoveBILEntryDPtr; |
|
311 |
||
312 |
typedef struct XTactWriteRecEntry { |
|
313 |
xtWord1 xw_status_1; /* XT_LOG_ENT_REC_MOVED, XT_LOG_ENT_REC_CLEANED, XT_LOG_ENT_REC_CLEANED_1, |
|
314 |
* XT_LOG_ENT_REC_UNLINKED */
|
|
315 |
xtWord1 xw_checksum_1; |
|
316 |
XTDiskValue4 xw_op_seq_4; /* Operation sequence number. */ |
|
317 |
XTDiskValue4 xw_tab_id_4; /* Table ID of the record. */ |
|
318 |
xtDiskRecordID4 xw_rec_id_4; /* Offset of the new written record. */ |
|
319 |
/* This is the start of the actual record data: */
|
|
320 |
xtWord1 xw_rec_type_1; |
|
321 |
xtWord1 xw_stat_id_1; |
|
322 |
xtDiskRecordID4 xw_next_rec_id_4; /* The next block on the free list. */ |
|
323 |
} XTactWriteRecEntryDRec, *XTactWriteRecEntryDPtr; |
|
324 |
||
325 |
typedef struct XTactRowAddedEntry { |
|
326 |
xtWord1 xa_status_1; /* XT_LOG_ENT_ROW_NEW or XT_LOG_ENT_ROW_NEW_FL */ |
|
327 |
xtWord1 xa_checksum_1; |
|
328 |
XTDiskValue4 xa_op_seq_4; /* Operation sequence number. */ |
|
329 |
XTDiskValue4 xa_tab_id_4; /* Table ID of the record. */ |
|
330 |
XTDiskValue4 xa_row_id_4; /* The row ID of the row allocated. */ |
|
331 |
XTDiskValue4 xa_free_list_4; /* Change to the free list (ONLY for XT_LOG_ENT_ROW_NEW_FL). */ |
|
332 |
} XTactRowAddedEntryDRec, *XTactRowAddedEntryDPtr; |
|
333 |
||
334 |
typedef struct XTactWriteRowEntry { |
|
335 |
xtWord1 wr_status_1; /* XT_LOG_ENT_ROW_ADD_REC, XT_LOG_ENT_ROW_SET, XT_LOG_ENT_ROW_FREED */ |
|
336 |
xtWord1 wr_checksum_1; |
|
337 |
XTDiskValue4 wr_op_seq_4; /* Operation sequence number. */ |
|
338 |
XTDiskValue4 wr_tab_id_4; /* Table ID of the record. */ |
|
339 |
XTDiskValue4 wr_row_id_4; /* Row ID of the row that was modified. */ |
|
340 |
/* This is the start of the actual record data: */
|
|
341 |
XTDiskValue4 wr_ref_id_4; /* The row reference data. */ |
|
342 |
} XTactWriteRowEntryDRec, *XTactWriteRowEntryDPtr; |
|
343 |
||
344 |
typedef struct XTactOpSyncEntry { |
|
345 |
xtWord1 os_status_1; /* XT_LOG_ENT_OP_SYNC */ |
|
346 |
xtWord1 os_checksum_1; |
|
347 |
XTDiskValue4 os_time_4; /* Time of the restart. */ |
|
348 |
} XTactOpSyncEntryDRec, *XTactOpSyncEntryDPtr; |
|
349 |
||
350 |
typedef struct XTactNoOpEntry { |
|
351 |
xtWord1 no_status_1; /* XT_LOG_ENT_NO_OP */ |
|
352 |
xtWord1 no_checksum_1; |
|
353 |
XTDiskValue4 no_op_seq_4; /* Operation sequence number. */ |
|
354 |
XTDiskValue4 no_tab_id_4; /* Table ID of the record. */ |
|
355 |
} XTactNoOpEntryDRec, *XTactNoOpEntryDPtr; |
|
356 |
||
357 |
typedef struct XTactExtRecEntry { |
|
358 |
xtWord1 er_status_1; /* XT_LOG_ENT_EXT_REC_OK, XT_LOG_ENT_EXT_REC_DEL */ |
|
359 |
XTDiskValue4 er_data_size_4; /* Size of this record data area only. */ |
|
360 |
XTDiskValue4 er_tab_id_4; /* The table referencing this extended record. */ |
|
361 |
xtDiskRecordID4 er_rec_id_4; /* The ID of the reference record. */ |
|
362 |
xtWord1 er_data[XT_VAR_LENGTH]; |
|
363 |
} XTactExtRecEntryDRec, *XTactExtRecEntryDPtr; |
|
364 |
||
365 |
typedef union XTXactLogBuffer { |
|
366 |
XTXactLogHeaderDRec xh; |
|
367 |
XTXactNewLogEntryDRec xl; |
|
368 |
XTXactNewTabEntryDRec xt; |
|
369 |
XTXactEndEntryDRec xe; |
|
370 |
XTXactCleanupEntryDRec xc; |
|
371 |
XTactUpdateEntryDRec xu; |
|
372 |
XTactUpdateFLEntryDRec xf; |
|
373 |
XTactFreeRecEntryDRec fr; |
|
374 |
XTactRemoveBIEntryDRec rb; |
|
375 |
XTactRemoveBILEntryDRec bl; |
|
376 |
XTactWriteRecEntryDRec xw; |
|
377 |
XTactRowAddedEntryDRec xa; |
|
378 |
XTactWriteRowEntryDRec wr; |
|
379 |
XTactOpSyncEntryDRec os; |
|
380 |
XTactExtRecEntryDRec er; |
|
381 |
XTactNoOpEntryDRec no; |
|
382 |
XTXactPrepareEntryDRec xp; |
|
383 |
} XTXactLogBufferDRec, *XTXactLogBufferDPtr; |
|
384 |
||
385 |
/* ---------------------------------------- */
|
|
386 |
||
387 |
typedef struct XTXactSeqRead { |
|
388 |
size_t xseq_buffer_size; /* Size of the buffer. */ |
|
389 |
xtBool xseq_load_cache; /* TRUE if reads should load the cache! */ |
|
390 |
||
391 |
xtLogID xseq_log_id; |
|
392 |
XTOpenFilePtr xseq_log_file; |
|
393 |
off_t xseq_log_eof; |
|
394 |
||
395 |
xtLogOffset xseq_buf_log_offset; /* File offset of the buffer. */ |
|
396 |
size_t xseq_buffer_len; /* Amount of data in the buffer. */ |
|
397 |
xtWord1 *xseq_buffer; |
|
398 |
||
399 |
xtLogID xseq_rec_log_id; /* The current record log ID. */ |
|
400 |
xtLogOffset xseq_rec_log_offset; /* The current log read position. */ |
|
401 |
size_t xseq_record_len; /* The length of the current record. */ |
|
402 |
} XTXactSeqReadRec, *XTXactSeqReadPtr; |
|
403 |
||
404 |
typedef struct XTXactLogFile { |
|
405 |
xtLogID lf_log_id; |
|
406 |
off_t lr_file_len; /* The log file size (0 means this is the last log) */ |
|
407 |
} XTXactLogFileRec, *XTXactLogFilePtr; |
|
408 |
||
409 |
/*
|
|
410 |
* The transaction log. Each database has one.
|
|
411 |
*/
|
|
412 |
||
413 |
/* Does not seem to make much difference... */
|
|
414 |
#ifndef XT_NO_ATOMICS
|
|
415 |
/* This function uses atomic ops: */
|
|
416 |
//#define XT_XLOG_WAIT_SPINS
|
|
417 |
#endif
|
|
418 |
||
419 |
typedef struct XTDatabaseLog { |
|
420 |
struct XTDatabase *xl_db; |
|
421 |
||
422 |
off_t xl_log_file_threshold; |
|
423 |
u_int xl_log_file_count; /* Number of logs to use (>= 1). */ |
|
424 |
u_int xt_log_file_dyn_count; /* A dynamic value to add to log file count. */ |
|
425 |
u_int xt_log_file_dyn_dec; /* Used to descide when to decrement the dynamic count. */ |
|
426 |
size_t xl_size_of_buffers; /* The size of both log buffers. */ |
|
427 |
xtWord8 xl_log_bytes_written; /* The total number of bytes written to the log, after recovery. */ |
|
428 |
xtWord8 xl_log_bytes_flushed; /* The total number of bytes flushed to the log, after recovery. */ |
|
429 |
xtWord8 xl_log_bytes_read; /* The total number of log bytes read, after recovery. */ |
|
430 |
||
431 |
u_int xl_last_flush_time; /* Last flush time in micro-seconds. */ |
|
432 |
||
433 |
/* The writer log buffer: */
|
|
434 |
xt_mutex_type xl_write_lock; |
|
435 |
xt_cond_type xl_write_cond; |
|
436 |
#ifdef XT_XLOG_WAIT_SPINS
|
|
437 |
xtWord4 xt_writing; /* 1 if a thread is writing. */ |
|
438 |
xtWord4 xt_waiting; /* Count of the threads waiting on the xl_write_cond. */ |
|
439 |
#else
|
|
440 |
xtBool xt_writing; /* TRUE if a thread is writing. */ |
|
441 |
#endif
|
|
442 |
xtLogID xl_log_id; /* The number of the write log. */ |
|
443 |
XTOpenFilePtr xl_log_file; /* The open write log. */ |
|
444 |
||
445 |
XTSpinLockRec xl_buffer_lock; /* This locks both the write and the append log buffers. */ |
|
446 |
||
447 |
xtLogID xl_max_log_id; /* The ID of the highest log on disk. */ |
|
448 |
||
449 |
xtLogID xl_write_log_id; /* This is the log ID were the write data will go. */ |
|
450 |
xtLogOffset xl_write_log_offset; /* The file offset of the write log. */ |
|
451 |
size_t xl_write_buf_pos; |
|
452 |
size_t xl_write_buf_pos_start; |
|
453 |
xtWord1 *xl_write_buffer; |
|
454 |
xtBool xl_write_done; /* TRUE if the write buffer has been written! */ |
|
455 |
||
456 |
xtLogID xl_append_log_id; /* This is the log ID were the append data will go. */ |
|
457 |
xtLogOffset xl_append_log_offset; /* The file offset in the log were the append data will go. */ |
|
458 |
size_t xl_append_buf_pos; /* The amount of data in the append buffer. */ |
|
459 |
size_t xl_append_buf_pos_start; /* The amount of data in the append buffer already written. */ |
|
460 |
xtWord1 *xl_append_buffer; |
|
461 |
||
462 |
xtLogID xl_flush_log_id; /* The last log flushed. */ |
|
463 |
xtLogOffset xl_flush_log_offset; /* The position in the log flushed. */ |
|
464 |
||
465 |
void xlog_setup(struct XTThread *self, struct XTDatabase *db, off_t log_file_size, size_t transaction_buffer_size, int log_count); |
|
466 |
xtBool xlog_set_write_offset(xtLogID log_id, xtLogOffset log_offset, xtLogID max_log_id, struct XTThread *thread); |
|
467 |
void xlog_close(struct XTThread *self); |
|
468 |
void xlog_exit(struct XTThread *self); |
|
469 |
void xlog_name(size_t size, char *path, xtLogID log_id); |
|
470 |
int xlog_delete_log(xtLogID del_log_id, struct XTThread *thread); |
|
471 |
||
472 |
xtBool xlog_append(struct XTThread *thread, size_t size1, xtWord1 *data1, size_t size2, xtWord1 *data2, int flush_log_at_trx_commit, xtLogID *log_id, xtLogOffset *log_offset); |
|
473 |
xtBool xlog_flush(struct XTThread *thread); |
|
474 |
xtBool xlog_flush_pending(); |
|
475 |
||
476 |
xtBool xlog_seq_init(XTXactSeqReadPtr seq, size_t buffer_size, xtBool load_cache); |
|
477 |
void xlog_seq_exit(XTXactSeqReadPtr seq); |
|
478 |
void xlog_seq_close(XTXactSeqReadPtr seq); |
|
479 |
xtBool xlog_seq_start(XTXactSeqReadPtr seq, xtLogID log_id, xtLogOffset log_offset, xtBool missing_ok); |
|
480 |
xtBool xlog_rnd_read(XTXactSeqReadPtr seq, xtLogID log_id, xtLogOffset log_offset, size_t size, xtWord1 *data, size_t *read, struct XTThread *thread); |
|
481 |
size_t xlog_bytes_to_write(); |
|
482 |
xtBool xlog_read_from_cache(XTXactSeqReadPtr seq, xtLogID log_id, xtLogOffset log_offset, size_t size, off_t eof, xtWord1 *buffer, size_t *data_read, struct XTThread *thread); |
|
483 |
xtBool xlog_write_thru(XTXactSeqReadPtr seq, size_t size, xtWord1 *data, struct XTThread *thread); |
|
484 |
xtBool xlog_verify(XTXactLogBufferDPtr record, size_t rec_size, xtLogID log_id); |
|
485 |
xtBool xlog_seq_next(XTXactSeqReadPtr seq, XTXactLogBufferDPtr *entry, xtBool verify, struct XTThread *thread); |
|
486 |
void xlog_seq_skip(XTXactSeqReadPtr seq, size_t size); |
|
487 |
||
488 |
private: |
|
489 |
xtBool xlog_open_log(xtLogID log_id, off_t curr_eof, struct XTThread *thread); |
|
490 |
} XTDatabaseLogRec, *XTDatabaseLogPtr; |
|
491 |
||
492 |
xtBool xt_xlog_flush_log(struct XTDatabase *db, struct XTThread *thread); |
|
493 |
xtBool xt_xlog_log_data(struct XTThread *thread, size_t len, XTXactLogBufferDPtr log_entry, int flush_log_at_trx_commit); |
|
494 |
xtBool xt_xlog_modify_table(xtTableID tab_id, u_int status, xtOpSeqNo op_seq, xtWord1 new_rec_type, xtRecordID free_rec_id, xtRecordID address, size_t size, xtWord1 *data, struct XTThread *thread); |
|
495 |
||
496 |
void xt_xlog_init(struct XTThread *self, size_t cache_size); |
|
497 |
void xt_xlog_exit(struct XTThread *self); |
|
498 |
xtInt8 xt_xlog_get_usage(); |
|
499 |
xtInt8 xt_xlog_get_size(); |
|
500 |
xtLogID xt_xlog_get_min_log(struct XTThread *self, struct XTDatabase *db); |
|
501 |
void xt_xlog_delete_logs(struct XTThread *self, struct XTDatabase *db); |
|
502 |
||
503 |
void xt_start_writer(struct XTThread *self, struct XTDatabase *db); |
|
504 |
void xt_wait_for_writer(struct XTThread *self, struct XTDatabase *db); |
|
505 |
void xt_stop_writer(struct XTThread *self, struct XTDatabase *db); |
|
506 |
||
507 |
#endif
|
|
508 |