ion_master_table.c
Go to the documentation of this file.
1 /******************************************************************************/
36 /******************************************************************************/
37 
38 #include "ion_master_table.h"
39 
40 FILE *ion_master_table_file = NULL;
42 
46  long where
47 ) {
48  long old_pos = ftell(ion_master_table_file);
49 
50  if (ION_MASTER_TABLE_CALCULATE_POS == where) {
51  where = (int) (config->id * ION_MASTER_TABLE_RECORD_SIZE(config));
52  }
53 
54  if (ION_MASTER_TABLE_CALCULATE_POS > where) {
55  if (0 != fseek(ion_master_table_file, 0, SEEK_END)) {
56  return err_file_bad_seek;
57  }
58  }
59  else if (0 != fseek(ion_master_table_file, where, SEEK_SET)) {
60  return err_file_bad_seek;
61  }
62 
63  if (1 != fwrite(&(config->id), sizeof(config->id), 1, ion_master_table_file)) {
64  return err_file_write_error;
65  }
66 
67  if (1 != fwrite(&(config->use_type), sizeof(config->use_type), 1, ion_master_table_file)) {
68  return err_file_write_error;
69  }
70 
71  if (1 != fwrite(&(config->type), sizeof(config->type), 1, ion_master_table_file)) {
72  return err_file_write_error;
73  }
74 
75  if (1 != fwrite(&(config->key_size), sizeof(config->key_size), 1, ion_master_table_file)) {
76  return err_file_write_error;
77  }
78 
79  if (1 != fwrite(&(config->value_size), sizeof(config->value_size), 1, ion_master_table_file)) {
80  return err_file_write_error;
81  }
82 
83  if (1 != fwrite(&(config->dictionary_size), sizeof(config->dictionary_size), 1, ion_master_table_file)) {
84  return err_file_write_error;
85  }
86 
87  if (1 != fwrite(&(config->dictionary_type), sizeof(config->dictionary_type), 1, ion_master_table_file)) {
88  return err_file_write_error;
89  }
90 
91  if (1 != fwrite(&(config->dictionary_status), sizeof(config->dictionary_status), 1, ion_master_table_file)) {
92  return err_file_write_error;
93  }
94 
95  if (0 != fseek(ion_master_table_file, old_pos, SEEK_SET)) {
96  return err_file_bad_seek;
97  }
98 
99  return err_ok;
100 }
101 
117 ion_err_t
120  long where
121 ) {
122  long old_pos = ftell(ion_master_table_file);
123 
124  if (ION_MASTER_TABLE_CALCULATE_POS == where) {
125  where = (int) (config->id * ION_MASTER_TABLE_RECORD_SIZE(config));
126  }
127 
128  if (0 != fseek(ion_master_table_file, where, SEEK_SET)) {
129  return err_file_bad_seek;
130  }
131 
132  if (1 != fread(&(config->id), sizeof(config->id), 1, ion_master_table_file)) {
133  return err_file_read_error;
134  }
135 
136  if (1 != fread(&(config->use_type), sizeof(config->use_type), 1, ion_master_table_file)) {
137  return err_file_read_error;
138  }
139 
140  if (1 != fread(&(config->type), sizeof(config->type), 1, ion_master_table_file)) {
141  return err_file_read_error;
142  }
143 
144  if (1 != fread(&(config->key_size), sizeof(config->key_size), 1, ion_master_table_file)) {
145  return err_file_read_error;
146  }
147 
148  if (1 != fread(&(config->value_size), sizeof(config->value_size), 1, ion_master_table_file)) {
149  return err_file_read_error;
150  }
151 
152  if (1 != fread(&(config->dictionary_size), sizeof(config->dictionary_size), 1, ion_master_table_file)) {
153  return err_file_read_error;
154  }
155 
156  if (1 != fread(&(config->dictionary_type), sizeof(config->dictionary_type), 1, ion_master_table_file)) {
157  return err_file_read_error;
158  }
159 
160  if (1 != fread(&(config->dictionary_status), sizeof(config->dictionary_status), 1, ion_master_table_file)) {
161  return err_file_read_error;
162  }
163 
164  if (0 != fseek(ion_master_table_file, old_pos, SEEK_SET)) {
165  return err_file_bad_seek;
166  }
167 
168  if (0 == config->id) {
169  return err_item_not_found;
170  }
171 
172  return err_ok;
173 }
174 
175 /* Returns the next dictionary ID, then increments. */
176 ion_err_t
179 ) {
181 
182  /* Flush master row. This writes the next ID to be used, so add 1. */
183  ion_dictionary_config_info_t master_config = { .id = ion_master_table_next_id + 1 };
184 
185  error = ion_master_table_write(&master_config, 0);
186 
187  if (err_ok != error) {
188  return error;
189  }
190 
191  *id = ion_master_table_next_id++;
192 
193  return err_ok;
194 }
195 
196 ion_err_t
198  void
199 ) {
201 
202  /* If it's already open, then we don't do anything. */
203  if (NULL != ion_master_table_file) {
204  return err_ok;
205  }
206 
208 
209  /* File may not exist. */
210  if (NULL == ion_master_table_file) {
212 
213  if (NULL == ion_master_table_file) {
214  return err_file_open_error;
215  }
216 
217  /* Clean fresh file was opened. */
219 
220  /* Write master row. */
222 
223  if (err_ok != (error = ion_master_table_write(&master_config, 0))) {
224  return error;
225  }
226  }
227  else {
228  /* Here we read an existing file. */
229 
230  /* Find existing ID count. */
231  ion_dictionary_config_info_t master_config;
232 
233  if (ion_master_table_read(&master_config, 0)) {
234  return err_file_read_error;
235  }
236 
237  ion_master_table_next_id = master_config.id;
238  }
239 
240  return err_ok;
241 }
242 
243 ion_err_t
245  void
246 ) {
247  if (NULL != ion_master_table_file) {
248  if (0 != fclose(ion_master_table_file)) {
249  return err_file_close_error;
250  }
251  }
252 
253  ion_master_table_file = NULL;
254 
255  return err_ok;
256 }
257 
258 ion_err_t
260  void
261 ) {
262  ion_err_t err;
263  ion_dictionary_handler_t handler;
264  ion_dictionary_t dict;
266 
268 
269  if (NULL != ion_master_table_file) {
270  id--;
271 
272  while (id > 0) {
273  err = ion_lookup_in_master_table(id, &config);
274 
275  /* Dictionary corresponding to ID has been found and dictionary is open. */
276  if ((err_ok == err) && (ion_dictionary_status_closed != config.dictionary_status)) {
277  err = ion_switch_handler(config.dictionary_type, &handler);
278 
279  if (err_ok != err) {
280  return err;
281  }
282 
283  dict.handler = &handler;
284 
285  /* Initialize dictionary instance. */
286  err = dictionary_open(&handler, &dict, &config);
287 
288  if (err_ok != err) {
289  return err;
290  }
291 
292  /* Close the dictionary instance. */
293  err = dictionary_close(&dict);
294 
295  if (err_ok != err) {
296  return err;
297  }
298  }
299 
300  id--;
301  }
302 
303  if (0 != fclose(ion_master_table_file)) {
304  return err_file_close_error;
305  }
306  }
307 
308  ion_master_table_file = NULL;
309 
310  return err_ok;
311 }
312 
313 ion_err_t
315  void
316 ) {
318  return err_file_delete_error;
319  }
320 
321  /* Reset master table ID as master table has been deleted. */
323 
324  return err_ok;
325 }
326 
337 ion_err_t
340  ion_dictionary_size_t dictionary_size
341 ) {
343  .id = dictionary->instance->id, .use_type = 0, .type = dictionary->instance->key_type, .key_size = dictionary->instance->record.key_size, .value_size = dictionary->instance->record.value_size, .dictionary_size = dictionary_size, .dictionary_type = dictionary->instance->type, .dictionary_status = dictionary->status
344  };
345 
347 }
348 
349 ion_err_t
351  ion_dictionary_handler_t *handler,
353  ion_key_type_t key_type,
354  ion_key_size_t key_size,
355  ion_value_size_t value_size,
356  ion_dictionary_size_t dictionary_size
357 ) {
358  ion_err_t err;
360 
361  err = ion_master_table_get_next_id(&id);
362 
363  if (err_ok != err) {
364  return err;
365  }
366 
367  err = dictionary_create(handler, dictionary, id, key_type, key_size, value_size, dictionary_size);
368 
369  if (err_ok != err) {
370  return err;
371  }
372 
373  err = ion_add_to_master_table(dictionary, dictionary_size);
374 
375  return err;
376 }
377 
378 ion_err_t
382 ) {
384 
385  config->id = id;
387 
388  if (err_ok != error) {
389  return error;
390  }
391 
392  return err_ok;
393 }
394 
395 ion_err_t
398  ion_dict_use_t use_type,
399  char whence
400 ) {
404 
405  tconfig.id = 0;
406 
407  id = 1;
408 
409  if (ION_MASTER_TABLE_FIND_LAST == whence) {
410  id = ion_master_table_next_id - 1;
411  }
412 
413  /* Loop through all items. */
414  for (; id < ion_master_table_next_id && id > 0; id += whence) {
415  error = ion_lookup_in_master_table(id, &tconfig);
416 
417  if (err_item_not_found == error) {
418  continue;
419  }
420 
421  if (err_ok != error) {
422  return error;
423  }
424 
425  /* If this config has the right type, set the output pointer. */
426  if (tconfig.use_type == use_type) {
427  *config = tconfig;
428 
429  return err_ok;
430  }
431  }
432 
433  return err_item_not_found;
434 }
435 
436 ion_err_t
439 ) {
440  ion_dictionary_config_info_t blank = { 0 };
441  long where = (id * ION_MASTER_TABLE_RECORD_SIZE(&blank));
442 
443  return ion_master_table_write(&blank, where);
444 }
445 
449 ) {
450  ion_err_t err;
452 
453  err = ion_lookup_in_master_table(id, &config);
454 
455  if (err_ok != err) {
457  }
458 
459  return config.dictionary_type;
460 }
461 
462 ion_err_t
464  ion_dictionary_handler_t *handler, /* Passed in empty, to be set. */
465  ion_dictionary_t *dictionary, /* Passed in empty, to be set. */
467 ) {
468  ion_err_t err;
470 
471  err = ion_lookup_in_master_table(id, &config);
472 
473  /* Lookup for id failed. */
474  if (err_ok != err) {
475  return err_uninitialized;
476  }
477 
478  ion_switch_handler(config.dictionary_type, handler);
479 
480  err = dictionary_open(handler, dictionary, &config);
481 
482  return err;
483 }
484 
485 ion_err_t
488 ) {
489  ion_err_t err;
490 
491  err = dictionary_close(dictionary);
492  return err;
493 }
494 
495 ion_err_t
499 ) {
500  ion_err_t err;
502 
503  if (ion_dictionary_status_closed != dictionary->status) {
504  id = dictionary->instance->id;
505  err = dictionary_delete_dictionary(dictionary);
506 
507  if (err_ok != err) {
509  }
510 
512  }
513  else {
514  type = ion_get_dictionary_type(id);
515 
516  if (dictionary_type_error_t == type) {
518  }
519 
520  ion_dictionary_handler_t handler;
521 
522  ion_switch_handler(type, &handler);
523 
524  err = dictionary_destroy_dictionary(&handler, id);
525 
526  if (err_ok != err) {
527  return err;
528  }
529 
531  }
532 
533  return err;
534 }
535 
536 ion_err_t
539  ion_dictionary_handler_t *handler
540 ) {
541  switch (type) {
543  bpptree_init(handler);
544  break;
545  }
546 
548  ffdict_init(handler);
549  break;
550  }
551 
553  oafdict_init(handler);
554  break;
555  }
556 
558  oadict_init(handler);
559  break;
560  }
561 
563  sldict_init(handler);
564  break;
565  }
566 
568  linear_hash_dict_init(handler);
569  break;
570  }
571 
573  return err_uninitialized;
574  }
575  }
576 
577  return err_ok;
578 }
ion_err_t ion_lookup_in_master_table(ion_dictionary_id_t id, ion_dictionary_config_info_t *config)
Looks up the config of the given id.
enum ION_KEY_TYPE ion_key_type_t
This is the available key types for ION_DB. All types will be based on system defines.
ion_record_info_t record
ion_byte_t ion_dict_use_t
A type describing how a dictionary is used.
ion_dictionary_type_t dictionary_type
#define ION_MASTER_TABLE_CALCULATE_POS
ion_err_t ion_master_table_create_dictionary(ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_key_type_t key_type, ion_key_size_t key_size, ion_value_size_t value_size, ion_dictionary_size_t dictionary_size)
Creates a dictionary through use of the master table.
int ion_value_size_t
The size (length) of a dictionary value in bytes.
Definition: kv_system.h:256
ion_err_t ion_add_to_master_table(ion_dictionary_t *dictionary, ion_dictionary_size_t dictionary_size)
Adds the given dictionary to the master table.
ion_err_t ion_master_table_read(ion_dictionary_config_info_t *config, long where)
Read a record to the master table.
void linear_hash_dict_init(ion_dictionary_handler_t *handler)
Registers a linear hash handler to a dictionary instance.
ion_dictionary_handler_t * handler
ion_dictionary_parent_t * instance
ion_err_t ion_switch_handler(ion_dictionary_type_t type, ion_dictionary_handler_t *handler)
Retrieves the type of dictionary stored under a particular id in the master table.
enum ION_DICTIONARY_TYPE ion_dictionary_type_t
This is the available dictionary types for ION_DB. All types will be based on system defines...
ion_err_t ion_delete_dictionary(ion_dictionary_t *dictionary, ion_dictionary_id_t id)
Deletes a given dictionary instance and deletes it from the master table.
unsigned int ion_dictionary_id_t
A type used to identify dictionaries, specifically in the master table.
unsigned int ion_dictionary_size_t
The implementation specific size of the dictionary.
Definition: kv_system.h:264
Struct containing details for opening a dictionary previously created.
void oadict_init(ion_dictionary_handler_t *handler)
Registers a specific handler for a dictionary instance.
#define ION_MASTER_TABLE_FILENAME
File name for IonDB master table.
ion_err_t ion_delete_master_table(void)
Deletes the master table.
ion_dictionary_status_t dictionary_status
#define fremove(x)
Definition: kv_system.h:56
ion_err_t ion_master_table_write(ion_dictionary_config_info_t *config, long where)
Write a record to the master table.
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
ion_err_t dictionary_create(ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_id_t id, ion_key_type_t key_type, ion_key_size_t key_size, ion_value_size_t value_size, ion_dictionary_size_t dictionary_size)
Creates as instance of a specific type of dictionary.
Definition: dictionary.c:125
Master table API.
A dictionary contains information regarding an instance of the storage element and the associated han...
ion_err_t ion_delete_from_master_table(ion_dictionary_id_t id)
Deletes a dictionary from the master table.
ion_dictionary_id_t id
ion_dictionary_type_t ion_get_dictionary_type(ion_dictionary_id_t id)
Retrieves the type of dictionary stored under a particular id in the master table.
ion_err_t ion_close_dictionary(ion_dictionary_t *dictionary)
Closes a given dictionary.
void ffdict_init(ion_dictionary_handler_t *handler)
Given the handler instance, bind the appropriate flat file functions.
ion_err_t dictionary_destroy_dictionary(ion_dictionary_handler_t *handler, ion_dictionary_id_t id)
Destroys dictionary.
Definition: dictionary.c:185
ion_err_t ion_init_master_table(void)
Opens the master table.
void oafdict_init(ion_dictionary_handler_t *handler)
Registers a specific handler for a dictionary instance.
ion_key_size_t key_size
Definition: kv_system.h:307
ion_err_t dictionary_delete_dictionary(ion_dictionary_t *dictionary)
Destroys dictionary.
Definition: dictionary.c:178
void bpptree_init(ion_dictionary_handler_t *handler)
Registers a specific handler for a dictionary instance.
ion_dictionary_type_t type
ion_err_t ion_open_dictionary(ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_id_t id)
Finds the target dictionary and opens it.
ion_dictionary_id_t ion_master_table_next_id
Master table resposible for managing instances.
ion_err_t ion_close_master_table(void)
Closes the master table.
ion_err_t dictionary_close(ion_dictionary_t *dictionary)
Closes a dictionary.
Definition: dictionary.c:372
#define error(rc)
Definition: bpp_tree.c:139
ion_key_type_t key_type
ion_err_t dictionary_open(ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_config_info_t *config)
Opens a dictionary, given the desired config.
Definition: dictionary.c:287
ion_dictionary_size_t dictionary_size
#define ION_MASTER_TABLE_WRITE_FROM_END
int ion_key_size_t
The size (length) of a dictionary key in bytes.
Definition: kv_system.h:251
ion_err_t ion_close_all_master_table(void)
Closes the master table and all dictionary instances within it.
#define ION_MASTER_TABLE_RECORD_SIZE(cp)
ion_err_t ion_find_by_use_master_table(ion_dictionary_config_info_t *config, ion_dict_use_t use_type, char whence)
Find first or last dictionary in master table with a given use.
void sldict_init(ion_dictionary_handler_t *handler)
Registers a skiplist handler to a dictionary instance.
FILE * ion_master_table_file
Master table file.
ion_err_t ion_master_table_get_next_id(ion_dictionary_id_t *id)
Returns the next dictionary ID, then increments.
ion_dictionary_status_t status
#define ION_MASTER_TABLE_FIND_LAST
Flag used when searching master table; search for last instance matching criteria.
ion_value_size_t value_size
Definition: kv_system.h:309
A dictionary_handler is responsible for dealing with the specific interface for an underlying diction...