1
/* Copyright (c) 2007 PrimeBase Technologies GmbH
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* 2007-10-31 Paul McCullagh
23
* The new table cache. Caches all non-index data. This includes the data
24
* files and the row pointer files.
27
#ifndef __xactlog_xt_h__
28
#define __xactlog_xt_h__
30
#include "pthread_xt.h"
31
#include "filesys_xt.h"
32
#include "sortedlist_xt.h"
39
//#define XT_USE_CACHE_DEBUG_SIZES
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
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
58
#define XT_XLC_BLOCK_SIZE (1 << XT_XLC_BLOCK_SHIFTS)
59
#define XT_XLC_BLOCK_MASK (XT_XLC_BLOCK_SIZE - 1)
61
#define XT_TIME_DIFF(start, now) (\
62
((xtWord4) (now) < (xtWord4) (start)) ? \
63
((xtWord4) 0XFFFFFFFF - ((xtWord4) (start) - (xtWord4) (now))) : \
64
((xtWord4) (now) - (xtWord4) (start)))
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)
70
#define XLC_BLOCK_FREE 0
71
#define XLC_BLOCK_READING 1
72
#define XLC_BLOCK_CLEAN 2
74
#define XT_RECYCLE_LOGS 0
75
#define XT_DELETE_LOGS 1
76
#define XT_KEEP_LOGS 2
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
82
/* LOG CACHE ---------------------------------------------------- */
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;
92
/* A disk cache segment. The cache is divided into a number of segments
93
* to improve concurrency.
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;
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;
114
/* LOG ENTRIES ---------------------------------------------------- */
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. */
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. */
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
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. */
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. */
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
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 */
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
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.
168
#define XT_LOG_ENT_PREPARE 39 /* XA prepare log entry. */
170
#define XT_LOG_FILE_MAGIC 0xAE88FE12
171
#define XT_LOG_VERSION_NO 1
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;
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)
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;
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;
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;
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;
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;
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;
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;
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)
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;
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. */
283
xtWord1 rb_new_rec_type_1; /* New type of the record (needed for below). */
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;
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. */
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. */
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;
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;
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;
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;
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;
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;
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;
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;
385
/* ---------------------------------------- */
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! */
392
XTOpenFilePtr xseq_log_file;
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;
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;
404
typedef struct XTXactLogFile {
406
off_t lr_file_len; /* The log file size (0 means this is the last log) */
407
} XTXactLogFileRec, *XTXactLogFilePtr;
410
* The transaction log. Each database has one.
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
419
typedef struct XTDatabaseLog {
420
struct XTDatabase *xl_db;
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. */
431
u_int xl_last_flush_time; /* Last flush time in micro-seconds. */
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. */
440
xtBool xt_writing; /* TRUE if a thread is writing. */
442
xtLogID xl_log_id; /* The number of the write log. */
443
XTOpenFilePtr xl_log_file; /* The open write log. */
445
XTSpinLockRec xl_buffer_lock; /* This locks both the write and the append log buffers. */
447
xtLogID xl_max_log_id; /* The ID of the highest log on disk. */
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! */
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;
462
xtLogID xl_flush_log_id; /* The last log flushed. */
463
xtLogOffset xl_flush_log_offset; /* The position in the log flushed. */
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);
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();
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);
489
xtBool xlog_open_log(xtLogID log_id, off_t curr_eof, struct XTThread *thread);
490
} XTDatabaseLogRec, *XTDatabaseLogPtr;
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);
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);
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);