| 1 | /* Copyright (C) 2007 MySQL AB & Sanja Belkin |
| 2 | |
| 3 | This program is free software; you can redistribute it and/or modify |
| 4 | it under the terms of the GNU General Public License as published by |
| 5 | the Free Software Foundation; version 2 of the License. |
| 6 | |
| 7 | This program is distributed in the hope that it will be useful, |
| 8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 10 | GNU General Public License for more details. |
| 11 | |
| 12 | You should have received a copy of the GNU General Public License |
| 13 | along with this program; if not, write to the Free Software |
| 14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ |
| 15 | |
| 16 | #ifndef _ma_loghandler_lsn_h |
| 17 | #define _ma_loghandler_lsn_h |
| 18 | |
| 19 | /* |
| 20 | Transaction log record address: |
| 21 | file_no << 32 | offset |
| 22 | file_no is only 3 bytes so we can use signed integer to make |
| 23 | comparison simpler. |
| 24 | */ |
| 25 | typedef int64 TRANSLOG_ADDRESS; |
| 26 | |
| 27 | /* |
| 28 | Compare addresses |
| 29 | A1 > A2 -> result > 0 |
| 30 | A1 == A2 -> 0 |
| 31 | A1 < A2 -> result < 0 |
| 32 | */ |
| 33 | #define cmp_translog_addr(A1,A2) ((A1) - (A2)) |
| 34 | |
| 35 | /* |
| 36 | TRANSLOG_ADDRESS is just address of some byte in the log (usually some |
| 37 | chunk) |
| 38 | LSN used where address of some record in the log needed (not just any |
| 39 | address) |
| 40 | */ |
| 41 | typedef TRANSLOG_ADDRESS LSN; |
| 42 | |
| 43 | /* Gets file number part of a LSN/log address */ |
| 44 | #define LSN_FILE_NO(L) (uint32) ((L) >> 32) |
| 45 | |
| 46 | /* Gets raw file number part of a LSN/log address */ |
| 47 | #define LSN_FILE_NO_PART(L) ((L) & ((int64)0xFFFFFF00000000LL)) |
| 48 | |
| 49 | /* Parts of LSN for printing */ |
| 50 | #define LSN_IN_PARTS(L) (uint)LSN_FILE_NO(L),(uint)LSN_OFFSET(L) |
| 51 | #define LSN_FMT "(%u,0x%x)" |
| 52 | |
| 53 | /* Gets record offset of a LSN/log address */ |
| 54 | #define LSN_OFFSET(L) (ulong) ((L) & 0xFFFFFFFFL) |
| 55 | |
| 56 | /* Makes lsn/log address from file number and record offset */ |
| 57 | #define MAKE_LSN(F,S) ((LSN) ((((uint64)(F)) << 32) | (S))) |
| 58 | |
| 59 | /* checks LSN */ |
| 60 | #define LSN_VALID(L) \ |
| 61 | ((LSN_FILE_NO_PART(L) != FILENO_IMPOSSIBLE) && \ |
| 62 | (LSN_OFFSET(L) != LOG_OFFSET_IMPOSSIBLE)) |
| 63 | |
| 64 | /* size of stored LSN on a disk, don't change it! */ |
| 65 | #define LSN_STORE_SIZE 7 |
| 66 | |
| 67 | /* Puts LSN into buffer (dst) */ |
| 68 | #define lsn_store(dst, lsn) \ |
| 69 | do { \ |
| 70 | int3store((dst), LSN_FILE_NO(lsn)); \ |
| 71 | int4store((char*)(dst) + 3, LSN_OFFSET(lsn)); \ |
| 72 | } while (0) |
| 73 | |
| 74 | /* Unpacks LSN from the buffer (P) */ |
| 75 | #define lsn_korr(P) MAKE_LSN(uint3korr(P), uint4korr((const char*)(P) + 3)) |
| 76 | |
| 77 | /* what we need to add to LSN to increase it on one file */ |
| 78 | #define LSN_ONE_FILE ((int64)0x100000000LL) |
| 79 | |
| 80 | #define LSN_REPLACE_OFFSET(L, S) (LSN_FILE_NO_PART(L) | (S)) |
| 81 | |
| 82 | /* |
| 83 | an 8-byte type whose most significant uchar is used for "flags"; 7 |
| 84 | other bytes are a LSN. |
| 85 | */ |
| 86 | typedef LSN LSN_WITH_FLAGS; |
| 87 | #define LSN_WITH_FLAGS_TO_LSN(x) (x & 0x00FFFFFFFFFFFFFFULL) |
| 88 | #define LSN_WITH_FLAGS_TO_FLAGS(x) (x & 0xFF00000000000000ULL) |
| 89 | |
| 90 | #define FILENO_IMPOSSIBLE 0 /**< log file's numbering starts at 1 */ |
| 91 | #define LOG_OFFSET_IMPOSSIBLE 0 /**< log always has a header */ |
| 92 | #define LSN_IMPOSSIBLE ((LSN)0) |
| 93 | /* following LSN also is impossible */ |
| 94 | #define LSN_ERROR ((LSN)1) |
| 95 | |
| 96 | /** @brief some impossible LSN serve as markers */ |
| 97 | |
| 98 | /** |
| 99 | When table is modified by maria_chk, or auto-zerofilled, old REDOs don't |
| 100 | apply, table is freshly born again somehow: its state's LSNs need to be |
| 101 | updated to the new instance which receives this table. |
| 102 | */ |
| 103 | #define LSN_NEEDS_NEW_STATE_LSNS ((LSN)2) |
| 104 | |
| 105 | /** |
| 106 | @brief the maximum valid LSN. |
| 107 | Unlike ULONGLONG_MAX, it can be safely used in comparison with valid LSNs |
| 108 | (ULONGLONG_MAX is too big for correctness of cmp_translog_addr()). |
| 109 | */ |
| 110 | #define LSN_MAX (LSN)0x00FFFFFFFFFFFFFFULL |
| 111 | |
| 112 | #endif |
| 113 | |