~drizzle-trunk/drizzle/development

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