~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/blitzdb/ha_blitz.h

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

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::TableIdentifier &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::TableShare &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 */