~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/blitzdb/ha_blitz.h

Updated pandora-build files to version 0.133

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2009 - 2010 Toru Maesaka
5
 
 *
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.
9
 
 *
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.
14
 
 *
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
18
 
 */
19
 
 
20
 
#ifndef PLUGIN_BLITZDB_HA_BLITZ_H
21
 
#define PLUGIN_BLITZDB_HA_BLITZ_H
22
 
 
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"
33
 
#include <tchdb.h>
34
 
#include <tcbdb.h>
35
 
 
36
 
#include <string>
37
 
#include <sys/stat.h>
38
 
 
39
 
/* File Extensions */
40
 
#define BLITZ_DATA_EXT         ".bzd"
41
 
#define BLITZ_INDEX_EXT        ".bzx"
42
 
#define BLITZ_SYSTEM_EXT       ".bzs"
43
 
 
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
51
 
 
52
 
/* Constants for TC */
53
 
#define BLITZ_TC_EXTRA_MMAP_SIZE (1024 * 1024 * 256)
54
 
#define BLITZ_TC_BUCKETS 1000000
55
 
 
56
 
const std::string BLITZ_TABLE_PROTO_KEY = "table_definition";
57
 
const std::string BLITZ_TABLE_PROTO_COMMENT_KEY = "table_definition_comment";
58
 
 
59
 
extern uint64_t blitz_estimated_rows;
60
 
 
61
 
/* Class Prototype */
62
 
class BlitzLock;
63
 
class BlitzData;
64
 
class BlitzKeyPart;
65
 
class BlitzCursor;
66
 
class BlitzTree;
67
 
class BlitzShare;
68
 
 
69
 
/* Multi Reader-Writer lock responsible for controlling concurrency
70
 
   at the handler level. This class is implemented in blitzlock.cc */
71
 
class BlitzLock {
72
 
private:
73
 
  int scanner_count;
74
 
  int updater_count;
75
 
  pthread_cond_t condition;
76
 
  pthread_mutex_t mutex;
77
 
  pthread_mutex_t slots[BLITZ_LOCK_SLOTS];
78
 
 
79
 
public:
80
 
  BlitzLock();
81
 
  ~BlitzLock();
82
 
 
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);
88
 
 
89
 
  /* Multi Reader-Writer Lock Mechanism. */
90
 
  void update_begin();
91
 
  void update_end();
92
 
  void scan_begin();
93
 
  void scan_end();
94
 
  void scan_update_begin();
95
 
  void scan_update_end();
96
 
};
97
 
 
98
 
/* Handler that takes care of all I/O to the data dictionary
99
 
   that holds actual rows. */
100
 
class BlitzData {
101
 
private:
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;
106
 
 
107
 
public:
108
 
  BlitzData() : data_table(NULL), system_table(NULL), tc_meta_buffer(NULL) {
109
 
    current_hidden_row_id = 0;
110
 
  }
111
 
  ~BlitzData() {}
112
 
  int startup(const char *table_path);
113
 
  int shutdown(void);
114
 
 
115
 
  /* DATA DICTIONARY CREATION RELATED */
116
 
  int create_data_table(drizzled::message::Table &proto,
117
 
                        drizzled::Table &table,
118
 
                        const drizzled::identifier::Table &identifier);
119
 
 
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);
123
 
 
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);
133
 
 
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,
138
 
                         int *value_len);
139
 
  char *first_row(int *row_len);
140
 
 
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);
149
 
 
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);
156
 
};
157
 
 
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. */
163
 
class BlitzKeyPart {
164
 
public:
165
 
  BlitzKeyPart() : offset(0), null_pos(0), flag(0), length(0), type(0),
166
 
                   null_bitmask(0) {}
167
 
  ~BlitzKeyPart() {}
168
 
 
169
 
  uint32_t offset;      /* Offset of the key in the row */
170
 
  uint32_t null_pos;    /* Offset of the NULL indicator in the row */
171
 
  uint16_t flag;
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 */
175
 
};
176
 
 
177
 
class BlitzCursor {
178
 
public:
179
 
  BlitzCursor() : tree(NULL), cursor(NULL), moved(false),
180
 
                  active(false) {}
181
 
  ~BlitzCursor() {}
182
 
 
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 */
187
 
 
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);
195
 
 
196
 
  char *find_key(const int search_mode, const char *key,
197
 
                 const int klen, int *rv_len);
198
 
 
199
 
  /* B+TREE UPDATE RELATED */
200
 
  int delete_position(void);
201
 
};
202
 
 
203
 
/* Class that reprensents a BTREE index. Takes care of all I/O
204
 
   to the B+Tree index structure */
205
 
class BlitzTree {
206
 
private:
207
 
  TCBDB *btree;
208
 
 
209
 
public:
210
 
  BlitzTree() : length(0), nparts(0), type(0), unique(false) {}
211
 
  ~BlitzTree() {}
212
 
 
213
 
  /* METADATA */
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 */
219
 
 
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);
225
 
  int close(void);
226
 
 
227
 
  /* KEY HANDLING */
228
 
  bool create_cursor(BlitzCursor *cursor);
229
 
  void destroy_cursor(BlitzCursor *cursor);
230
 
 
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);
236
 
 
237
 
  /* BTREE METADATA RELATED */
238
 
  uint64_t records(void); 
239
 
};
240
 
 
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);
247
 
 
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. */
251
 
class BlitzShare {
252
 
public:
253
 
  BlitzShare() : blitz_lock(), use_count(0), nkeys(0) {}
254
 
  ~BlitzShare() {}
255
 
 
256
 
  drizzled::atomic<uint64_t> auto_increment_value;
257
 
 
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 */
266
 
};
267
 
 
268
 
class ha_blitz: public drizzled::Cursor {
269
 
private:
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 */
273
 
 
274
 
  /* THREAD STATE */
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 */
279
 
 
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 */
284
 
 
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 */
290
 
 
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 */
295
 
 
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 */
300
 
  int errkey_id;
301
 
 
302
 
public:
303
 
  ha_blitz(drizzled::plugin::StorageEngine &engine_arg,
304
 
           drizzled::Table &table_arg);
305
 
  ~ha_blitz() {}
306
 
 
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);
311
 
  int close(void);
312
 
  int info(uint32_t flag);
313
 
 
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);
319
 
 
320
 
  void position(const unsigned char *record);
321
 
 
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 */
336
 
 
337
 
  drizzled::ha_rows records_in_range(uint32_t key_num,
338
 
                                     drizzled::key_range *min_key,
339
 
                                     drizzled::key_range *max_key);
340
 
 
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);
351
 
 
352
 
  /* UTILITY FUNCTIONS (BLITZDB SPECIFIC) */
353
 
  BlitzShare *get_share(const char *table_name);
354
 
  int free_share(void);
355
 
 
356
 
  /* LOCK RELATED FUNCTIONS (BLITZDB SPECIFIC) */
357
 
  int blitz_optimal_lock();
358
 
  int blitz_optimal_unlock();
359
 
  uint32_t max_row_length(void);
360
 
 
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);
370
 
 
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);
375
 
 
376
 
  /* COMAPARISON LOGIC (BLITZDB SPECIFIC) */
377
 
  int compare_rows_for_unique_violation(const unsigned char *old_row,
378
 
                                        const unsigned char *new_row);
379
 
};
380
 
 
381
 
#endif /* PLUGIN_BLITZDB_HA_BLITZ_H */