maria_def.h 47.9 KB
Newer Older
1 2 3 4
/* Copyright (C) 2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB

   This program is free software; you can redistribute it and/or modify
   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 8 9 10 11 12 13 14 15 16 17 18

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* This file is included by all internal maria files */

#include "maria.h"				/* Structs & some defines */
unknown's avatar
unknown committed
19
#include <myisampack.h>				/* packing of keys */
20
#include <my_tree.h>
unknown's avatar
unknown committed
21
#include <my_bitmap.h>
22 23 24 25 26 27
#ifdef THREAD
#include <my_pthread.h>
#include <thr_lock.h>
#else
#include <my_no_pthread.h>
#endif
28 29 30
#include "ma_loghandler.h"
#include "ma_control_file.h"

31
/* For testing recovery */
32
#ifndef DBUG_OFF
33
#define IDENTICAL_PAGES_AFTER_RECOVERY 1
34
#endif
35 36
/* Do extra sanity checking */
#define SANITY_CHECKS 1
37 38 39
#ifdef EXTRA_DEBUG
#define EXTRA_DEBUG_KEY_CHANGES
#endif
40

41 42
#define MAX_NONMAPPED_INSERTS 1000
#define MARIA_MAX_TREE_LEVELS 32
43
#define MARIA_MAX_CONTROL_FILE_LOCK_RETRY 30     /* Retry this many times */
44 45 46

struct st_transaction;

47
/* undef map from my_nosys; We need test-if-disk full */
unknown's avatar
unknown committed
48 49 50
#undef my_write

#define CRC_SIZE 4
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

typedef struct st_maria_status_info
{
  ha_rows records;				/* Rows in table */
  ha_rows del;					/* Removed rows */
  my_off_t empty;				/* lost space in datafile */
  my_off_t key_empty;				/* lost space in indexfile */
  my_off_t key_file_length;
  my_off_t data_file_length;
  ha_checksum checksum;
} MARIA_STATUS_INFO;

typedef struct st_maria_state_info
{
  struct
  {					/* Fileheader */
    uchar file_version[4];
    uchar options[2];
    uchar header_length[2];
    uchar state_info_length[2];
    uchar base_info_length[2];
    uchar base_pos[2];
    uchar key_parts[2];			/* Key parts */
    uchar unique_key_parts[2];		/* Key parts + unique parts */
    uchar keys;				/* number of keys in file */
    uchar uniques;			/* number of UNIQUE definitions */
    uchar language;			/* Language for indexes */
    uchar fulltext_keys;
unknown's avatar
unknown committed
79
    uchar data_file_type;
80 81
    /* Used by mariapack to store the original data_file_type */
    uchar org_data_file_type;
82 83 84 85 86
  } header;

  MARIA_STATUS_INFO state;
  ha_rows split;			/* number of split blocks */
  my_off_t dellink;			/* Link to next removed block */
unknown's avatar
unknown committed
87
  ulonglong first_bitmap_with_space;
88 89 90 91 92
  ulonglong auto_increment;
  ulong process;			/* process that updated table last */
  ulong unique;				/* Unique number for this process */
  ulong update_count;			/* Updated for each write lock */
  ulong status;
93 94
  double *rec_per_key_part;
  ulong *nulls_per_key_part;
95
  ha_checksum checksum;                 /* Table checksum */
96
  my_off_t *key_root;			/* Start of key trees */
97
  my_off_t key_del;			/* delete links for index pages */
98
  my_off_t records_at_analyze;		/* Rows when calculating rec_per_key */
99 100 101 102 103 104 105 106 107 108 109

  ulong sec_index_changed;		/* Updated when new sec_index */
  ulong sec_index_used;			/* which extra index are in use */
  ulonglong key_map;			/* Which keys are in use */
  ulong version;			/* timestamp of create */
  time_t create_time;			/* Time when created database */
  time_t recover_time;			/* Time for last recover */
  time_t check_time;			/* Time for last check */
  uint sortkey;				/* sorted by this key (not used) */
  uint open_count;
  uint8 changed;			/* Changed since mariachk */
110
  LSN create_rename_lsn;    /**< LSN when table was last created/renamed */
unknown's avatar
unknown committed
111 112
  /** @brief Log horizon when state was last updated on disk */
  TRANSLOG_ADDRESS is_of_horizon;
113 114 115 116 117 118 119 120

  /* the following isn't saved on disk */
  uint state_diff_length;		/* Should be 0 */
  uint state_length;			/* Length of state header in file */
  ulong *key_info;
} MARIA_STATE_INFO;


121
#define MARIA_STATE_INFO_SIZE	\
unknown's avatar
unknown committed
122
  (24 + LSN_STORE_SIZE*2 + 4 + 11*8 + 4*4 + 8 + 3*4 + 5*8)
123
#define MARIA_STATE_KEY_SIZE	(8 + 4)
124
#define MARIA_STATE_KEYBLOCK_SIZE  8
125
#define MARIA_STATE_KEYSEG_SIZE	12
unknown's avatar
unknown committed
126
#define MARIA_STATE_EXTRA_SIZE (MARIA_MAX_KEY*MARIA_STATE_KEY_SIZE + MARIA_MAX_KEY*HA_MAX_KEY_SEG*MARIA_STATE_KEYSEG_SIZE)
127
#define MARIA_KEYDEF_SIZE	(2+ 5*2)
128 129
#define MARIA_UNIQUEDEF_SIZE	(2+1+1)
#define HA_KEYSEG_SIZE		(6+ 2*2 + 4*2)
130
#define MARIA_COLUMNDEF_SIZE	(2*7+1+1+4)
131
#define MARIA_BASE_INFO_SIZE	(MY_UUID_SIZE + 5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16)
132
#define MARIA_INDEX_BLOCK_MARGIN 16	/* Safety margin for .MYI tables */
133
/* Internal management bytes needed to store 2 keys on an index page */
134 135
#define MARIA_INDEX_OVERHEAD_SIZE (TRANSID_SIZE * 2)
#define MARIA_DELETE_KEY_NR  255	/* keynr for deleted blocks */
136 137 138 139 140

/*
  Basic information of the Maria table. This is stored on disk
  and not changed (unless we do DLL changes).
*/
141

unknown's avatar
unknown committed
142
typedef struct st_ma_base_info
143
{
unknown's avatar
unknown committed
144
  my_off_t keystart;                    /* Start of keys */
145 146 147
  my_off_t max_data_file_length;
  my_off_t max_key_file_length;
  my_off_t margin_key_file_length;
unknown's avatar
unknown committed
148 149 150 151
  ha_rows records, reloc;               /* Create information */
  ulong mean_row_length;                /* Create information */
  ulong reclength;                      /* length of unpacked record */
  ulong pack_reclength;                 /* Length of full packed rec */
152
  ulong min_pack_length;
unknown's avatar
unknown committed
153
  ulong max_pack_length;                /* Max possibly length of packed rec */
154
  ulong min_block_length;
unknown's avatar
unknown committed
155 156 157 158 159 160
  uint fields;                          /* fields in table */
  uint fixed_not_null_fields;
  uint fixed_not_null_fields_length;
  uint max_field_lengths;
  uint pack_fields;                     /* packed fields in table */
  uint varlength_fields;                /* char/varchar/blobs */
161 162 163
  /* Number of bytes in the index used to refer to a row (2-8) */
  uint rec_reflength;
  /* Number of bytes in the index used to refer to another index page (2-8) */
unknown's avatar
unknown committed
164 165 166 167 168 169 170 171 172 173 174 175
  uint key_reflength;                   /* = 2-8 */
  uint keys;                            /* same as in state.header */
  uint auto_key;                        /* Which key-1 is a auto key */
  uint blobs;                           /* Number of blobs */
  /* Length of packed bits (when table was created first time) */
  uint pack_bytes;
  /* Length of null bits (when table was created first time) */
  uint original_null_bytes;
  uint null_bytes;                      /* Null bytes in record */
  uint field_offsets;                   /* Number of field offsets */
  uint max_key_block_length;            /* Max block length */
  uint max_key_length;                  /* Max key length */
176 177 178
  /* Extra allocation when using dynamic record format */
  uint extra_alloc_bytes;
  uint extra_alloc_procent;
unknown's avatar
unknown committed
179 180 181
  uint is_nulls_extended;               /* 1 if new null bytes */
  uint default_row_flag;                /* 0 or ROW_FLAG_NULLS_EXTENDED */
  uint block_size;
182
  /* Size of initial record buffer */
unknown's avatar
unknown committed
183
  uint default_rec_buff_size;
184
  /* Extra number of bytes the row format require in the record buffer */
unknown's avatar
unknown committed
185
  uint extra_rec_buff_size;
186 187
  /* Tuning flags that can be ignored by older Maria versions */
  uint extra_options;
unknown's avatar
unknown committed
188

189 190
  /* The following are from the header */
  uint key_parts, all_key_parts;
191
  uchar uuid[MY_UUID_SIZE];
unknown's avatar
unknown committed
192 193 194 195 196
  /**
     @brief If false, we disable logging, versioning, transaction etc. Observe
     difference with MARIA_SHARE::now_transactional
  */
  my_bool born_transactional;
197 198 199
} MARIA_BASE_INFO;


unknown's avatar
unknown committed
200
/* Structs used intern in database */
201

unknown's avatar
unknown committed
202
typedef struct st_maria_blob            /* Info of record */
203
{
unknown's avatar
unknown committed
204 205 206
  ulong offset;                         /* Offset to blob in record */
  uint pack_length;                     /* Type of packed length */
  ulong length;                         /* Calc:ed for each record */
207 208 209 210 211 212 213 214 215 216
} MARIA_BLOB;


typedef struct st_maria_pack
{
  ulong header_length;
  uint ref_length;
  uchar version;
} MARIA_PACK;

unknown's avatar
unknown committed
217 218 219 220
typedef struct st_maria_file_bitmap
{
  uchar *map;
  ulonglong page;                      /* Page number for current bitmap */
221
  uint used_size;                      /* Size of bitmap head that is not 0 */
unknown's avatar
unknown committed
222
  my_bool changed;                     /* 1 if page needs to be flushed */
unknown's avatar
unknown committed
223 224
  my_bool flush_all_requested;         /**< If _ma_bitmap_flush_all waiting */
  uint non_flushable;                  /**< 0 if bitmap and log are in sync */
unknown's avatar
unknown committed
225
  PAGECACHE_FILE file;		       /* datafile where bitmap is stored */
unknown's avatar
unknown committed
226 227 228

#ifdef THREAD
  pthread_mutex_t bitmap_lock;
unknown's avatar
unknown committed
229
  pthread_cond_t bitmap_cond;          /**< When bitmap becomes flushable */
unknown's avatar
unknown committed
230 231 232 233 234 235
#endif
  /* Constants, allocated when initiating bitmaps */
  uint sizes[8];                      /* Size per bit combination */
  uint total_size;		      /* Total usable size of bitmap page */
  uint block_size;                    /* Block size of file */
  ulong pages_covered;                /* Pages covered by bitmap + 1 */
unknown's avatar
unknown committed
236
  DYNAMIC_ARRAY pinned_pages;         /**< not-yet-flushable bitmap pages */
unknown's avatar
unknown committed
237 238
} MARIA_FILE_BITMAP;

unknown's avatar
unknown committed
239 240
#define MARIA_CHECKPOINT_LOOKS_AT_ME 1
#define MARIA_CHECKPOINT_SHOULD_FREE_ME 2
unknown's avatar
unknown committed
241
#define MARIA_CHECKPOINT_SEEN_IN_LOOP 4
unknown's avatar
unknown committed
242

243 244 245 246 247 248 249 250 251
typedef struct st_maria_share
{					/* Shared between opens */
  MARIA_STATE_INFO state;
  MARIA_BASE_INFO base;
  MARIA_KEYDEF ft2_keyinfo;		/* Second-level ft-key
						   definition */
  MARIA_KEYDEF *keyinfo;		/* Key definitions */
  MARIA_UNIQUEDEF *uniqueinfo;		/* unique definitions */
  HA_KEYSEG *keyparts;			/* key part info */
252
  MARIA_COLUMNDEF *columndef;		/* Pointer to column information */
253 254
  MARIA_PACK pack;			/* Data about packed records */
  MARIA_BLOB *blobs;			/* Pointer to blobs */
255
  uint16 *column_nr;			/* Original column order */
256
  char *unique_file_name;		/* realpath() of index file */
257 258 259
  char *data_file_name;			/* Resolved path names from symlinks */
  char *index_file_name;
  char *open_file_name;			/* parameter to open filename */
unknown's avatar
unknown committed
260
  uchar *file_map;			/* mem-map of file if possible */
unknown's avatar
unknown committed
261
  PAGECACHE *pagecache;			/* ref to the current key cache */
262 263
  MARIA_DECODE_TREE *decode_trees;
  uint16 *decode_tables;
264
  uint16 id; /**< 2-byte id by which log records refer to the table */
265
  /* Called the first time the table instance is opened */
unknown's avatar
unknown committed
266
  my_bool (*once_init)(struct st_maria_share *, File);
267
  /* Called when the last instance of the table is closed */
unknown's avatar
unknown committed
268
  my_bool (*once_end)(struct st_maria_share *);
269
  /* Is called for every open of the table */
270
  my_bool (*init)(MARIA_HA *);
271
  /* Is called for every close of the table */
272
  void (*end)(MARIA_HA *);
273
  /* Called when we want to read a record from a specific position */
274
  int (*read_record)(MARIA_HA *, uchar *, MARIA_RECORD_POS);
275
  /* Initialize a scan */
276
  my_bool (*scan_init)(MARIA_HA *);
277
  /* Read next record while scanning */
278
  int (*scan)(MARIA_HA *, uchar *, MARIA_RECORD_POS, my_bool);
279
  /* End scan */
280
  void (*scan_end)(MARIA_HA *);
281 282
  int (*scan_remember_pos)(MARIA_HA *, MARIA_RECORD_POS*);
  void (*scan_restore_pos)(MARIA_HA *, MARIA_RECORD_POS);
283
  /* Pre-write of row (some handlers may do the actual write here) */
284
  MARIA_RECORD_POS (*write_record_init)(MARIA_HA *, const uchar *);
285
  /* Write record (or accept write_record_init) */
286
  my_bool (*write_record)(MARIA_HA *, const uchar *);
287
  /* Called when write failed */
288 289
  my_bool (*write_record_abort)(MARIA_HA *);
  my_bool (*update_record)(MARIA_HA *, MARIA_RECORD_POS,
unknown's avatar
unknown committed
290
                           const uchar *, const uchar *);
291 292
  my_bool (*delete_record)(MARIA_HA *, const uchar *record);
  my_bool (*compare_record)(MARIA_HA *, const uchar *);
293
  /* calculate checksum for a row */
294
  ha_checksum(*calc_checksum)(MARIA_HA *, const uchar *);
295 296 297 298
  /*
    Calculate checksum for a row during write. May be 0 if we calculate
    the checksum in write_record_init()
  */
299
  ha_checksum(*calc_write_checksum)(MARIA_HA *, const uchar *);
300
  /* calculate checksum for a row during check table */
301
  ha_checksum(*calc_check_checksum)(MARIA_HA *, const uchar *);
302
  /* Compare a row in memory with a row on disk */
303
  my_bool (*compare_unique)(MARIA_HA *, MARIA_UNIQUEDEF *,
unknown's avatar
unknown committed
304
                            const uchar *record, MARIA_RECORD_POS pos);
305 306 307
  my_off_t (*keypos_to_recpos)(MARIA_HA *info, my_off_t pos);
  my_off_t (*recpos_to_keypos)(MARIA_HA *info, my_off_t pos);

308
  /* Mapings to read/write the data file */
unknown's avatar
unknown committed
309 310
  size_t (*file_read)(MARIA_HA *, uchar *, size_t, my_off_t, myf);
  size_t (*file_write)(MARIA_HA *, const uchar *, size_t, my_off_t, myf);
311
  invalidator_by_filename invalidator;	/* query cache invalidator */
312
  my_off_t current_key_del;		/* delete links for index pages */
313 314 315 316
  ulong this_process;			/* processid */
  ulong last_process;			/* For table-change-check */
  ulong last_version;			/* Version on start */
  ulong options;			/* Options used */
unknown's avatar
unknown committed
317
  ulong min_pack_length;		/* These are used by packed data */
318 319 320 321
  ulong max_pack_length;
  ulong state_diff_length;
  uint rec_reflength;			/* rec_reflength in use now */
  uint unique_name_length;
322
  uint keypage_header;
323 324
  uint32 ftparsers;			/* Number of distinct ftparsers
						   + 1 */
unknown's avatar
unknown committed
325
  PAGECACHE_FILE kfile;			/* Shared keyfile */
326 327 328 329
  File data_file;			/* Shared data file */
  int mode;				/* mode of file on open */
  uint reopen;				/* How many times reopened */
  uint w_locks, r_locks, tot_locks;	/* Number of read/write locks */
unknown's avatar
unknown committed
330
  uint block_size;			/* block_size of keyfile & data file*/
331
  /* Fixed length part of a packed row in BLOCK_RECORD format */
unknown's avatar
unknown committed
332
  uint base_length;
333 334
  myf write_flag;
  enum data_file_type data_file_type;
335
  enum pagecache_page_type page_type;   /* value depending transactional */
unknown's avatar
unknown committed
336
  uint8 in_checkpoint;               /**< if Checkpoint looking at table */
unknown's avatar
unknown committed
337
  my_bool temporary;
338 339 340
  /* Below flag is needed to make log tables work with concurrent insert */
  my_bool is_log_table;

341 342
  my_bool changed,			/* If changed since lock */
    global_changed,			/* If changed since open */
unknown's avatar
unknown committed
343 344
    not_flushed, concurrent_insert;
  my_bool delay_key_write;
345
  my_bool have_rtree;
unknown's avatar
unknown committed
346 347 348 349 350 351 352
  /**
     @brief if the table is transactional right now. It may have been created
     transactional (base.born_transactional==TRUE) but with transactionality
     (logging) temporarily disabled (now_transactional==FALSE). The opposite
     (FALSE, TRUE) is impossible.
  */
  my_bool now_transactional;
353
  my_bool used_key_del;                         /* != 0 if key_del is locked */
354 355
#ifdef THREAD
  THR_LOCK lock;
unknown's avatar
unknown committed
356
  pthread_mutex_t intern_lock;		/* Locking for use with _locking */
357
  pthread_cond_t intern_cond;
358 359 360 361 362
  rw_lock_t *key_root_lock;
#endif
  my_off_t mmaped_length;
  uint nonmmaped_inserts;		/* counter of writing in
						   non-mmaped area */
unknown's avatar
unknown committed
363
  MARIA_FILE_BITMAP bitmap;
364
  rw_lock_t mmap_lock;
unknown's avatar
unknown committed
365
  LSN lsn_of_file_id; /**< LSN of its last LOGREC_FILE_ID */
366 367 368
} MARIA_SHARE;


unknown's avatar
unknown committed
369
typedef uchar MARIA_BITMAP_BUFFER;
unknown's avatar
unknown committed
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403

typedef struct st_maria_bitmap_block
{
  ulonglong page;                       /* Page number */
  /* Number of continuous pages. TAIL_BIT is set if this is a tail page */
  uint page_count;
  uint empty_space;                     /* Set for head and tail pages */
  /*
    Number of BLOCKS for block-region (holds all non-blob-fields or one blob)
  */
  uint sub_blocks;
  /* set to <> 0 in write_record() if this block was actually used */
  uint8 used;
  uint8 org_bitmap_value;
} MARIA_BITMAP_BLOCK;


typedef struct st_maria_bitmap_blocks
{
  MARIA_BITMAP_BLOCK *block;
  uint count;
  my_bool tail_page_skipped;            /* If some tail pages was not used */
  my_bool page_skipped;                 /* If some full pages was not used */
} MARIA_BITMAP_BLOCKS;


/* Data about the currently read row */
typedef struct st_maria_row
{
  MARIA_BITMAP_BLOCKS insert_blocks;
  MARIA_BITMAP_BUFFER *extents;
  MARIA_RECORD_POS lastpos, nextpos;
  MARIA_RECORD_POS *tail_positions;
  ha_checksum checksum;
404
  LSN orig_undo_lsn;			/* Lsn at start of row insert */
unknown's avatar
unknown committed
405
  uchar *empty_bits, *field_lengths;
unknown's avatar
unknown committed
406 407 408 409
  uint *null_field_lengths;             /* All null field lengths */
  ulong *blob_lengths;                  /* Length for each blob */
  ulong base_length, normal_length, char_length, varchar_length, blob_length;
  ulong head_length, total_length;
unknown's avatar
unknown committed
410
  size_t extents_buffer_length;         /* Size of 'extents' buffer */
unknown's avatar
unknown committed
411 412 413
  uint field_lengths_length;            /* Length of data in field_lengths */
  uint extents_count;                   /* number of extents in 'extents' */
  uint full_page_count, tail_count;     /* For maria_chk */
unknown's avatar
unknown committed
414
  uint space_on_head_page;
unknown's avatar
unknown committed
415 416 417 418 419
} MARIA_ROW;

/* Data to scan row in blocked format */
typedef struct st_maria_block_scan
{
unknown's avatar
unknown committed
420 421
  uchar *bitmap_buff, *bitmap_pos, *bitmap_end, *page_buff;
  uchar *dir, *dir_end;
unknown's avatar
unknown committed
422 423 424 425 426 427 428
  ulong bitmap_page;
  ulonglong bits;
  uint number_of_rows, bit_pos;
  MARIA_RECORD_POS row_base_page;
} MARIA_BLOCK_SCAN;


429
struct st_maria_handler
430 431
{
  MARIA_SHARE *s;			/* Shared between open:s */
432
  struct st_transaction *trn;           /* Pointer to active transaction */
433
  MARIA_STATUS_INFO *state, save_state;
434 435
  MARIA_ROW cur_row;                    /* The active row that we just read */
  MARIA_ROW new_row;			/* Storage for a row during update */
436
  MARIA_BLOCK_SCAN scan, *scan_save;
437 438
  MARIA_BLOB *blobs;			/* Pointer to blobs */
  MARIA_BIT_BUFF bit_buff;
unknown's avatar
unknown committed
439
  DYNAMIC_ARRAY bitmap_blocks;
440
  DYNAMIC_ARRAY pinned_pages;
441 442
  /* accumulate indexfile changes between write's */
  TREE *bulk_insert;
443
  LEX_STRING *log_row_parts;		/* For logging */
444
  DYNAMIC_ARRAY *ft1_to_ft2;		/* used only in ft1->ft2 conversion */
445
  MEM_ROOT      ft_memroot;             /* used by the parser               */
446
  MYSQL_FTPARSER_PARAM *ftparser_param;	/* share info between init/deinit */
447 448
  LSN   *key_write_undo_lsn;            /* Pointer to undo for each key */
  LSN   *key_delete_undo_lsn;           /* Pointer to undo for each key */
unknown's avatar
unknown committed
449 450 451 452 453 454
  uchar *buff;				/* page buffer */
  uchar *keyread_buff;                   /* Buffer for last key read */
  uchar *lastkey, *lastkey2;		/* Last used search key */
  uchar *first_mbr_key;			/* Searhed spatial key */
  uchar *rec_buff;			/* Temp buffer for recordpack */
  uchar *int_keypos,			/* Save position for next/previous */
455
   *int_maxpos;				/* -""- */
unknown's avatar
unknown committed
456
  uchar *update_field_data;		/* Used by update in rows-in-block */
457 458
  uint int_nod_flag;			/* -""- */
  uint32 int_keytree_version;		/* -""- */
459
  int (*read_record)(MARIA_HA *, uchar*, MARIA_RECORD_POS);
460 461 462 463 464
  invalidator_by_filename invalidator;	/* query cache invalidator */
  ulong this_unique;			/* uniq filenumber or thread */
  ulong last_unique;			/* last unique number */
  ulong this_loop;			/* counter for this open */
  ulong last_loop;			/* last used counter */
unknown's avatar
unknown committed
465 466
  MARIA_RECORD_POS save_lastpos;
  MARIA_RECORD_POS dup_key_pos;
467 468 469
  my_off_t pos;				/* Intern variable */
  my_off_t last_keypage;		/* Last key page read */
  my_off_t last_search_keypage;		/* Last keypage when searching */
unknown's avatar
unknown committed
470

471 472 473 474 475
  /*
    QQ: the folloing two xxx_length fields should be removed,
     as they are not compatible with parallel repair
  */
  ulong packed_length, blob_length;	/* Length of found, packed record */
unknown's avatar
unknown committed
476
  size_t rec_buff_size;
unknown's avatar
unknown committed
477
  PAGECACHE_FILE dfile;			/* The datafile */
unknown's avatar
unknown committed
478 479
  IO_CACHE rec_cache;			/* When cacheing records */
  LIST open_list;
unknown's avatar
unknown committed
480
  MY_BITMAP changed_fields;
481 482 483 484 485 486 487 488
  uint opt_flag;			/* Optim. for space/speed */
  uint update;				/* If file changed since open */
  int lastinx;				/* Last used index */
  uint lastkey_length;			/* Length of key in lastkey */
  uint last_rkey_length;		/* Last length in maria_rkey() */
  enum ha_rkey_function last_key_func;	/* CONTAIN, OVERLAP, etc */
  uint save_lastkey_length;
  uint pack_key_length;			/* For MARIAMRG */
489
  myf lock_wait;			/* is 0 or MY_SHORT_WAIT */
490 491 492 493 494 495 496
  int errkey;				/* Got last error on this key */
  int lock_type;			/* How database was locked */
  int tmp_lock_type;			/* When locked by readinfo */
  uint data_changed;			/* Somebody has changed data */
  uint save_update;			/* When using KEY_READ */
  int save_lastinx;
  uint preload_buff_size;		/* When preloading indexes */
497 498
  uint16 last_used_keyseg;              /* For MARIAMRG */
  uint8 used_key_del;                   /* != 0 if key_del is used */
499 500 501
  my_bool was_locked;			/* Was locked in panic */
  my_bool append_insert_at_end;		/* Set if concurrent insert */
  my_bool quick_mode;
502
  /* Marker if key_del_changed */
unknown's avatar
unknown committed
503
  /* If info->keyread_buff can't be used for rnext */
504
  my_bool page_changed;
505 506
  /* If info->keyread_buff has to be re-read for rnext */
  my_bool keyread_buff_used;
unknown's avatar
unknown committed
507
  my_bool once_flags;			/* For MARIA_MRG */
508
#ifdef __WIN__
unknown's avatar
unknown committed
509
  my_bool owned_by_merge;               /* This Maria table is part of a merge union */
510
#endif
511 512 513
#ifdef THREAD
  THR_LOCK_DATA lock;
#endif
unknown's avatar
unknown committed
514
  uchar *maria_rtree_recursion_state;	/* For RTREE */
unknown's avatar
unknown committed
515
  uchar length_buff[5];			/* temp buff to store blob lengths */
516 517 518
  int maria_rtree_recursion_depth;
};

unknown's avatar
unknown committed
519
/* Some defines used by maria-functions */
520

521
#define USE_WHOLE_KEY	65535         /* Use whole key in _search() */
522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
#define F_EXTRA_LCK	-1

/* bits in opt_flag */
#define MEMMAP_USED	32
#define REMEMBER_OLD_POS 64

#define WRITEINFO_UPDATE_KEYFILE	1
#define WRITEINFO_NO_UNLOCK		2

/* once_flags */
#define USE_PACKED_KEYS         1
#define RRND_PRESERVE_LASTINX   2

/* bits in state.changed */

#define STATE_CHANGED		1
#define STATE_CRASHED		2
#define STATE_CRASHED_ON_REPAIR 4
#define STATE_NOT_ANALYZED	8
#define STATE_NOT_OPTIMIZED_KEYS 16
#define STATE_NOT_SORTED_PAGES	32
unknown's avatar
unknown committed
543
#define STATE_NOT_OPTIMIZED_ROWS 64
544 545 546 547 548 549

/* options to maria_read_cache */

#define READING_NEXT	1
#define READING_HEADER	2

550 551 552 553 554 555
/* Number of bytes on key pages to indicate used size */
#define KEYPAGE_USED_SIZE  2
#define KEYPAGE_KEYID_SIZE 1
#define KEYPAGE_FLAG_SIZE  1
#define KEYPAGE_CHECKSUM_SIZE 4
#define MAX_KEYPAGE_HEADER_SIZE (LSN_STORE_SIZE + KEYPAGE_USED_SIZE + \
556 557
                                 KEYPAGE_KEYID_SIZE + KEYPAGE_FLAG_SIZE + \
                                 TRANSID_SIZE)
558
#define KEYPAGE_FLAG_ISNOD 1
559

560 561 562 563 564 565 566 567
#define _ma_get_page_used(share,x) \
  ((uint) mi_uint2korr((x) + (share)->keypage_header - KEYPAGE_USED_SIZE))
#define _ma_store_page_used(share,x,y) \
  mi_int2store((x) + (share)->keypage_header - KEYPAGE_USED_SIZE, (y))
#define _ma_test_if_nod(share,x) \
  ((_ma_get_keypage_flag(share,x) & KEYPAGE_FLAG_ISNOD) ? (share)->base.key_reflength : 0)

#define _ma_get_used_and_nod(share,buff,length,nod)                     \
568
{                                                                      \
569 570
  nod=    _ma_test_if_nod((share),(buff));                              \
  length= _ma_get_page_used((share),(buff));                            \
571
}
572 573
#define _ma_store_keynr(share, x, nr) x[(share)->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE]= (nr)
#define _ma_get_keynr(share, x) ((uchar) x[(share)->keypage_header - KEYPAGE_KEYID_SIZE - KEYPAGE_FLAG_SIZE - KEYPAGE_USED_SIZE])
574 575 576 577
#define _ma_store_transid(buff, transid) \
  int6store((buff) + LSN_STORE_SIZE, (transid))
#define _ma_korr_transid(buff) \
  uint6korr((buff) + LSN_STORE_SIZE)
578 579
#define _ma_get_keypage_flag(share,x) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]
#define _ma_store_keypage_flag(share,x,flag) x[(share)->keypage_header - KEYPAGE_USED_SIZE - KEYPAGE_FLAG_SIZE]= (flag)
580

581

unknown's avatar
unknown committed
582 583 584 585 586 587
/*
  TODO: write int4store_aligned as *((uint32 *) (T))= (uint32) (A) for
  architectures where it is possible
*/
#define int4store_aligned(A,B) int4store((A),(B))

588 589 590
#define maria_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
    DBUG_PRINT("error", ("Marked table crashed"));                      \
  }while(0)
unknown's avatar
unknown committed
591 592 593 594
#define maria_mark_crashed_share(x)                                     \
  do{(x)->state.changed|= STATE_CRASHED;                                \
    DBUG_PRINT("error", ("Marked table crashed"));                      \
  }while(0)
595 596 597 598 599 600
#define maria_mark_crashed_on_repair(x) do{(x)->s->state.changed|=      \
      STATE_CRASHED|STATE_CRASHED_ON_REPAIR;                            \
    (x)->update|= HA_STATE_CHANGED;                                     \
    DBUG_PRINT("error",                                                 \
               ("Marked table crashed"));                               \
  }while(0)
601 602
#define maria_is_crashed(x) ((x)->s->state.changed & STATE_CRASHED)
#define maria_is_crashed_on_repair(x) ((x)->s->state.changed & STATE_CRASHED_ON_REPAIR)
603
#ifdef EXTRA_DEBUG
604 605
#define maria_print_error(SHARE, ERRNO)                     \
        _ma_report_error((ERRNO), (SHARE)->index_file_name)
606 607 608 609
#else
#define maria_print_error(SHARE, ERRNO) while (0)
#endif

610 611 612 613 614 615 616 617 618 619 620

/* Functions to store length of space packed keys, VARCHAR or BLOB keys */

#define store_key_length(key,length) \
{ if ((length) < 255) \
  { *(key)=(length); } \
  else \
  { *(key)=255; mi_int2store((key)+1,(length)); } \
}

#define get_key_full_length(length,key) \
unknown's avatar
unknown committed
621 622
  { if (*(uchar*) (key) != 255)            \
    length= ((uint) *(uchar*) ((key)++))+1; \
623 624 625 626 627
  else \
  { length=mi_uint2korr((key)+1)+3; (key)+=3; } \
}

#define get_key_full_length_rdonly(length,key) \
unknown's avatar
unknown committed
628 629
{ if (*(uchar*) (key) != 255) \
    length= ((uint) *(uchar*) ((key)))+1; \
630 631 632 633
  else \
  { length=mi_uint2korr((key)+1)+3; } \
}

634
#define maria_max_key_length() ((maria_block_size - MAX_KEYPAGE_HEADER_SIZE)/2 - MARIA_INDEX_OVERHEAD_SIZE)
635 636 637 638 639 640 641 642 643 644 645 646 647
#define get_pack_length(length) ((length) >= 255 ? 3 : 1)

#define MARIA_MIN_BLOCK_LENGTH	20		/* Because of delete-link */
/* Don't use to small record-blocks */
#define MARIA_EXTEND_BLOCK_LENGTH	20
#define MARIA_SPLIT_LENGTH	((MARIA_EXTEND_BLOCK_LENGTH+4)*2)
	/* Max prefix of record-block */
#define MARIA_MAX_DYN_BLOCK_HEADER	20
#define MARIA_BLOCK_INFO_HEADER_LENGTH 20
#define MARIA_DYN_DELETE_BLOCK_HEADER 20    /* length of delete-block-header */
#define MARIA_DYN_MAX_BLOCK_LENGTH	((1L << 24)-4L)
#define MARIA_DYN_MAX_ROW_LENGTH	(MARIA_DYN_MAX_BLOCK_LENGTH - MARIA_SPLIT_LENGTH)
#define MARIA_DYN_ALIGN_SIZE	  4	/* Align blocks on this */
unknown's avatar
unknown committed
648
#define MARIA_MAX_DYN_HEADER_BYTE 13	/* max header uchar for dynamic rows */
649 650 651 652 653 654 655 656 657 658
#define MARIA_MAX_BLOCK_LENGTH	((((ulong) 1 << 24)-1) & (~ (ulong) (MARIA_DYN_ALIGN_SIZE-1)))
#define MARIA_REC_BUFF_OFFSET      ALIGN_SIZE(MARIA_DYN_DELETE_BLOCK_HEADER+sizeof(uint32))

#define MEMMAP_EXTRA_MARGIN	7	/* Write this as a suffix for file */

#define PACK_TYPE_SELECTED	1	/* Bits in field->pack_type */
#define PACK_TYPE_SPACE_FIELDS	2
#define PACK_TYPE_ZERO_FILL	4
#define MARIA_FOUND_WRONG_KEY 32738	/* Impossible value from ha_key_cmp */

659
#define MARIA_BLOCK_SIZE(key_length,data_pointer,key_pointer,block_size)  (((((key_length)+(data_pointer)+(key_pointer))*4+(key_pointer)+2)/(block_size)+1)*(block_size))
660 661 662 663 664 665 666 667
#define MARIA_MAX_KEYPTR_SIZE	5	/* For calculating block lengths */
#define MARIA_MIN_KEYBLOCK_LENGTH 50	/* When to split delete blocks */

#define MARIA_MIN_SIZE_BULK_INSERT_TREE 16384	/* this is per key */
#define MARIA_MIN_ROWS_TO_USE_BULK_INSERT 100
#define MARIA_MIN_ROWS_TO_DISABLE_INDEXES 100
#define MARIA_MIN_ROWS_TO_USE_WRITE_CACHE 10

668 669 670
/* Marker for impossible delete link */
#define IMPOSSIBLE_PAGE_NO LL(0xFFFFFFFFFF)

671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
/* The UNIQUE check is done with a hashed long key */

#define MARIA_UNIQUE_HASH_TYPE	HA_KEYTYPE_ULONG_INT
#define maria_unique_store(A,B)    mi_int4store((A),(B))

#ifdef THREAD
extern pthread_mutex_t THR_LOCK_maria;
#endif
#if !defined(THREAD) || defined(DONT_USE_RW_LOCKS)
#define rw_wrlock(A) {}
#define rw_rdlock(A) {}
#define rw_unlock(A) {}
#endif


686
/* Some extern variables */
687
extern LIST *maria_open_list;
688 689 690
extern uchar maria_file_magic[], maria_pack_file_magic[];
extern uchar maria_uuid[MY_UUID_SIZE];
extern uint maria_read_vec[], maria_readnext_vec[];
691
extern uint maria_quick_table_bits;
692
extern const char *maria_data_root;
unknown's avatar
unknown committed
693
extern uchar maria_zero_string[];
694
extern my_bool maria_inited;
695 696


697
/* This is used by _ma_calc_xxx_key_length och _ma_store_key */
698 699
typedef struct st_maria_s_param
{
unknown's avatar
unknown committed
700 701
  const uchar *key;
  uchar *prev_key, *next_key_pos;
702 703 704 705 706
  uchar *key_pos;                               /* For balance page */
  uint ref_length, key_length, n_ref_length;
  uint n_length, totlength, part_of_prev_key, prev_length, pack_marker;
  uint changed_length;
  int move_length;                              /* For balance_page */
707 708 709 710
  bool store_not_null;
} MARIA_KEY_PARAM;


711 712 713
/* Used to store reference to pinned page */
typedef struct st_pinned_page
{
unknown's avatar
unknown committed
714
  PAGECACHE_BLOCK_LINK *link;
715 716
  enum pagecache_page_lock unlock, write_lock;
  my_bool changed;
717 718 719 720
} MARIA_PINNED_PAGE;


/* Prototypes for intern functions */
unknown's avatar
unknown committed
721 722
extern int _ma_read_dynamic_record(MARIA_HA *, uchar *, MARIA_RECORD_POS);
extern int _ma_read_rnd_dynamic_record(MARIA_HA *, uchar *, MARIA_RECORD_POS,
723
                                       my_bool);
unknown's avatar
unknown committed
724
extern my_bool _ma_write_dynamic_record(MARIA_HA *, const uchar *);
unknown's avatar
unknown committed
725
extern my_bool _ma_update_dynamic_record(MARIA_HA *, MARIA_RECORD_POS,
unknown's avatar
unknown committed
726 727 728 729
                                         const uchar *, const uchar *);
extern my_bool _ma_delete_dynamic_record(MARIA_HA *info, const uchar *record);
extern my_bool _ma_cmp_dynamic_record(MARIA_HA *info, const uchar *record);
extern my_bool _ma_write_blob_record(MARIA_HA *, const uchar *);
unknown's avatar
unknown committed
730
extern my_bool _ma_update_blob_record(MARIA_HA *, MARIA_RECORD_POS,
unknown's avatar
unknown committed
731 732 733
                                      const uchar *, const uchar *);
extern int _ma_read_static_record(MARIA_HA *info, uchar *, MARIA_RECORD_POS);
extern int _ma_read_rnd_static_record(MARIA_HA *, uchar *, MARIA_RECORD_POS,
unknown's avatar
unknown committed
734
                                      my_bool);
unknown's avatar
unknown committed
735
extern my_bool _ma_write_static_record(MARIA_HA *, const uchar *);
unknown's avatar
unknown committed
736
extern my_bool _ma_update_static_record(MARIA_HA *, MARIA_RECORD_POS,
unknown's avatar
unknown committed
737 738 739 740
                                        const uchar *, const uchar *);
extern my_bool _ma_delete_static_record(MARIA_HA *info, const uchar *record);
extern my_bool _ma_cmp_static_record(MARIA_HA *info, const uchar *record);
extern int _ma_ck_write(MARIA_HA *info, uint keynr, uchar *key,
741
                        uint length);
742 743 744 745 746 747 748
extern int _ma_enlarge_root(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
                            const uchar *key, MARIA_RECORD_POS *root);
extern int _ma_insert(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
                      uchar *key, uchar *anc_buff, uchar *key_pos,
                      my_off_t anc_page, uchar *key_buff, my_off_t father_page,
                      uchar *father_buff, MARIA_PINNED_PAGE *father_page_link,
                      uchar *father_key_pos, my_bool insert_last);
749
extern int _ma_ck_real_write_btree(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
unknown's avatar
unknown committed
750
                                   uchar *key, uint key_length,
unknown's avatar
unknown committed
751
                                   MARIA_RECORD_POS *root, uint comp_flag);
752 753 754 755 756 757 758
extern int _ma_split_page(register MARIA_HA *info,
                          register MARIA_KEYDEF *keyinfo,
                          uchar *key, my_off_t split_page, uchar *split_buff,
                          uint org_split_length,
                          uchar *inserted_key_pos, uint changed_length,
                          int move_length,
                          uchar *key_buff, my_bool insert_last_key);
759 760
extern uchar *_ma_find_half_pos(MARIA_HA *info, uint nod_flag,
                                MARIA_KEYDEF *keyinfo,
unknown's avatar
unknown committed
761
                                uchar *page, uchar *key,
762
                                uint *return_key_length,
unknown's avatar
unknown committed
763
                                uchar ** after_key);
764
extern int _ma_calc_static_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
unknown's avatar
unknown committed
765 766
                                      uchar *key_pos, uchar *org_key,
                                      uchar *key_buff, const uchar *key,
767 768
                                      MARIA_KEY_PARAM *s_temp);
extern int _ma_calc_var_key_length(MARIA_KEYDEF *keyinfo, uint nod_flag,
unknown's avatar
unknown committed
769 770
                                   uchar *key_pos, uchar *org_key,
                                   uchar *key_buff, const uchar *key,
771 772
                                   MARIA_KEY_PARAM *s_temp);
extern int _ma_calc_var_pack_key_length(MARIA_KEYDEF *keyinfo,
unknown's avatar
unknown committed
773 774 775
                                        uint nod_flag, uchar *key_pos,
                                        uchar *org_key, uchar *prev_key,
                                        const uchar *key,
776 777
                                        MARIA_KEY_PARAM *s_temp);
extern int _ma_calc_bin_pack_key_length(MARIA_KEYDEF *keyinfo,
unknown's avatar
unknown committed
778 779 780
                                        uint nod_flag, uchar *key_pos,
                                        uchar *org_key, uchar *prev_key,
                                        const uchar *key,
781
                                        MARIA_KEY_PARAM *s_temp);
782 783 784 785
extern void _ma_store_static_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
                                 MARIA_KEY_PARAM *s_temp);
extern void _ma_store_var_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
                                   MARIA_KEY_PARAM *s_temp);
786
#ifdef NOT_USED
787 788
extern void _ma_store_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
                               MARIA_KEY_PARAM *s_temp);
789
#endif
790 791
extern void _ma_store_bin_pack_key(MARIA_KEYDEF *keyinfo, uchar *key_pos,
                                   MARIA_KEY_PARAM *s_temp);
792

unknown's avatar
unknown committed
793
extern int _ma_ck_delete(MARIA_HA *info, uint keynr, uchar *key,
794
                         uint key_length);
795 796 797
extern int _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEYDEF *keyinfo,
                              uchar *key, uint key_length,
                              my_off_t *root);
798 799 800 801 802 803
extern int _ma_readinfo(MARIA_HA *info, int lock_flag, int check_keybuffer);
extern int _ma_writeinfo(MARIA_HA *info, uint options);
extern int _ma_test_if_changed(MARIA_HA *info);
extern int _ma_mark_file_changed(MARIA_HA *info);
extern int _ma_decrement_open_count(MARIA_HA *info);
extern int _ma_check_index(MARIA_HA *info, int inx);
unknown's avatar
unknown committed
804
extern int _ma_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo, uchar *key,
805
                      uint key_len, uint nextflag, my_off_t pos);
806
extern int _ma_bin_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
807
                          uchar *page, const uchar *key, uint key_len,
unknown's avatar
unknown committed
808
                          uint comp_flag, uchar **ret_pos, uchar *buff,
809 810
                          my_bool *was_last_key);
extern int _ma_seq_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
811
                          uchar *page, const uchar *key, uint key_len,
unknown's avatar
unknown committed
812
                          uint comp_flag, uchar ** ret_pos, uchar *buff,
813 814
                          my_bool *was_last_key);
extern int _ma_prefix_search(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
815
                             uchar *page, const uchar *key, uint key_len,
unknown's avatar
unknown committed
816
                             uint comp_flag, uchar ** ret_pos, uchar *buff,
817
                             my_bool *was_last_key);
unknown's avatar
unknown committed
818 819
extern my_off_t _ma_kpos(uint nod_flag, uchar *after_key);
extern void _ma_kpointer(MARIA_HA *info, uchar *buff, my_off_t pos);
unknown's avatar
unknown committed
820
extern MARIA_RECORD_POS _ma_dpos(MARIA_HA *info, uint nod_flag,
unknown's avatar
unknown committed
821
                                 const uchar *after_key);
822
extern MARIA_RECORD_POS _ma_rec_pos(MARIA_HA *info, uchar *ptr);
unknown's avatar
unknown committed
823
extern void _ma_dpointer(MARIA_HA *info, uchar *buff, MARIA_RECORD_POS pos);
824
extern uint _ma_get_static_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
unknown's avatar
unknown committed
825
                               uchar **page, uchar *key);
826
extern uint _ma_get_pack_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
unknown's avatar
unknown committed
827
                             uchar **page, uchar *key);
828
extern uint _ma_get_binary_pack_key(MARIA_KEYDEF *keyinfo, uint nod_flag,
unknown's avatar
unknown committed
829 830 831 832 833 834
                                    uchar ** page_pos, uchar *key);
extern uchar *_ma_get_last_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
                               uchar *keypos, uchar *lastkey,
                               uchar *endpos, uint *return_key_length);
extern uchar *_ma_get_key(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
                          uchar *page, uchar *key, uchar *keypos,
835
                          uint *return_key_length);
unknown's avatar
unknown committed
836 837
extern uint _ma_keylength(MARIA_KEYDEF *keyinfo, const uchar *key);
extern uint _ma_keylength_part(MARIA_KEYDEF *keyinfo, register const uchar *key,
838
                               HA_KEYSEG *end);
unknown's avatar
unknown committed
839
extern uchar *_ma_move_key(MARIA_KEYDEF *keyinfo, uchar *to, const uchar *from);
840
extern int _ma_search_next(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
unknown's avatar
unknown committed
841
                           uchar *key, uint key_length, uint nextflag,
842 843 844 845 846
                           my_off_t pos);
extern int _ma_search_first(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
                            my_off_t pos);
extern int _ma_search_last(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
                           my_off_t pos);
847 848 849 850 851 852
extern my_off_t _ma_static_keypos_to_recpos(MARIA_HA *info, my_off_t pos);
extern my_off_t _ma_static_recpos_to_keypos(MARIA_HA *info, my_off_t pos);
extern my_off_t _ma_transparent_recpos(MARIA_HA *info, my_off_t pos);
extern my_off_t _ma_transaction_keypos_to_recpos(MARIA_HA *info, my_off_t pos);
extern my_off_t _ma_transaction_recpos_to_keypos(MARIA_HA *info, my_off_t pos);

unknown's avatar
unknown committed
853
extern uchar *_ma_fetch_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
854 855 856
                                my_off_t page, enum pagecache_page_lock lock,
                                int level, uchar *buff, int return_buffer,
                                MARIA_PINNED_PAGE **page_link);
857
extern int _ma_write_keypage(MARIA_HA *info, MARIA_KEYDEF *keyinfo,
858 859 860 861 862
                             my_off_t page, enum pagecache_page_lock lock,
                             int level, uchar *buff);
extern int _ma_dispose(MARIA_HA *info, my_off_t pos, my_bool page_not_read);
extern my_off_t _ma_new(register MARIA_HA *info, int level,
                        MARIA_PINNED_PAGE **page_link);
unknown's avatar
unknown committed
863 864 865
extern uint _ma_make_key(MARIA_HA *info, uint keynr, uchar *key,
                         const uchar *record, MARIA_RECORD_POS filepos);
extern uint _ma_pack_key(MARIA_HA *info, uint keynr, uchar *key,
866
                         const uchar *old, key_part_map keypart_map,
867
                         HA_KEYSEG ** last_used_keyseg);
unknown's avatar
unknown committed
868 869
extern int _ma_read_key_record(MARIA_HA *info, uchar *buf, MARIA_RECORD_POS);
extern int _ma_read_cache(IO_CACHE *info, uchar *buff, MARIA_RECORD_POS pos,
870
                          uint length, int re_read_if_possibly);
871
extern ulonglong ma_retrieve_auto_increment(const uchar *key, uint8 key_type);
unknown's avatar
unknown committed
872 873 874
extern my_bool _ma_alloc_buffer(uchar **old_addr, size_t *old_size,
                                size_t new_size);
extern ulong _ma_rec_unpack(MARIA_HA *info, uchar *to, uchar *from,
875
                            ulong reclength);
876
extern my_bool _ma_rec_check(MARIA_HA *info, const uchar *record,
unknown's avatar
unknown committed
877
                             uchar *packpos, ulong packed_length,
878
                             my_bool with_checkum, ha_checksum checksum);
879 880
extern int _ma_write_part_record(MARIA_HA *info, my_off_t filepos,
                                 ulong length, my_off_t next_filepos,
unknown's avatar
unknown committed
881
                                 uchar ** record, ulong *reclength,
882 883
                                 int *flag);
extern void _ma_print_key(FILE *stream, HA_KEYSEG *keyseg,
unknown's avatar
unknown committed
884
                          const uchar *key, uint length);
unknown's avatar
unknown committed
885 886
extern my_bool _ma_once_init_pack_row(MARIA_SHARE *share, File dfile);
extern my_bool _ma_once_end_pack_row(MARIA_SHARE *share);
unknown's avatar
unknown committed
887
extern int _ma_read_pack_record(MARIA_HA *info, uchar *buf,
unknown's avatar
unknown committed
888
                                MARIA_RECORD_POS filepos);
unknown's avatar
unknown committed
889
extern int _ma_read_rnd_pack_record(MARIA_HA *, uchar *, MARIA_RECORD_POS,
unknown's avatar
unknown committed
890
                                    my_bool);
891
extern int _ma_pack_rec_unpack(MARIA_HA *info, MARIA_BIT_BUFF *bit_buff,
unknown's avatar
unknown committed
892
                               uchar *to, uchar *from, ulong reclength);
893
extern ulonglong _ma_safe_mul(ulonglong a, ulonglong b);
unknown's avatar
unknown committed
894 895
extern int _ma_ft_update(MARIA_HA *info, uint keynr, uchar *keybuf,
                         const uchar *oldrec, const uchar *newrec,
896 897
                         my_off_t pos);

898 899 900 901 902
/*
  Parameter to _ma_get_block_info
  The dynamic row header is read into this struct. For an explanation of
  the fields, look at the function _ma_get_block_info().
*/
903 904 905 906 907 908 909 910

typedef struct st_maria_block_info
{
  uchar header[MARIA_BLOCK_INFO_HEADER_LENGTH];
  ulong rec_len;
  ulong data_len;
  ulong block_len;
  ulong blob_len;
unknown's avatar
unknown committed
911 912 913
  MARIA_RECORD_POS filepos;
  MARIA_RECORD_POS next_filepos;
  MARIA_RECORD_POS prev_filepos;
914 915 916 917
  uint second_read;
  uint offset;
} MARIA_BLOCK_INFO;

918

919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
/* bits in return from _ma_get_block_info */

#define BLOCK_FIRST	1
#define BLOCK_LAST	2
#define BLOCK_DELETED	4
#define BLOCK_ERROR	8			/* Wrong data */
#define BLOCK_SYNC_ERROR 16			/* Right data at wrong place */
#define BLOCK_FATAL_ERROR 32			/* hardware-error */

#define NEED_MEM	((uint) 10*4*(IO_SIZE+32)+32) /* Nead for recursion */
#define MAXERR			20
#define BUFFERS_WHEN_SORTING	16		/* Alloc for sort-key-tree */
#define WRITE_COUNT		MY_HOW_OFTEN_TO_WRITE
#define INDEX_TMP_EXT		".TMM"
#define DATA_TMP_EXT		".TMD"

#define UPDATE_TIME		1
#define UPDATE_STAT		2
#define UPDATE_SORT		4
#define UPDATE_AUTO_INC		8
#define UPDATE_OPEN_COUNT	16

941
#define USE_BUFFER_INIT		(((1024L*1024L*10-MALLOC_OVERHEAD)/8192)*8192)
942 943 944 945 946 947 948 949
#define READ_BUFFER_INIT	(1024L*256L-MALLOC_OVERHEAD)
#define SORT_BUFFER_INIT	(2048L*1024L-MALLOC_OVERHEAD)
#define MIN_SORT_BUFFER		(4096-MALLOC_OVERHEAD)

#define fast_ma_writeinfo(INFO) if (!(INFO)->s->tot_locks) (void) _ma_writeinfo((INFO),0)
#define fast_ma_readinfo(INFO) ((INFO)->lock_type == F_UNLCK) && _ma_readinfo((INFO),F_RDLCK,1)

extern uint _ma_get_block_info(MARIA_BLOCK_INFO *, File, my_off_t);
unknown's avatar
unknown committed
950
extern uint _ma_rec_pack(MARIA_HA *info, uchar *to, const uchar *from);
951
extern uint _ma_pack_get_block_info(MARIA_HA *maria, MARIA_BIT_BUFF *bit_buff,
unknown's avatar
unknown committed
952 953
                                    MARIA_BLOCK_INFO *info, uchar **rec_buff_p,
                                    size_t *rec_buff_size,
954
                                    File file, my_off_t filepos);
unknown's avatar
unknown committed
955
extern void _ma_store_blob_length(uchar *pos, uint pack_length, uint length);
956 957 958
extern void _ma_report_error(int errcode, const char *file_name);
extern my_bool _ma_memmap_file(MARIA_HA *info);
extern void _ma_unmap_file(MARIA_HA *info);
unknown's avatar
unknown committed
959
extern uint _ma_save_pack_length(uint version, uchar * block_buff,
960 961
                                 ulong length);
extern uint _ma_calc_pack_length(uint version, ulong length);
unknown's avatar
unknown committed
962
extern ulong _ma_calc_blob_length(uint length, const uchar *pos);
963 964 965 966 967 968 969 970
extern size_t _ma_mmap_pread(MARIA_HA *info, uchar *Buffer,
			     size_t Count, my_off_t offset, myf MyFlags);
extern size_t _ma_mmap_pwrite(MARIA_HA *info, const uchar *Buffer,
			      size_t Count, my_off_t offset, myf MyFlags);
extern size_t _ma_nommap_pread(MARIA_HA *info, uchar *Buffer,
			       size_t Count, my_off_t offset, myf MyFlags);
extern size_t _ma_nommap_pwrite(MARIA_HA *info, const uchar *Buffer,
				size_t Count, my_off_t offset, myf MyFlags);
971

unknown's avatar
unknown committed
972 973
uint _ma_state_info_write(MARIA_SHARE *share, uint pWrite);
uint _ma_state_info_write_sub(File file, MARIA_STATE_INFO *state, uint pWrite);
974
uint _ma_state_info_read_dsk(File file, MARIA_STATE_INFO *state);
975
uint _ma_base_info_write(File file, MARIA_BASE_INFO *base);
976
my_bool _ma_keyseg_write(File file, const HA_KEYSEG *keyseg);
977
uchar *_ma_keyseg_read(uchar *ptr, HA_KEYSEG *keyseg);
978
my_bool _ma_keydef_write(File file, MARIA_KEYDEF *keydef);
979
uchar *_ma_keydef_read(uchar *ptr, MARIA_KEYDEF *keydef);
980
my_bool _ma_uniquedef_write(File file, MARIA_UNIQUEDEF *keydef);
981
uchar *_ma_uniquedef_read(uchar *ptr, MARIA_UNIQUEDEF *keydef);
982
my_bool _ma_columndef_write(File file, MARIA_COLUMNDEF *columndef);
983
uchar *_ma_columndef_read(uchar *ptr, MARIA_COLUMNDEF *columndef);
984 985
my_bool _ma_column_nr_write(File file, uint16 *offsets, uint columns);
uchar *_ma_column_nr_read(uchar *ptr, uint16 *offsets, uint columns);
unknown's avatar
unknown committed
986 987 988
ulong _ma_calc_total_blob_length(MARIA_HA *info, const uchar *record);
ha_checksum _ma_checksum(MARIA_HA *info, const uchar *buf);
ha_checksum _ma_static_checksum(MARIA_HA *info, const uchar *buf);
989
my_bool _ma_check_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
unknown's avatar
unknown committed
990
                         uchar *record, ha_checksum unique_hash,
unknown's avatar
unknown committed
991
                         MARIA_RECORD_POS pos);
unknown's avatar
unknown committed
992
ha_checksum _ma_unique_hash(MARIA_UNIQUEDEF *def, const uchar *buf);
unknown's avatar
unknown committed
993
my_bool _ma_cmp_static_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
unknown's avatar
unknown committed
994
                              const uchar *record, MARIA_RECORD_POS pos);
unknown's avatar
unknown committed
995
my_bool _ma_cmp_dynamic_unique(MARIA_HA *info, MARIA_UNIQUEDEF *def,
unknown's avatar
unknown committed
996 997
                               const uchar *record, MARIA_RECORD_POS pos);
my_bool _ma_unique_comp(MARIA_UNIQUEDEF *def, const uchar *a, const uchar *b,
unknown's avatar
unknown committed
998
                        my_bool null_are_equal);
999 1000
void _ma_get_status(void *param, int concurrent_insert);
void _ma_update_status(void *param);
1001
void _ma_restore_status(void *param);
1002 1003
void _ma_copy_status(void *to, void *from);
my_bool _ma_check_status(void *param);
1004
void _ma_reset_status(MARIA_HA *maria);
1005 1006 1007
int _ma_def_scan_remember_pos(MARIA_HA *info, MARIA_RECORD_POS *lastpos);
void _ma_def_scan_restore_pos(MARIA_HA *info, MARIA_RECORD_POS lastpos);

unknown's avatar
unknown committed
1008
#include "ma_commit.h"
1009

1010
extern MARIA_HA *_ma_test_if_reopen(const char *filename);
1011 1012 1013 1014 1015 1016 1017
my_bool _ma_check_table_is_closed(const char *name, const char *where);
int _ma_open_datafile(MARIA_HA *info, MARIA_SHARE *share, File file_to_dup);
int _ma_open_keyfile(MARIA_SHARE *share);
void _ma_setup_functions(register MARIA_SHARE *share);
my_bool _ma_dynmap_file(MARIA_HA *info, my_off_t size);
void _ma_remap_file(MARIA_HA *info, my_off_t size);

unknown's avatar
unknown committed
1018
MARIA_RECORD_POS _ma_write_init_default(MARIA_HA *info, const uchar *record);
unknown's avatar
unknown committed
1019 1020
my_bool _ma_write_abort_default(MARIA_HA *info);

1021
C_MODE_START
unknown's avatar
unknown committed
1022 1023 1024 1025 1026
#define MARIA_FLUSH_DATA  1
#define MARIA_FLUSH_INDEX 2
int _ma_flush_table_files(MARIA_HA *info, uint flush_data_or_index,
                          enum flush_type flush_type_for_data,
                          enum flush_type flush_type_for_index);
unknown's avatar
unknown committed
1027 1028 1029 1030
/*
  Functions needed by _ma_check (are overridden in MySQL/ha_maria.cc).
  See ma_check_standalone.h .
*/
1031
volatile int *_ma_killed_ptr(HA_CHECK *param);
1032 1033 1034 1035 1036 1037
void _ma_check_print_error _VARARGS((HA_CHECK *param, const char *fmt, ...))
  ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_warning _VARARGS((HA_CHECK *param, const char *fmt, ...))
  ATTRIBUTE_FORMAT(printf, 2, 3);
void _ma_check_print_info _VARARGS((HA_CHECK *param, const char *fmt, ...))
  ATTRIBUTE_FORMAT(printf, 2, 3);
1038 1039 1040 1041 1042 1043 1044 1045
C_MODE_END

int _ma_flush_pending_blocks(MARIA_SORT_PARAM *param);
int _ma_sort_ft_buf_flush(MARIA_SORT_PARAM *sort_param);
int _ma_thr_write_keys(MARIA_SORT_PARAM *sort_param);
#ifdef THREAD
pthread_handler_t _ma_thr_find_all_keys(void *arg);
#endif
unknown's avatar
unknown committed
1046
int _ma_flush_table_files_after_repair(HA_CHECK *param, MARIA_HA *info);
1047 1048 1049

int _ma_sort_write_record(MARIA_SORT_PARAM *sort_param);
int _ma_create_index_by_sort(MARIA_SORT_PARAM *info, my_bool no_messages,
1050
                             size_t);
1051
int _ma_sync_table_files(const MARIA_HA *info);
1052
int _ma_initialize_data_file(MARIA_SHARE *share, File dfile);
unknown's avatar
unknown committed
1053 1054 1055 1056
int _ma_update_create_rename_lsn(MARIA_SHARE *share,
                                 LSN lsn, my_bool do_sync);
int _ma_update_create_rename_lsn_sub(MARIA_SHARE *share,
                                     LSN lsn, my_bool do_sync);
1057

unknown's avatar
unknown committed
1058 1059
void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
                                       my_bool log_incomplete);
unknown's avatar
unknown committed
1060 1061 1062
#define _ma_reenable_logging_for_table(S)                        \
  { if (((S)->now_transactional= (S)->base.born_transactional))  \
      (S)->page_type= PAGECACHE_LSN_PAGE; }
1063

unknown's avatar
unknown committed
1064 1065 1066 1067
#define MARIA_NO_CRC_NORMAL_PAGE 0xffffffff
#define MARIA_NO_CRC_BITMAP_PAGE 0xfffffffe
extern my_bool maria_page_crc_set_index(uchar *page,
                                        pgcache_page_no_t page_no,
1068
                                        uchar *data_ptr);
unknown's avatar
unknown committed
1069 1070
extern my_bool maria_page_crc_set_normal(uchar *page,
                                         pgcache_page_no_t page_no,
1071
                                         uchar *data_ptr);
unknown's avatar
unknown committed
1072 1073
extern my_bool maria_page_crc_check_bitmap(uchar *page,
                                           pgcache_page_no_t page_no,
1074
                                           uchar *data_ptr);
unknown's avatar
unknown committed
1075 1076
extern my_bool maria_page_crc_check_data(uchar *page,
                                           pgcache_page_no_t page_no,
1077
                                           uchar *data_ptr);
unknown's avatar
unknown committed
1078 1079
extern my_bool maria_page_crc_check_index(uchar *page,
                                           pgcache_page_no_t page_no,
1080 1081 1082 1083
                                           uchar *data_ptr);
extern my_bool maria_page_crc_check_none(uchar *page,
                                         pgcache_page_no_t page_no,
                                         uchar *data_ptr);
unknown's avatar
unknown committed
1084 1085
extern my_bool maria_page_filler_set_bitmap(uchar *page,
                                            pgcache_page_no_t page_no,
1086
                                            uchar *data_ptr);
unknown's avatar
unknown committed
1087 1088
extern my_bool maria_page_filler_set_normal(uchar *page,
                                            pgcache_page_no_t page_no,
1089 1090 1091 1092
                                            uchar *data_ptr);
extern my_bool maria_page_filler_set_none(uchar *page,
                                          pgcache_page_no_t page_no,
                                          uchar *data_ptr);
unknown's avatar
unknown committed
1093 1094
extern void maria_page_write_failure(uchar* data_ptr);

1095
extern PAGECACHE *maria_log_pagecache;