1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 - 2010 Toru Maesaka
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef PLUGIN_BLITZDB_HA_BLITZ_H
21
#define PLUGIN_BLITZDB_HA_BLITZ_H
23
#include "drizzled/session.h"
24
#include "drizzled/cursor.h"
25
#include "drizzled/table.h"
26
#include "drizzled/field.h"
27
#include "drizzled/field/blob.h"
28
#include "drizzled/atomics.h"
29
#include "drizzled/error.h"
30
#include "drizzled/gettext.h"
31
#include "drizzled/cached_directory.h"
32
#include "drizzled/internal/my_sys.h"
40
#define BLITZ_DATA_EXT ".bzd"
41
#define BLITZ_INDEX_EXT ".bzx"
42
#define BLITZ_SYSTEM_EXT ".bzs"
44
/* Constants for BlitzDB */
45
#define BLITZ_LOCK_SLOTS 16
46
#define BLITZ_MAX_INDEX 8
47
#define BLITZ_MAX_META_LEN 128
48
#define BLITZ_MAX_ROW_STACK 2048
49
#define BLITZ_MAX_KEY_LEN 1024
50
#define BLITZ_WORST_CASE_RANGE 4
52
/* Constants for TC */
53
#define BLITZ_TC_EXTRA_MMAP_SIZE (1024 * 1024 * 256)
54
#define BLITZ_TC_BUCKETS 1000000
56
const std::string BLITZ_TABLE_PROTO_KEY = "table_definition";
57
const std::string BLITZ_TABLE_PROTO_COMMENT_KEY = "table_definition_comment";
59
extern uint64_t blitz_estimated_rows;
69
/* Multi Reader-Writer lock responsible for controlling concurrency
70
at the handler level. This class is implemented in blitzlock.cc */
75
pthread_cond_t condition;
76
pthread_mutex_t mutex;
77
pthread_mutex_t slots[BLITZ_LOCK_SLOTS];
83
/* Slotted Lock Mechanism for Concurrently and Atomically
84
updating the index and data dictionary at the same time. */
85
uint32_t slot_id(const void *data, size_t len);
86
int slotted_lock(const uint32_t slot_id);
87
int slotted_unlock(const uint32_t slot_id);
89
/* Multi Reader-Writer Lock Mechanism. */
94
void scan_update_begin();
95
void scan_update_end();
98
/* Handler that takes care of all I/O to the data dictionary
99
that holds actual rows. */
102
TCHDB *data_table; /* Where the actual row data lives */
103
TCHDB *system_table; /* Keeps track of system info */
104
char *tc_meta_buffer; /* Tokyo Cabinet's Persistent Meta Buffer */
105
drizzled::atomic<uint64_t> current_hidden_row_id;
108
BlitzData() : data_table(NULL), system_table(NULL), tc_meta_buffer(NULL) {
109
current_hidden_row_id = 0;
112
int startup(const char *table_path);
115
/* DATA DICTIONARY CREATION RELATED */
116
int create_data_table(drizzled::message::Table &proto,
117
drizzled::Table &table,
118
const drizzled::identifier::Table &identifier);
120
int open_data_table(const char *path, const int mode);
121
int close_data_table(void);
122
bool rename_table(const char *from, const char *to);
124
/* DATA DICTIONARY METADATA RELATED */
125
uint64_t nrecords(void);
126
uint64_t table_size(void);
127
uint64_t read_meta_row_id(void);
128
uint64_t read_meta_autoinc(void);
129
uint32_t read_meta_keycount(void);
130
void write_meta_row_id(uint64_t row_id);
131
void write_meta_autoinc(uint64_t num);
132
void write_meta_keycount(uint32_t nkeys);
134
/* DATA DICTIONARY READ RELATED*/
135
char *get_row(const char *key, const size_t klen, int *value_len);
136
char *next_key_and_row(const char *key, const size_t klen,
137
int *next_key_len, const char **value,
139
char *first_row(int *row_len);
141
/* DATA DICTIONARY WRITE RELATED */
142
uint64_t next_hidden_row_id(void);
143
int write_row(const char *key, const size_t klen,
144
const unsigned char *row, const size_t rlen);
145
int write_unique_row(const char *key, const size_t klen,
146
const unsigned char *row, const size_t rlen);
147
int delete_row(const char *key, const size_t klen);
148
bool delete_all_rows(void);
150
/* SYSTEM TABLE RELATED */
151
int create_system_table(const std::string &path);
152
int open_system_table(const std::string &path, const int mode);
153
int close_system_table(void);
154
bool write_table_definition(drizzled::message::Table &proto);
155
char *get_system_entry(const char *key, const size_t klen, int *vlen);
158
/* This class is only used by the BlitzTree object which has a long life
159
span. In general we use the Cursor's local KeyPartInfo array for
160
obtaining key information. We create our own array of key information
161
because there is no guarantee that the pointer to the internal key_info
162
array will always be alive. */
165
BlitzKeyPart() : offset(0), null_pos(0), flag(0), length(0), type(0),
169
uint32_t offset; /* Offset of the key in the row */
170
uint32_t null_pos; /* Offset of the NULL indicator in the row */
172
uint16_t length; /* Length of the key */
173
uint8_t type; /* Type of the key */
174
uint8_t null_bitmask; /* Bitmask to test for NULL */
179
BlitzCursor() : tree(NULL), cursor(NULL), moved(false),
183
BlitzTree *tree; /* Tree that this instance works on */
184
BDBCUR *cursor; /* Raw cursor to TC */
185
bool moved; /* Whether the key was implicitly moved */
186
bool active; /* Whether this cursor is active */
188
/* B+TREE READ RELATED */
189
char *first_key(int *key_len);
190
char *final_key(int *key_len);
191
char *next_key(int *key_len);
192
char *prev_key(int *key_ken);
193
char *next_logical_key(int *key_len);
194
char *prev_logical_key(int *key_len);
196
char *find_key(const int search_mode, const char *key,
197
const int klen, int *rv_len);
199
/* B+TREE UPDATE RELATED */
200
int delete_position(void);
203
/* Class that reprensents a BTREE index. Takes care of all I/O
204
to the B+Tree index structure */
210
BlitzTree() : length(0), nparts(0), type(0), unique(false) {}
214
BlitzKeyPart *parts; /* Array of Key Part(s) */
215
int length; /* Length of the entire key */
216
int nparts; /* Number of parts in this key */
217
int type; /* Type of the key */
218
bool unique; /* Whether this key is unique */
220
/* BTREE INDEX CREATION RELATED */
221
int open(const char *path, const int key_num, int mode);
222
int create(const char *path, const int key_num);
223
int drop(const char *path, const int key_num);
224
int rename(const char *from, const char *to, const int key_num);
228
bool create_cursor(BlitzCursor *cursor);
229
void destroy_cursor(BlitzCursor *cursor);
231
/* BTREE INDEX WRITE RELATED */
232
int write(const char *key, const size_t klen);
233
int write_unique(const char *key, const size_t klen);
234
int delete_key(const char *key, const int klen);
235
int delete_all(void);
237
/* BTREE METADATA RELATED */
238
uint64_t records(void);
241
/* Callback function for TC's B+Tree key comparison. */
242
extern int blitz_keycmp_cb(const char *a, int alen,
243
const char *b, int blen, void *opaque);
244
/* Comparison function for Drizzle types. */
245
extern int packed_key_cmp(BlitzTree *, const char *a, const char *b,
246
int *a_real_len, int *b_real_len);
248
/* Object shared among all worker threads. Try to only add
249
data that will not be updated at runtime or those that
250
do not require locking. */
253
BlitzShare() : blitz_lock(), use_count(0), nkeys(0) {}
256
drizzled::atomic<uint64_t> auto_increment_value;
258
BlitzLock blitz_lock; /* Handler level lock for BlitzDB */
259
BlitzData dict; /* Utility class of BlitzDB */
260
BlitzTree *btrees; /* Array of BTREE indexes */
261
std::string table_name; /* Name and Length of the table */
262
uint32_t use_count; /* Reference counter of this object */
263
uint32_t nkeys; /* Number of indexes in this table */
264
bool fixed_length_table; /* Whether the table is fixed length */
265
bool primary_key_exists; /* Whether a PK exists in this table */
268
class ha_blitz: public drizzled::Cursor {
270
BlitzShare *share; /* Shared object among all threads */
271
BlitzCursor *btree_cursor; /* Array of B+Tree Cursor */
272
drizzled::THR_LOCK_DATA lock; /* Drizzle Lock */
275
bool table_scan; /* Whether a table scan is occuring */
276
bool table_based; /* Whether the query involves rnd_xxx() */
277
bool thread_locked; /* Whether the thread is locked */
278
uint32_t sql_command_type; /* Type of SQL command to process */
280
/* RECORDED KEY IN TABLE OR INDEX READ */
281
char *held_key; /* Points to held_key_buf or an allocated key */
282
char *held_key_buf; /* Buffer used to copy an unallocated key */
283
int held_key_len; /* Length of the key being held */
285
/* TABLE SCANNER VARIABLES */
286
char *current_key; /* Current key in table scan */
287
const char *current_row; /* Current row in table scan */
288
int current_key_len; /* Length of the current key */
289
int current_row_len; /* Length of the current row */
291
/* KEY PROCESSING BUFFERS */
292
char *key_buffer; /* Key generation buffer */
293
char *key_merge_buffer; /* Key Merge buffer for B+Tree */
294
size_t key_merge_buffer_len; /* Size of the merge buffer */
296
/* ROW PROCESSING VARIABLES */
297
unsigned char pack_buffer[BLITZ_MAX_ROW_STACK]; /* Pack Buffer */
298
unsigned char *secondary_row_buffer; /* For big rows */
299
size_t secondary_row_buffer_size; /* Reserved buffer size */
303
ha_blitz(drizzled::plugin::StorageEngine &engine_arg,
304
drizzled::Table &table_arg);
307
/* TABLE CONTROL RELATED FUNCTIONS */
308
const char **bas_ext() const;
309
const char *index_type(uint32_t key_num);
310
int open(const char *name, int mode, uint32_t open_options);
312
int info(uint32_t flag);
314
/* TABLE SCANNER RELATED FUNCTIONS */
315
int doStartTableScan(bool scan);
316
int rnd_next(unsigned char *buf);
317
int doEndTableScan(void);
318
int rnd_pos(unsigned char *buf, unsigned char *pos);
320
void position(const unsigned char *record);
322
/* INDEX RELATED FUNCTIONS */
323
int doStartIndexScan(uint32_t key_num, bool sorted);
324
int index_first(unsigned char *buf);
325
int index_next(unsigned char *buf);
326
int index_prev(unsigned char *buf);
327
int index_last(unsigned char *buf);
328
int index_read(unsigned char *buf, const unsigned char *key,
329
uint32_t key_len, enum drizzled::ha_rkey_function find_flag);
330
int index_read_idx(unsigned char *buf, uint32_t key_num,
331
const unsigned char *key, uint32_t key_len,
332
enum drizzled::ha_rkey_function find_flag);
333
int doEndIndexScan(void);
334
int enable_indexes(uint32_t mode); /* For ALTER ... ENABLE KEYS */
335
int disable_indexes(uint32_t mode); /* For ALTER ... DISABLE KEYS */
337
drizzled::ha_rows records_in_range(uint32_t key_num,
338
drizzled::key_range *min_key,
339
drizzled::key_range *max_key);
341
/* UPDATE RELATED FUNCTIONS */
342
int doInsertRecord(unsigned char *buf);
343
int doUpdateRecord(const unsigned char *old_data, unsigned char *new_data);
344
int doDeleteRecord(const unsigned char *buf);
345
int delete_all_rows(void);
346
virtual void get_auto_increment(uint64_t offset, uint64_t increment,
347
uint64_t nb_desired_values,
348
uint64_t *first_value,
349
uint64_t *nb_reserved_values);
350
int reset_auto_increment(uint64_t value);
352
/* UTILITY FUNCTIONS (BLITZDB SPECIFIC) */
353
BlitzShare *get_share(const char *table_name);
354
int free_share(void);
356
/* LOCK RELATED FUNCTIONS (BLITZDB SPECIFIC) */
357
int blitz_optimal_lock();
358
int blitz_optimal_unlock();
359
uint32_t max_row_length(void);
361
/* INDEX KEY RELATED FUNCTIONS (BLITZDB SPECIFIC) */
362
size_t make_primary_key(char *pack_to, const unsigned char *row);
363
size_t make_index_key(char *pack_to, int key_num, const unsigned char *row);
364
size_t btree_key_length(const char *key, const int key_num);
365
char *native_to_blitz_key(const unsigned char *native_key,
366
const int key_num, int *return_key_length);
367
char *merge_key(const char *a, const size_t a_len, const char *b,
368
const size_t b_len, size_t *merged_len);
369
void keep_track_of_key(const char *key, const int klen);
371
/* ROW RELATED FUNCTIONS (BLITZDB SPECIFIC) */
372
size_t pack_row(unsigned char *row_buffer, unsigned char *row_to_pack);
373
bool unpack_row(unsigned char *to, const char *from, const size_t from_len);
374
unsigned char *get_pack_buffer(const size_t size);
376
/* COMAPARISON LOGIC (BLITZDB SPECIFIC) */
377
int compare_rows_for_unique_violation(const unsigned char *old_row,
378
const unsigned char *new_row);
381
#endif /* PLUGIN_BLITZDB_HA_BLITZ_H */