1
/* Copyright (c) 2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
* Author: Paul McCullagh
27
#include "win_inttypes.h"
31
#include <sys/types.h>
36
//#include "pthread_xt.h"
39
//#define DEBUG_LOG_DELETE
42
/* the following macros are used to quote compile-time numeric
43
* constants into strings, e.g. __LINE__
46
#define QUOTE(x) _QUOTE(x)
48
/* ----------------------------------------------------------------------
52
/* Define this if crash debug should be on by default:
53
* pbxt_crash_debug set to TRUE by default.
54
* It can be turned off by creating a file called 'no-debug'
55
* in the pbxt database.
56
* It can be turned on by defining the file 'crash-debug'
57
* in the pbxt database.
59
//#define XT_CRASH_DEBUG
61
/* These are the things crash debug will do: */
62
/* Create a core dump (windows only): */
65
/* Backup the datadir before recovery after a crash: */
66
//#define XT_BACKUP_BEFORE_RECOVERY
68
/* Keep this number of transaction logs around
69
* for analysis after a crash.
71
#define XT_NUMBER_OF_LOGS_TO_SAVE 5
73
/* ----------------------------------------------------------------------
74
* GENERIC GLOBAL TYPES
80
#define xtInt2 __int16
81
#define xtInt4 __int32
82
#define xtInt8 __int64
84
#define xtWord1 unsigned __int8
85
#define xtWord2 unsigned __int16
86
#define xtWord4 unsigned __int32
87
#define xtWord8 unsigned __int64
90
#define PATH_MAX MAX_PATH
93
#define NAME_MAX MAX_PATH
96
/* XT actually assumes that off_t is 8 bytes: */
101
#define xtInt1 int8_t
102
#define xtInt2 int16_t
103
#define xtInt4 int32_t
104
#define xtInt8 int64_t
107
#define u_int8_t uint8_t
108
#define u_int16_t uint16_t
109
#define u_int32_t uint32_t
110
#define u_int64_t uint64_t
113
#define xtWord1 u_int8_t
114
#define xtWord2 u_int16_t
115
#define xtWord4 u_int32_t
116
#define xtWord8 u_int64_t
120
/* A pointer sized word value: */
121
#define xtWordPS ptrdiff_t
123
#define XT_MAX_INT_1 ((xtInt1) 0x7F)
124
#define XT_MIN_INT_1 ((xtInt1) 0x80)
125
#define XT_MAX_INT_2 ((xtInt2) 0x7FFF)
126
#define XT_MIN_INT_2 ((xtInt2) 0x8000)
127
#define XT_MAX_INT_4 ((xtInt4) 0x7FFFFFFF)
128
#define XT_MIN_INT_4 ((xtInt4) 0x80000000)
130
#define xtReal4 float
131
#define xtReal8 double
134
#define u_int unsigned int /* Assumed at least 4 bytes long! */
135
#define u_long unsigned long /* Assumed at least 4 bytes long! */
137
#define llong long long /* Assumed at least 8 bytes long! */
138
#define u_llong unsigned long long /* Assumed at least 8 bytes long! */
140
#define c_char const char
149
#define xtBool1 xtWord1 /* A boolean that saves space in structures. */
157
/* Additional return codes: */
174
typedef xtWord1 XTDiskValue1[1];
175
typedef xtWord1 XTDiskValue2[2];
176
typedef xtWord1 XTDiskValue3[3];
177
typedef xtWord1 XTDiskValue4[4];
178
typedef xtWord1 XTDiskValue6[6];
179
typedef xtWord1 XTDiskValue8[8];
182
#define XT_VAR_LENGTH 100
184
#define XT_VAR_LENGTH 1
187
typedef struct XTPathStr {
188
char ps_path[XT_VAR_LENGTH];
191
//#define XT_UNUSED(x) x __attribute__((__unused__))
194
/* Only used when DEBUG is on: */
196
#define XT_NDEBUG_UNUSED(x) x
198
//#define XT_NDEBUG_UNUSED(x) x __attribute__((__unused__))
199
#define XT_NDEBUG_UNUSED(x)
202
/* ----------------------------------------------------------------------
207
* Define if there should only be one database per server instance:
209
#define XT_USE_GLOBAL_DB
212
* The rollover size is the write limit of a log file.
213
* After this size is reached, a thread will start a
216
* However, logs can grow much larger than this size.
217
* The reason is, a transaction single transaction
218
* may not span more than one data log file.
220
* This means the log rollover size is actually a
225
#define XT_USE_GLOBAL_DEBUG_SIZES
229
* I believe the MySQL limit is 16. This limit is currently only used for
232
#define XT_MAX_COLS_PER_INDEX 32
235
* The maximum number of tables that can be created in a PBXT
236
* database. The amount is based on the fact that XT creates
237
* about 5 files per table in the database, and also
238
* uses directory listing to find tables.
240
#define XT_MAX_TABLES 10000
243
* When the amount of garbage in the file is greater than the
244
* garbage threshold, then compactor is activated.
246
#define XT_GARBAGE_THRESHOLD ((double) 50.0)
248
/* A record that does not contain blobs will be handled as a fixed
249
* length record if its maximum size is less than this amount,
250
* regardless of the size of the VARCHAR fields it contains.
252
#define XT_TAB_MIN_VAR_REC_LENGTH 320
254
/* No record in the data handle file may exceed this size: */
255
#define XT_TAB_MAX_FIX_REC_LENGTH (16 * 1024)
257
/* No record in the data handle file may exceed this size, if
258
* AVG_ROW_LENGTH is set.
260
#define XT_TAB_MAX_FIX_REC_LENGTH_SPEC (64 * 1024)
263
* Determines the page size of the indexes. The value is given
264
* in shifts of 1 to the left (e.g. 1 << 11 == 2048,
267
* PMC: Note the performance of sysbench is better with 11
270
* InnoDB uses 16K pages:
273
#define XT_INDEX_PAGE_SHIFTS 14
275
/* The number of RW locks used to scatter locks on the rows
276
* of a table. The locks are only help for a short time during which
277
* the row list is scanned.
279
* For more details see [(9)].
282
#define XT_ROW_RWLOCKS 1019
283
//#define XT_ROW_RWLOCKS 223
286
* These are the number of row lock "slots" per table.
287
* Row locks are taken on UPDATE/DELETE or SELECT FOR UPDATE.
289
#define XT_ROW_LOCK_COUNT (XT_ROW_RWLOCKS * 91)
292
* The size of index write buffer. Must be at least as large as the
293
* largest index page, plus overhead.
295
#define XT_INDEX_WRITE_BUFFER_SIZE (1024 * 1024)
297
/* This is the time in seconds that a open table in the open
298
* table pool must be on the free list before it
299
* is actually freed from the pool.
301
* This is to reduce the affect from MySQL with a very low
302
* table cache size, which causes tables to be openned and
303
* closed very rapidly.
305
#define XT_OPEN_TABLE_FREE_TIME 30
307
/* Define this in order to use memory mapped files
308
* (record and row pointer files only).
310
* This makes no difference in sysbench R/W performance
313
//#define XT_USE_ROW_REC_MMAP_FILES
315
/* Define this if sequential scan should load data into the
318
* This is the way InnoDB behaves.
320
#define XT_SEQ_SCAN_LOADS_CACHE
322
/* Define this in order to use memory mapped files (XT_FT_STANDARD): */
323
//#define XT_USE_DEFAULT_MEMORY_TABS
325
/* Define the default file type used by disk tables: */
326
#ifdef XT_USE_ROW_REC_MMAP_FILES
327
#define XT_REC_FILE_TYPE XT_FT_MEM_MAP
328
#define XT_ROW_FILE_TYPE XT_FT_MEM_MAP
330
#define XT_REC_FILE_TYPE XT_FT_STANDARD
331
#define XT_ROW_FILE_TYPE XT_FT_STANDARD
333
#define XT_IND_FILE_TYPE XT_FT_STANDARD
335
/* Define this in order to use direct I/O on index files: */
336
/* NOTE: DO NOT ENABLE!
338
* It currently does not work, because of changes to the inde
341
//#define XT_USE_DIRECT_IO_ON_INDEX
344
* Define this variable if PBXT should do lazy deleting in indexes
345
* Note, even if the variable is not defined, PBXT will handle
346
* lazy deleted items in an index.
348
* NOTE: This can cause significant degrade of index scan speed.
349
* 25% on sysbench readonly index scan tests.
351
//#define XT_USE_LAZY_DELETE
354
* Define this variable if a connection should wait for the
355
* sweeper to clean up previous transactions executed by the
356
* connection, before continuing.
358
* The number of transactions that the sweeper is aload to
359
* lag can be dynamic, but there is a limit (XT_MAX_XACT_BEHIND)
361
#define XT_WAIT_FOR_CLEANUP
364
* This seems to be the optimal value, at least according to
365
* sysbench/sysbench run --test=oltp --num-threads=128 --max-requests=50000 --mysql-user=root
366
* --oltp-table-size=100000 --oltp-table-name=sb_pbxt --mysql-engine-trx=yes
368
* Using 8, 16 and 128 threads.
370
#define XT_MAX_XACT_BEHIND 2
373
* Define this to implement NO ACTION correctly
374
* NOTE: this does not work currently because of a bug
377
* The bug prevent returning of an error in external_lock()
378
* on statement end. In this case an assertion fails.
380
* set storage_engine = pbxt;
381
* DROP TABLE IF EXISTS t4,t3,t2,t1;
382
* CREATE TABLE t1 (s1 INT PRIMARY KEY);
383
* CREATE TABLE t2 (s1 INT PRIMARY KEY, FOREIGN KEY (s1) REFERENCES t1 (s1) ON DELETE NO ACTION);
385
* INSERT INTO t1 VALUES (1);
386
* INSERT INTO t2 VALUES (1);
389
* INSERT INTO t1 VALUES (2);
390
* DELETE FROM t1 where s1 = 1;
391
* <-- Assertion fails here because this DELETE returns
392
* an error from external_lock()
394
//#define XT_IMPLEMENT_NO_ACTION
397
* This is the number of rows imported in a single transactions.
398
* Import is done during the ALTER TABLE, CREATE INDEX and
399
* LOAD DATA INFILE statements.
401
#define XT_IMPORT_ROW_COUNT 10000
404
* Define this if freed records should be clustered together in pages.
405
* This means when a record is freed it is not added to the front of
406
* the free list if there is already a record free on the same page.
407
* Instead it is changed into the list so that free records in the
408
* same page follow one another.
410
* This should cause updated records to cluster togetger
413
//#define XT_CLUSTER_FREE_RECORDS
415
/* Define this to add a timer for disk writes.
417
#define XT_TIME_DISK_WRITES
419
/* Define this to add a timer to disk reads. Not enabled by default,
420
* because it is considered expensive (?).
422
#define XT_TIME_DISK_READS
425
* Define the number of bytes that are written by the writer before
426
* it flushes the record and row files.
429
//#define XT_REC_FLUSH_THRESHOLD (500 * 1024)
431
//#define XT_REC_FLUSH_THRESHOLD (100 * 1024 * 1024)
435
* Define this in order to sort writes to the handle data file.
436
* The number given is the maximum number of writes delayed for
439
//#define XT_SORT_REC_WRITES
441
#ifdef XT_SORT_REC_WRITES
443
#define XT_SORT_REC_MAX_BUF_SIZE (64*1024)
445
#define XT_SORT_REC_MAX_BUF_SIZE (256*1024)
449
/* Define the variable to cause the sweeper to sort transactions
450
* that need to be sweeped. The affect is that the sweeper will
451
* clean up transaction as soon as possible, not just in
454
//#define XT_SWEEPER_SORT_XACTS
457
* Define this in order to enable BLOB streaming. BLOB streaming
458
* requires the PBMS storage engine. If the engine is not present
459
* then defining this has no affect.
461
//#define PBMS_ENABLED
463
/* Define this value if online-backup should be supported.
464
* Note that, online backup is currently only supported
465
* by MySQL 6.0.9 or later
467
#define XT_ENABLE_ONLINE_BACKUP
469
/* Define this switch if you don't want to use atomic
472
#ifndef XT_NO_ATOMICS
473
//#define XT_NO_ATOMICS
476
/* When pbxt_flush_log_at_trx_commit != 1, the transaction log is flushed
477
* at regular intervals. Set the interval here.
479
#define XT_XLOG_FLUSH_FREQ 1000
481
/* ----------------------------------------------------------------------
485
#define XT_INDEX_PAGE_SIZE (1 << XT_INDEX_PAGE_SHIFTS)
486
#define XT_INDEX_PAGE_MASK (XT_INDEX_PAGE_SIZE - 1)
488
/* The index file uses direct I/O. This is the minimum block.
489
* size that can be used when doing direct I/O.
491
#define XT_BLOCK_SIZE_FOR_DIRECT_IO 512
494
* The header is currently a fixed size, so the information must
497
* This must also be a multiple of XT_INDEX_MIN_BLOCK_SIZE
499
#define XT_INDEX_HEAD_SIZE (XT_BLOCK_SIZE_FOR_DIRECT_IO * 8) // 4K
501
#define XT_IDENTIFIER_CHAR_COUNT 64
503
#define XT_IDENTIFIER_NAME_SIZE ((XT_IDENTIFIER_CHAR_COUNT * 3) + 1) // The identifier length as UTF-8
504
#define XT_TABLE_NAME_SIZE ((XT_IDENTIFIER_CHAR_COUNT * 5) + 1) // The maximum length of a file name that has been normalized
506
#define XT_ADD_PTR(p, l) ((void *) ((char *) (p) + (l)))
508
#define XT_MAX_XA_DATA_SIZE (3*4 + 128) /* Corresponds to the maximum size of struct xid_t in handler.h. */
510
/* ----------------------------------------------------------------------
511
* DEFINES DEPENDENT ON CONSTANTS
514
#define XT_ROW_REC_FILE_PTR XTOpenFilePtr
515
#define XT_PREAD_RR_FILE xt_pread_file
516
#define XT_FLUSH_RR_FILE xt_flush_file
517
#define XT_CLOSE_RR_FILE_NS xt_close_file_ns
519
#define XT_LOCK_MEMORY_PTR(x, f, a, s, v, c) do { if (!xt_lock_file_ptr(f, &x, a, s, v, c)) x = NULL; } while (0)
520
#define XT_UNLOCK_MEMORY_PTR(f, d, v) xt_unlock_file_ptr(f, d, v)
522
/* ----------------------------------------------------------------------
524
* Reduce the thresholds to make things happen faster.
527
#ifdef XT_USE_GLOBAL_DEBUG_SIZES
529
//#undef XT_ROW_RWLOCKS
530
//#define XT_ROW_RWLOCKS 2
532
//#undef XT_TAB_MIN_VAR_REC_LENGTH
533
//#define XT_TAB_MIN_VAR_REC_LENGTH 20
535
//#undef XT_ROW_LOCK_COUNT
536
//#define XT_ROW_LOCK_COUNT (XT_ROW_RWLOCKS * 2)
538
//#undef XT_INDEX_PAGE_SHIFTS
539
//#define XT_INDEX_PAGE_SHIFTS 8 // 256
540
//#undef XT_BLOCK_SIZE_FOR_DIRECT_IO
541
//#define XT_BLOCK_SIZE_FOR_DIRECT_IO 256
543
//#undef XT_INDEX_WRITE_BUFFER_SIZE
544
//#define XT_INDEX_WRITE_BUFFER_SIZE (40 * 1024)
546
//#undef XT_XLOG_FLUSH_FREQ
547
//#define XT_XLOG_FLUSH_FREQ (30 * 1000)
549
//#undef XT_IMPORT_ROW_COUNT
550
//#define XT_IMPORT_ROW_COUNT 12
554
/* ----------------------------------------------------------------------
559
* Byte order on the disk is little endian! This is the byte order of the i386.
560
* Little endian byte order starts with the least significant byte.
562
* The reason for choosing this byte order for the disk is 2-fold:
563
* Firstly the i386 is the cheapest and fasted platform today.
564
* Secondly the i386, unlike RISK chips (with big endian) can address
565
* memory that is not aligned!
567
* Since the disk image of PrimeBase XT is not aligned, the second point
568
* is significant. A RISK chip needs to access it byte-wise, so we might as
569
* well do the byte swapping at the same time.
571
* The macros below are of 4 general types:
573
* GET/SET - Get and set 1,2,4,8 byte values (short, int, long, etc).
574
* Values are swapped only on big endian platforms. This makes these
575
* functions very efficient on little-endian platforms.
577
* COPY - Transfer data without swapping regardless of platform. This
578
* function is a bit more efficient on little-endian platforms
579
* because alignment is not an issue.
581
* MOVE - Similar to get and set, but the deals with memory instead
582
* of values. Since no swapping is done on little-endian platforms
583
* this function is identical to COPY on little-endian platforms.
585
* SWAP - Transfer and swap data regardless of the platform type.
586
* Aligment is not assumed.
588
* The DISK component of the macro names indicates that alignment of
589
* the value cannot be assumed.
592
#if BYTE_ORDER == BIG_ENDIAN
593
/* The native order of the machine is big endian. Since the native disk
594
* disk order of XT is little endian, all data to and from disk
597
#define XT_SET_DISK_1(d, s) ((d)[0] = (xtWord1) (s))
599
#define XT_SET_DISK_2(d, s) do { (d)[0] = (xtWord1) (((xtWord2) (s)) & 0xFF); (d)[1] = (xtWord1) ((((xtWord2) (s)) >> 8 ) & 0xFF); } while (0)
601
#define XT_SET_DISK_3(d, s) do { (d)[0] = (xtWord1) (((xtWord4) (s)) & 0xFF); (d)[1] = (xtWord1) ((((xtWord4) (s)) >> 8 ) & 0xFF); \
602
(d)[2] = (xtWord1) ((((xtWord4) (s)) >> 16) & 0xFF); } while (0)
604
#define XT_SET_DISK_4(d, s) do { (d)[0] = (xtWord1) (((xtWord4) (s)) & 0xFF); (d)[1] = (xtWord1) ((((xtWord4) (s)) >> 8 ) & 0xFF); \
605
(d)[2] = (xtWord1) ((((xtWord4) (s)) >> 16) & 0xFF); (d)[3] = (xtWord1) ((((xtWord4) (s)) >> 24) & 0xFF); } while (0)
607
#define XT_SET_DISK_6(d, s) do { (d)[0] = (xtWord1) (((xtWord8) (s)) & 0xFF); (d)[1] = (xtWord1) ((((xtWord8) (s)) >> 8 ) & 0xFF); \
608
(d)[2] = (xtWord1) ((((xtWord8) (s)) >> 16) & 0xFF); (d)[3] = (xtWord1) ((((xtWord8) (s)) >> 24) & 0xFF); \
609
(d)[4] = (xtWord1) ((((xtWord8) (s)) >> 32) & 0xFF); (d)[5] = (xtWord1) ((((xtWord8) (s)) >> 40) & 0xFF); } while (0)
611
#define XT_SET_DISK_8(d, s) do { (d)[0] = (xtWord1) (((xtWord8) (s)) & 0xFF); (d)[1] = (xtWord1) ((((xtWord8) (s)) >> 8 ) & 0xFF); \
612
(d)[2] = (xtWord1) ((((xtWord8) (s)) >> 16) & 0xFF); (d)[3] = (xtWord1) ((((xtWord8) (s)) >> 24) & 0xFF); \
613
(d)[4] = (xtWord1) ((((xtWord8) (s)) >> 32) & 0xFF); (d)[5] = (xtWord1) ((((xtWord8) (s)) >> 40) & 0xFF); \
614
(d)[6] = (xtWord1) ((((xtWord8) (s)) >> 48) & 0xFF); (d)[7] = (xtWord1) ((((xtWord8) (s)) >> 56) & 0xFF); } while (0)
616
#define XT_GET_DISK_1(s) ((s)[0])
618
#define XT_GET_DISK_2(s) ((xtWord2) (((xtWord2) (s)[0]) | (((xtWord2) (s)[1]) << 8)))
620
#define XT_GET_DISK_3(s) ((xtWord4) (((xtWord4) (s)[0]) | (((xtWord4) (s)[1]) << 8) | (((xtWord4) (s)[2]) << 16)))
622
#define XT_GET_DISK_4(s) (((xtWord4) (s)[0]) | (((xtWord4) (s)[1]) << 8 ) | \
623
(((xtWord4) (s)[2]) << 16) | (((xtWord4) (s)[3]) << 24))
625
#define XT_GET_DISK_6(s) (((xtWord8) (s)[0]) | (((xtWord8) (s)[1]) << 8 ) | \
626
(((xtWord8) (s)[2]) << 16) | (((xtWord8) (s)[3]) << 24) | \
627
(((xtWord8) (s)[4]) << 32) | (((xtWord8) (s)[5]) << 40))
629
#define XT_GET_DISK_8(s) (((xtWord8) (s)[0]) | (((xtWord8) (s)[1]) << 8 ) | \
630
(((xtWord8) (s)[2]) << 16) | (((xtWord8) (s)[3]) << 24) | \
631
(((xtWord8) (s)[4]) << 32) | (((xtWord8) (s)[5]) << 40) | \
632
(((xtWord8) (s)[6]) << 48) | (((xtWord8) (s)[7]) << 56))
634
/* Move will copy memory, and swap the bytes on a big endian machine.
635
* On a little endian machine it is the same as COPY.
637
#define XT_MOVE_DISK_1(d, s) ((d)[0] = (s)[0])
638
#define XT_MOVE_DISK_2(d, s) do { (d)[0] = (s)[1]; (d)[1] = (s)[0]; } while (0)
639
#define XT_MOVE_DISK_3(d, s) do { (d)[0] = (s)[2]; (d)[1] = (s)[1]; (d)[2] = (s)[0]; } while (0)
640
#define XT_MOVE_DISK_4(d, s) do { (d)[0] = (s)[3]; (d)[1] = (s)[2]; (d)[2] = (s)[1]; (d)[3] = (s)[0]; } while (0)
641
#define XT_MOVE_DISK_8(d, s) do { (d)[0] = (s)[7]; (d)[1] = (s)[6]; \
642
(d)[2] = (s)[5]; (d)[3] = (s)[4]; \
643
(d)[4] = (s)[3]; (d)[5] = (s)[2]; \
644
(d)[6] = (s)[1]; (d)[7] = (s)[0]; } while (0)
647
* Copy just copies the number of bytes assuming the data is not alligned.
649
#define XT_COPY_DISK_1(d, s) (d)[0] = s
650
#define XT_COPY_DISK_2(d, s) do { (d)[0] = (s)[0]; (d)[1] = (s)[1]; } while (0)
651
#define XT_COPY_DISK_3(d, s) do { (d)[0] = (s)[0]; (d)[1] = (s)[1]; (d)[2] = (s)[2]; } while (0)
652
#define XT_COPY_DISK_4(d, s) do { (d)[0] = (s)[0]; (d)[1] = (s)[1]; (d)[2] = (s)[2]; (d)[3] = (s)[3]; } while (0)
653
#define XT_COPY_DISK_6(d, s) memcpy(&((d)[0]), &((s)[0]), 6)
654
#define XT_COPY_DISK_8(d, s) memcpy(&((d)[0]), &((s)[0]), 8)
655
#define XT_COPY_DISK_10(d, s) memcpy(&((d)[0]), &((s)[0]), 10)
657
#define XT_SET_NULL_DISK_1(d) XT_SET_DISK_1(d, 0)
658
#define XT_SET_NULL_DISK_2(d) do { (d)[0] = 0; (d)[1] = 0; } while (0)
659
#define XT_SET_NULL_DISK_4(d) do { (d)[0] = 0; (d)[1] = 0; (d)[2] = 0; (d)[3] = 0; } while (0)
660
#define XT_SET_NULL_DISK_6(d) do { (d)[0] = 0; (d)[1] = 0; (d)[2] = 0; (d)[3] = 0; (d)[4] = 0; (d)[5] = 0; } while (0)
661
#define XT_SET_NULL_DISK_8(d) do { (d)[0] = 0; (d)[1] = 0; (d)[2] = 0; (d)[3] = 0; (d)[4] = 0; (d)[5] = 0; (d)[6] = 0; (d)[7] = 0; } while (0)
663
#define XT_IS_NULL_DISK_1(d) (!(XT_GET_DISK_1(d)))
664
#define XT_IS_NULL_DISK_4(d) (!(d)[0] && !(d)[1] && !(d)[2] && !(d)[3])
665
#define XT_IS_NULL_DISK_8(d) (!(d)[0] && !(d)[1] && !(d)[2] && !(d)[3] && !(d)[4] && !(d)[5] && !(d)[6] && !(7)[3])
667
#define XT_EQ_DISK_4(d, s) ((d)[0] == (s)[0] && (d)[1] == (s)[1] && (d)[2] == (s)[2] && (d)[3] == (s)[3])
668
#define XT_EQ_DISK_8(d, s) ((d)[0] == (s)[0] && (d)[1] == (s)[1] && (d)[2] == (s)[2] && (d)[3] == (s)[3] && \
669
(d)[4] == (s)[4] && (d)[5] == (s)[5] && (d)[6] == (s)[6] && (d)[7] == (s)[7])
671
#define XT_IS_FF_DISK_4(d) ((d)[0] == 0xFF && (d)[1] == 0xFF && (d)[2] == 0xFF && (d)[3] == 0xFF)
674
* The native order of the machine is little endian. This means the data to
675
* and from disk need not be swapped. In addition to this, since
676
* the i386 can access non-aligned memory we are not required to
677
* handle the data byte-for-byte.
679
#define XT_SET_DISK_1(d, s) ((d)[0] = (xtWord1) (s))
680
#define XT_SET_DISK_2(d, s) (*((xtWord2 *) &((d)[0])) = (xtWord2) (s))
681
#define XT_SET_DISK_3(d, s) do { (*((xtWord2 *) &((d)[0])) = (xtWord2) (s)); *((xtWord1 *) &((d)[2])) = (xtWord1) (((xtWord4) (s)) >> 16); } while (0)
682
#define XT_SET_DISK_4(d, s) (*((xtWord4 *) &((d)[0])) = (xtWord4) (s))
683
#define XT_SET_DISK_6(d, s) do { *((xtWord4 *) &((d)[0])) = (xtWord4) (s); *((xtWord2 *) &((d)[4])) = (xtWord2) (((xtWord8) (s)) >> 32); } while (0)
684
#define XT_SET_DISK_8(d, s) (*((xtWord8 *) &((d)[0])) = (xtWord8) (s))
686
#define XT_GET_DISK_1(s) ((s)[0])
687
#define XT_GET_DISK_2(s) *((xtWord2 *) &((s)[0]))
688
#define XT_GET_DISK_3(s) ((xtWord4) *((xtWord2 *) &((s)[0])) | (((xtWord4) *((xtWord1 *) &((s)[2]))) << 16))
689
#define XT_GET_DISK_4(s) *((xtWord4 *) &((s)[0]))
690
#define XT_GET_DISK_6(s) ((xtWord8) *((xtWord4 *) &((s)[0])) | (((xtWord8) *((xtWord2 *) &((s)[4]))) << 32))
691
#define XT_GET_DISK_8(s) *((xtWord8 *) &((s)[0]))
693
#define XT_MOVE_DISK_1(d, s) ((d)[0] = (s)[0])
694
#define XT_MOVE_DISK_2(d, s) XT_COPY_DISK_2(d, s)
695
#define XT_MOVE_DISK_3(d, s) XT_COPY_DISK_3(d, s)
696
#define XT_MOVE_DISK_4(d, s) XT_COPY_DISK_4(d, s)
697
#define XT_MOVE_DISK_8(d, s) XT_COPY_DISK_8(d, s)
699
#define XT_COPY_DISK_1(d, s) (d)[0] = s
700
#define XT_COPY_DISK_2(d, s) (*((xtWord2 *) &((d)[0])) = (*((xtWord2 *) &((s)[0]))))
701
#define XT_COPY_DISK_3(d, s) do { *((xtWord2 *) &((d)[0])) = *((xtWord2 *) &((s)[0])); (d)[2] = (s)[2]; } while (0)
702
#define XT_COPY_DISK_4(d, s) (*((xtWord4 *) &((d)[0])) = (*((xtWord4 *) &((s)[0]))))
703
#define XT_COPY_DISK_6(d, s) do { *((xtWord4 *) &((d)[0])) = *((xtWord4 *) &((s)[0])); *((xtWord2 *) &((d)[4])) = *((xtWord2 *) &((s)[4])); } while (0)
704
#define XT_COPY_DISK_8(d, s) (*((xtWord8 *) &(d[0])) = (*((xtWord8 *) &((s)[0]))))
705
#define XT_COPY_DISK_10(d, s) memcpy(&((d)[0]), &((s)[0]), 10)
707
#define XT_SET_NULL_DISK_1(d) XT_SET_DISK_1(d, 0)
708
#define XT_SET_NULL_DISK_2(d) XT_SET_DISK_2(d, 0)
709
#define XT_SET_NULL_DISK_3(d) XT_SET_DISK_3(d, 0)
710
#define XT_SET_NULL_DISK_4(d) XT_SET_DISK_4(d, 0L)
711
#define XT_SET_NULL_DISK_6(d) XT_SET_DISK_6(d, 0LL)
712
#define XT_SET_NULL_DISK_8(d) XT_SET_DISK_8(d, 0LL)
714
#define XT_IS_NULL_DISK_1(d) (!(XT_GET_DISK_1(d)))
715
#define XT_IS_NULL_DISK_2(d) (!(XT_GET_DISK_2(d)))
716
#define XT_IS_NULL_DISK_3(d) (!(XT_GET_DISK_3(d)))
717
#define XT_IS_NULL_DISK_4(d) (!(XT_GET_DISK_4(d)))
718
#define XT_IS_NULL_DISK_8(d) (!(XT_GET_DISK_8(d)))
720
#define XT_EQ_DISK_4(d, s) (XT_GET_DISK_4(d) == XT_GET_DISK_4(s))
721
#define XT_EQ_DISK_8(d, s) (XT_GET_DISK_8(d) == XT_GET_DISK_8(s))
723
#define XT_IS_FF_DISK_4(d) (XT_GET_DISK_4(d) == 0xFFFFFFFF)
726
#define XT_CMP_DISK_4(a, b) ((xtInt4) XT_GET_DISK_4(a) - (xtInt4) XT_GET_DISK_4(b))
727
#define XT_CMP_DISK_8(d, s) memcmp(&((d)[0]), &((s)[0]), 8)
728
//#define XT_CMP_DISK_8(d, s) (XT_CMP_DISK_4((d).h_number_4, (s).h_number_4) == 0 ? XT_CMP_DISK_4((d).h_file_4, (s).h_file_4) : XT_CMP_DISK_4((d).h_number_4, (s).h_number_4))
730
#define XT_SWAP_DISK_2(d, s) do { (d)[0] = (s)[1]; (d)[1] = (s)[0]; } while (0)
731
#define XT_SWAP_DISK_3(d, s) do { (d)[0] = (s)[2]; (d)[1] = (s)[1]; (d)[2] = (s)[0]; } while (0)
732
#define XT_SWAP_DISK_4(d, s) do { (d)[0] = (s)[3]; (d)[1] = (s)[2]; (d)[2] = (s)[1]; (d)[3] = (s)[0]; } while (0)
733
#define XT_SWAP_DISK_8(d, s) do { (d)[0] = (s)[7]; (d)[1] = (s)[6]; (d)[2] = (s)[5]; (d)[3] = (s)[4]; \
734
(d)[4] = (s)[3]; (d)[5] = (s)[2]; (d)[6] = (s)[1]; (d)[7] = (s)[0]; } while (0)
736
/* ----------------------------------------------------------------------
737
* GLOBAL APPLICATION TYPES & MACROS
742
typedef void (*XTFreeFunc)(struct XTThread *self, void *thunk, void *item);
743
typedef int (*XTCompareFunc)(struct XTThread *self, register const void *thunk, register const void *a, register const void *b);
745
/* Log ID and offset: */
746
#define xtLogID xtWord4
747
#define xtLogOffset off_t
749
#define xtDatabaseID xtWord4
750
#define xtTableID xtWord4
751
#define xtOpSeqNo xtWord4
752
#define xtXactID xtWord4
753
#define xtThreadID xtWord4
756
//#define XT_USE_NODE_ID_STRUCT
759
#ifdef XT_USE_NODE_ID_STRUCT
760
typedef struct xtIndexNodeID {
763
#define XT_NODE_TEMP xtWord4 xt_node_temp
764
#define XT_NODE_ID(a) (a).x
765
#define XT_RET_NODE_ID(a) *((xtIndexNodeID *) &(xt_node_temp = (a)))
768
#define xtIndexNodeID xtWord4
769
#define XT_NODE_ID(a) a
770
#define XT_RET_NODE_ID(a) ((xtIndexNodeID) (a))
773
/* Row, Record ID and Record offsets: */
774
#define xtRowID xtWord4
775
#define xtRecordID xtWord4 /* NOTE: Record offset == header-size + record-id * record-size! */
776
#define xtRefID xtWord4 /* Must be big enough to contain a xtRowID and a xtRecordID! */
777
#define xtRecOffset off_t
778
#define xtDiskRecordID4 XTDiskValue4
780
#define xtProcID DWORD
782
#define xtProcID pid_t
785
#define XT_ROW_ID_SIZE 4
786
#define XT_RECORD_ID_SIZE 4
787
#define XT_REF_ID_SIZE 4 /* max(XT_ROW_ID_SIZE, XT_RECORD_ID_SIZE) */
788
#define XT_RECORD_OFFS_SIZE 4
789
#define XT_RECORD_REF_SIZE (XT_RECORD_ID_SIZE + XT_ROW_ID_SIZE)
790
#define XT_CHECKSUM4_REC(x) (x)
792
#define XT_XACT_ID_SIZE 4
793
#define XT_CHECKSUM4_XACT(x) (x)
796
#define __FUNC__ __FUNCTION__
797
#elif defined(XT_SOLARIS)
798
#define __FUNC__ "__func__"
800
#define __FUNC__ __PRETTY_FUNCTION__
803
/* ----------------------------------------------------------------------
807
extern bool pbxt_inited;
808
extern xtBool pbxt_ignore_case;
809
extern const char *pbxt_extensions[];
810
extern xtBool pbxt_crash_debug;
813
/* ----------------------------------------------------------------------
814
* DRIZZLE MAPPINGS VARIABLES
818
/* Drizzle is stuck at this level: */
819
#define MYSQL_VERSION_ID 60005
821
#define TABLE_LIST TableList
824
#define MYSQL_THD Session *
825
#define THR_THD THR_Session
826
#define STRUCT_TABLE class drizzled::Table
827
#define TABLE_SHARE TableShare
829
#define MYSQL_TYPE_STRING DRIZZLE_TYPE_VARCHAR
830
#define MYSQL_TYPE_VARCHAR DRIZZLE_TYPE_VARCHAR
831
#define MYSQL_TYPE_LONGLONG DRIZZLE_TYPE_LONGLONG
832
#define MYSQL_TYPE_BLOB DRIZZLE_TYPE_BLOB
833
#define MYSQL_TYPE_ENUM DRIZZLE_TYPE_ENUM
834
#define MYSQL_TYPE_LONG DRIZZLE_TYPE_LONG
835
#define MYSQL_PLUGIN_VAR_HEADER DRIZZLE_PLUGIN_VAR_HEADER
836
#define MYSQL_SYSVAR_STR DRIZZLE_SYSVAR_STR
837
#define MYSQL_SYSVAR_INT DRIZZLE_SYSVAR_INT
838
#define MYSQL_SYSVAR_BOOL DRIZZLE_SYSVAR_BOOL
839
#define MYSQL_SYSVAR DRIZZLE_SYSVAR
840
#define MYSQL_STORAGE_ENGINE_PLUGIN DRIZZLE_STORAGE_ENGINE_PLUGIN
841
#define MYSQL_INFORMATION_SCHEMA_PLUGIN DRIZZLE_INFORMATION_SCHEMA_PLUGIN
842
#define memcpy_fixed memcpy
843
#define bfill(m, len, ch) memset(m, ch, len)
845
#define mx_tmp_use_all_columns(x, y) (x)->use_all_columns(y)
846
#define mx_tmp_restore_column_map(x, y) (x)->restore_column_map(y)
848
#define MX_TABLE_TYPES_T StorageEngine::Table_flags
849
#define MX_UINT8_T uint8_t
850
#define MX_ULONG_T uint32_t
851
#define MX_ULONGLONG_T uint64_t
852
#define MX_LONGLONG_T uint64_t
853
#define MX_CHARSET_INFO struct drizzled::charset_info_st
854
#define MX_CONST_CHARSET_INFO const struct drizzled::charset_info_st
855
#define MX_CONST const
856
#define MX_BITMAP drizzled::MyBitmap
857
#define MX_BIT_SIZE() numOfBitsInMap()
858
#define MX_BIT_SET(x, y) (x)->setBit(y)
859
#define MX_BIT_FAST_TEST_AND_SET(x, y) (x)->testAndSet(y)
862
//#define int16 int16_t
863
//#define int32 int32_t
864
//#define uint16 uint16_t
865
//#define uint32 uint32_t
866
#define uchar unsigned char
867
#define longlong int64_t
868
#define ulonglong uint64_t
869
#define handler Cursor
871
#define HAVE_LONG_LONG
873
#define my_malloc(x, y) malloc(x)
874
#define my_free(x, y) free(x)
876
#define HA_CAN_SQL_HANDLER 0
877
#define HA_CAN_INSERT_DELAYED 0
878
#define HA_BINLOG_ROW_CAPABLE 0
879
#define HA_BINLOG_STMT_CAPABLE 0
880
#define HA_CACHE_TBL_TRANSACT 0
887
#define thd_charset session_charset
888
#define thd_slave_thread session_slave_thread
889
#define thd_non_transactional_update session_non_transactional_update
890
#define thd_binlog_format session_binlog_format
891
#define thd_mark_transaction_to_rollback session_mark_transaction_to_rollback
892
#define thd_ha_data session_ha_data
893
#define current_thd current_session
894
#define thd_sql_command session_sql_command
895
#define thd_test_options session_test_options
896
#define thd_killed session_killed
897
#define thd_tx_isolation session_tx_isolation
898
#define thd_in_lock_tables session_in_lock_tables
899
#define thd_tablespace_op session_tablespace_op
900
#define thd_alloc session_alloc
901
#define thd_make_lex_string session_make_lex_string
902
#define column_bitmaps_signal()
904
#define my_pthread_setspecific_ptr(T, V) pthread_setspecific(T, (void*) (V))
906
#define mysql_real_data_home drizzle_real_data_home
908
#define mi_int4store(T,A) { uint32_t def_temp= (uint32_t) (A);\
909
((unsigned char*) (T))[3]= (unsigned char) (def_temp);\
910
((unsigned char*) (T))[2]= (unsigned char) (def_temp >> 8);\
911
((unsigned char*) (T))[1]= (unsigned char) (def_temp >> 16);\
912
((unsigned char*) (T))[0]= (unsigned char) (def_temp >> 24); }
914
#define mi_uint4korr(A) ((uint32_t) (((uint32_t) (((const unsigned char*) (A))[3])) +\
915
(((uint32_t) (((const unsigned char*) (A))[2])) << 8) +\
916
(((uint32_t) (((const unsigned char*) (A))[1])) << 16) +\
917
(((uint32_t) (((const unsigned char*) (A))[0])) << 24)))
919
class PBXTStorageEngine;
920
typedef PBXTStorageEngine handlerton;
925
extern "C" void session_mark_transaction_to_rollback(drizzled::Session *session, bool all);
928
/* The MySQL case: */
929
#if MYSQL_VERSION_ID >= 50404
930
#define STRUCT_TABLE struct TABLE
932
#define STRUCT_TABLE struct st_table
934
#if MYSQL_VERSION_ID >= 60009
935
#define storage_media default_storage_media
938
#define mx_tmp_use_all_columns dbug_tmp_use_all_columns
939
#define mx_tmp_restore_column_map(x, y) dbug_tmp_restore_column_map((x)->read_set, y)
940
#define MX_BIT_FAST_TEST_AND_SET(x, y) bitmap_fast_test_and_set(x, y)
942
#define MX_TABLE_TYPES_T ulonglong
943
#define MX_UINT8_T uint8
944
#define MX_ULONG_T ulong
945
#define MX_ULONGLONG_T ulonglong
946
#define MX_LONGLONG_T longlong
947
#define MX_CHARSET_INFO CHARSET_INFO
948
#define MX_CONST_CHARSET_INFO struct charset_info_st
950
#define MX_BITMAP MY_BITMAP
951
#define MX_BIT_SIZE() n_bits
952
#define MX_BIT_SET(x, y) bitmap_set_bit(x, y)
956
#define MX_BIT_IS_SUBSET(x, y) bitmap_is_subset(x, y)
958
#ifndef XT_SCAN_CORE_DEFINED
959
#define XT_SCAN_CORE_DEFINED
960
xtBool xt_mm_scan_core(void);
963
//#define DEBUG_LOCK_QUEUE