Zero  0.1.0
table_desc.h
Go to the documentation of this file.
1 /* -*- mode:C++; c-basic-offset:4 -*-
2  Shore-kits -- Benchmark implementations for Shore-MT
3 
4  Copyright (c) 2007-2009
5  Data Intensive Applications and Systems Labaratory (DIAS)
6  Ecole Polytechnique Federale de Lausanne
7 
8  All Rights Reserved.
9 
10  Permission to use, copy, modify and distribute this software and
11  its documentation is hereby granted, provided that both the
12  copyright notice and this permission notice appear in all copies of
13  the software, derivative works or modified versions, and any
14  portions thereof, and that both notices appear in supporting
15  documentation.
16 
17  This code is distributed in the hope that it will be useful, but
18  WITHOUT ANY WARRANTY; without even the implied warranty of
19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
20  DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
21  RESULTING FROM THE USE OF THIS SOFTWARE.
22 */
23 
36 /* shore_table.h contains the base class (table_desc_t) for tables stored in
37  * Shore. Each table consists of several parts:
38  *
39  * 1. An array of field_desc, which contains the decription of the
40  * fields. The number of fields is set by the constructor. The schema
41  * of the table is not written to the disk.
42  *
43  * 2. The primary index of the table.
44  *
45  * 3. Secondary indices on the table. All the secondary indices created
46  * on the table are stored as a linked list.
47  *
48  *
49  * FUNCTIONALITY
50  *
51  * There are methods in (table_desc_t) for creating, the table
52  * and indexes.
53  *
54  *
55  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
56  * @note Modifications to the schema need rebuilding the whole
57  * database.
58  * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
59  *
60  *
61  * USAGE:
62  *
63  * To create a new table, create a class for the table by inheriting
64  * publicly from class tuple_desc_t to take advantage of all the
65  * built-in tools. The schema of the table should be set at the
66  * constructor of the table. (See shore_tpcc_schema.h for examples.)
67  *
68  *
69  * NOTE:
70  *
71  * Due to limitation of Shore implementation, only the last field
72  * in indexes can be variable length.
73  *
74  *
75  * BUGS:
76  *
77  * If a new index is created on an existing table, explicit call to
78  * load the index is needed.
79  *
80  * Timestamp field is not fully implemented: no set function.
81  *
82  *
83  * EXTENSIONS:
84  *
85  * The mapping between SQL types and C++ types are defined in
86  * (field_desc_t). Modify the class to support more SQL types or
87  * change the mapping. The NUMERIC type is currently stored as string;
88  * no further understanding is provided yet.
89  *
90  */
91 
92 #ifndef __TABLE_DESC_H
93 #define __TABLE_DESC_H
94 
95 #include "sm_vas.h"
96 #include "mcs_lock.h"
97 
98 //#include "shore_msg.h"
99 #include "util/guard.h"
100 
101 #include "file_desc.h"
102 #include "field.h"
103 #include "index_desc.h"
104 #include "row.h"
105 
106 // Shore -> Zero compatibility
108 
109 #define DECLARE_TABLE_SCHEMA(tablename) \
110  class tablename : public table_desc_t { \
111  public: tablename(); }
112 
113 /* ---------------------------------------------------------------
114  *
115  * @class: table_desc_t
116  *
117  * @brief: Description of a Shore table. Gives access to the fields,
118  * and indexes of the table.
119  *
120  * --------------------------------------------------------------- */
121 
123 protected:
124 
125  pthread_mutex_t _fschema_mutex; // file schema mutex
126  string _name; // file name
127  unsigned _field_count; // # of fields
128 
129  /* ------------------- */
130  /* --- table schema -- */
131  /* ------------------- */
132 
133  ss_m* _db; // the SM
134 
135  field_desc_t* _desc; // schema - set of field descriptors
136 
137  // primary index for index-organized table (replaces Heap of Shore-MT)
139 
140  // secondary indexes
141  std::vector<index_desc_t*> _indexes;
142 
143  unsigned _maxsize; // max tuple size for this table, shortcut
144 
145 public:
146 
147  /* ------------------- */
148  /* --- Constructor --- */
149  /* ------------------- */
150 
151  table_desc_t(const char* name, int fieldcnt);
152 
153  virtual ~table_desc_t();
154 
155 
156  /* ----------------------------------------- */
157  /* --- create physical table and indexes --- */
158  /* ----------------------------------------- */
159 
161 
163 
165  // using fixed stid=1 for catalog (enforced when creating)
166  return 1;
167  }
168 
169  w_rc_t load_stids();
170 
171 
172  /* ----------------------------------------------------- */
173  /* --- create the logical description of the indexes --- */
174  /* ----------------------------------------------------- */
175 
176  // create an index on the table
177  bool create_index_desc(const char* name,
178  const unsigned* fields,
179  const unsigned num,
180  const bool unique = true,
181  const bool primary = false);
182 
183  bool create_primary_idx_desc(const unsigned* fields,
184  const unsigned num);
185 
186 
187 
188  /* ------------------------ */
189  /* --- index facilities --- */
190  /* ------------------------ */
191 
192  // index by name
193  index_desc_t* find_index(const char* index_name) {
194  if (_primary_idx->matches_name(index_name)) {
195  return _primary_idx;
196  }
197  for (size_t i = 0; i < _indexes.size(); i++) {
198  if (_indexes[i]->matches_name(index_name)) {
199  return _indexes[i];
200  }
201  }
202  return nullptr;
203  }
204 
205  std::vector<index_desc_t*>& get_indexes() {
206  return _indexes;
207  }
208 
209  // # of indexes
210  int index_count() {
211  return _indexes.size();
212  }
213 
215  return (_primary_idx);
216  }
217 
219 
220  /* sets primary index, the index itself should be already set to
221  * primary and unique */
223  assert (idx->is_primary() && idx->is_unique());
224  _primary_idx = idx;
225  }
226 
227  char* index_keydesc(index_desc_t* idx);
228 
229  int index_maxkeysize(index_desc_t* index) const; /* max index key size */
230 
231  /* ---------------------------------------------------------------- */
232  /* --- for the conversion between disk format and memory format --- */
233  /* ---------------------------------------------------------------- */
234 
235  unsigned maxsize(); /* maximum requirement for disk format */
236 
237  inline field_desc_t* desc(const unsigned descidx) {
238  assert (descidx < _field_count);
239  assert (_desc);
240  return (&(_desc[descidx]));
241  }
242 
243  const char* name() const {
244  return _name.c_str();
245  }
246 
247  unsigned field_count() const {
248  return _field_count;
249  }
250 
251  /* ---------- */
252  /* --- db --- */
253  /* ---------- */
254  void set_db(ss_m* db) {
255  _db = db;
256  }
257 
258  ss_m* db() {
259  return (_db);
260  }
261 
262  /* ----------------- */
263  /* --- debugging --- */
264  /* ----------------- */
265 
266  void print_desc(ostream& os = cout); /* print the schema */
267 
268 protected:
269  int find_field_by_name(const char* field_name) const;
270 
272 }; // EOF: table_desc_t
273 
274 
275 typedef std::list<table_desc_t*> table_list_t;
276 
277 /******************************************************************
278  *
279  * class table_desc_t methods
280  *
281  ******************************************************************/
282 
283 
284 
285 /******************************************************************
286  *
287  * @fn: find_field_by_name
288  *
289  * @brief: Returns the field index, given its name. If no such field
290  * name exists it returns -1.
291  *
292  ******************************************************************/
293 
294 inline int table_desc_t::find_field_by_name(const char* field_name) const {
295  for (unsigned i = 0; i < _field_count; i++) {
296  if (strcmp(field_name, _desc[i].name()) == 0) {
297  return (i);
298  }
299  }
300  return (-1);
301 }
302 
303 /******************************************************************
304  *
305  * @fn: index_keydesc
306  *
307  * @brief: Iterates over all the fields of a selected index and returns
308  * on a single string the corresponding key description
309  *
310  ******************************************************************/
311 
313  CRITICAL_SECTION(idx_kd_cs, idx->_keydesc_lock);
314  if (strlen(idx->_keydesc) > 1) { // is key_desc is already set
315  return (idx->_keydesc);
316  }
317 
318  // else set the index keydesc
319  for (unsigned i = 0; i < idx->field_count(); i++) {
320  strcat(idx->_keydesc, _desc[idx->key_index(i)].keydesc());
321  }
322  return (idx->_keydesc);
323 }
324 
325 /******************************************************************
326  *
327  * @fn: index_maxkeysize
328  *
329  * @brief: For an index it returns the maximum size of the index key
330  *
331  * @note: !!! Now that key_size() Uses the maxsize() of each field,
332  * key_size() == maxkeysize()
333  *
334  ******************************************************************/
335 
337  unsigned size = 0;
338  if ((size = idx->get_keysize()) > 0) {
339  // keysize has already been calculated
340  // just return that value
341  return (size);
342  }
343 
344  // needs to calculate the (max)key for that index
345  unsigned ix = 0;
346  for (unsigned i = 0; i < idx->field_count(); i++) {
347  ix = idx->key_index(i);
348  size += _desc[ix].fieldmaxsize();
349  }
350  // set it for the index, for future invokations
351  idx->set_keysize(size);
352  return (size);
353 }
354 
355 /******************************************************************
356  *
357  * @fn: maxsize()
358  *
359  * @brief: Return the maximum size requirement for a tuple in disk format.
360  * Normally, it will be calculated only once.
361  *
362  ******************************************************************/
363 
364 inline unsigned table_desc_t::maxsize() {
365  // shortcut not to re-compute maxsize
366  if (*&_maxsize) {
367  return (*&_maxsize);
368  }
369 
370  // calculate maximum size required
371  unsigned size = 0;
372  unsigned var_count = 0;
373  unsigned null_count = 0;
374  for (unsigned i = 0; i < _field_count; i++) {
375  size += _desc[i].fieldmaxsize();
376  if (_desc[i].allow_null()) {
377  null_count++;
378  }
379  if (_desc[i].is_variable_length()) {
380  var_count++;
381  }
382  }
383 
384  size += (var_count * sizeof(offset_t)) + (null_count >> 3) + 1;
385 
386  // There is a small window from the time it checks if maxsize is already set,
387  // until the time it tries to set it up. In the meantime, another thread may
388  // has done the calculation already. If that had happened, the two threads
389  // should have calculated the same maxsize, since it is the same table desc.
390  // In other words, the maxsize should be either 0 or equal to the size.
391  assert ((*&_maxsize == 0) || (*&_maxsize == size));
392 
393  // atomic_swap_uint(&_maxsize, size);
394  _maxsize = size;
395  // add an offset for each field, which is used to serialize
396  _maxsize += sizeof(offset_t) * _field_count;
397  return (*&_maxsize);
398 }
399 
400 #endif // __TABLE_DESC_H
w_rc_t create_physical_table(ss_m *db)
Definition: table_desc.cpp:84
int key_index(const unsigned index) const
Definition: index_desc.cpp:76
unsigned _field_count
Definition: table_desc.h:127
Definition: table_desc.h:122
ss_m * _db
Definition: table_desc.h:133
void set_primary(index_desc_t *idx)
Definition: table_desc.h:222
StoreID get_primary_stid()
Definition: table_desc.cpp:196
ss_m * db()
Definition: table_desc.h:258
int find_field_by_name(const char *field_name) const
Definition: table_desc.h:294
std::list< table_desc_t * > table_list_t
Definition: table_desc.h:275
void set_keysize(const unsigned sz)
Definition: index_desc.h:147
char * index_keydesc(index_desc_t *idx)
Definition: table_desc.h:312
Definition: field.h:125
w_rc_t load_stids()
Definition: table_desc.cpp:201
table_desc_t(const char *name, int fieldcnt)
Definition: table_desc.cpp:37
uint32_t StoreID
Definition: basics.h:47
StoreID get_catalog_stid()
Definition: table_desc.h:164
unsigned fieldmaxsize() const
Definition: field.h:175
const char * keydesc()
Definition: field.h:191
: Description of an index.
bool create_primary_idx_desc(const unsigned *fields, const unsigned num)
Definition: table_desc.cpp:172
int get_keysize()
Definition: index_desc.h:143
std::vector< index_desc_t * > & get_indexes()
Definition: table_desc.h:205
string _name
Definition: table_desc.h:126
field_desc_t * _desc
Definition: table_desc.h:135
void print_desc(ostream &os=cout)
Definition: table_desc.cpp:217
bool is_primary() const
Definition: index_desc.h:135
element_lock_mode
Lock mode for one OKVL component (key, partition, or gap).
Definition: w_okvl.h:107
void set_db(ss_m *db)
Definition: table_desc.h:254
const char * name() const
Definition: table_desc.h:243
unsigned field_count() const
Definition: index_desc.h:105
This is the SHORE Storage Manager API.
Definition: sm.h:405
unsigned field_count() const
Definition: table_desc.h:247
index_desc_t * find_index(const char *index_name)
Definition: table_desc.h:193
bool matches_name(const char *name)
Definition: index_desc.cpp:72
index_desc_t * _primary_idx
Definition: table_desc.h:138
Return code for most functions and methods.
Definition: w_rc.h:87
Definition: index_desc.h:60
tatas_lock _keydesc_lock
Definition: index_desc.h:84
unsigned maxsize()
Definition: table_desc.h:364
w_rc_t create_physical_index(ss_m *db, index_desc_t *index)
Definition: table_desc.cpp:106
: Descriptors for Shore files/indexes, and structures that help in keeping track of the created files...
unsigned _maxsize
Definition: table_desc.h:143
srwlock_t _mutex
Definition: table_desc.h:271
: Description and current value of a field (column)
: Base class for records (rows) of tables in Shore
pthread_mutex_t _fschema_mutex
Definition: table_desc.h:125
std::vector< index_desc_t * > _indexes
Definition: table_desc.h:141
index_desc_t * primary_idx()
Definition: table_desc.h:214
field_desc_t * desc(const unsigned descidx)
Definition: table_desc.h:237
int index_maxkeysize(index_desc_t *index) const
Definition: table_desc.h:336
okvl_mode::element_lock_mode lock_mode_t
Definition: table_desc.h:107
char _keydesc[MAX_KEYDESC_LEN]
Definition: index_desc.h:83
intptr_t offset_t
Definition: row.h:94
bool create_index_desc(const char *name, const unsigned *fields, const unsigned num, const bool unique=true, const bool primary=false)
Definition: table_desc.cpp:142
bool is_unique() const
Definition: index_desc.h:131
#define CRITICAL_SECTION(name, lock)
Definition: critical_section.h:75
Shore read-write lock:: many-reader/one-writer spin lock.
Definition: latches.h:350
int index_count()
Definition: table_desc.h:210
virtual ~table_desc_t()
Definition: table_desc.cpp:51