bpp_tree_handler.c File Reference
#include "bpp_tree_handler.h"

Description

The handler for a disk-backed B+ Tree.

Author
Graeme Douglas
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1.Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2.Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3.Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Definition in file bpp_tree_handler.c.

Include dependency graph for bpp_tree_handler.c:

Functions

void bpptree_get_filename (ion_dictionary_id_t id, char *str)
 
ion_err_t bpptree_create_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, ion_dictionary_compare_t compare, ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary)
 Creates an instance of a dictionary. More...
 
ion_status_t bpptree_insert (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Inserts a key and value into the dictionary. More...
 
ion_status_t bpptree_get (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Queries a dictionary instance for the given key and returns the associated value. More...
 
ion_status_t bpptree_delete (ion_dictionary_t *dictionary, ion_key_t key)
 Deletes the key and associated value from the dictionary instance. More...
 
ion_err_t bpptree_close_dictionary (ion_dictionary_t *dictionary)
 Closes a BppTree instance of a dictionary. More...
 
ion_err_t bpptree_delete_dictionary (ion_dictionary_t *dictionary)
 Deletes an instance of the dictionary and associated data. More...
 
ion_err_t bpptree_destroy_dictionary (ion_dictionary_id_t id)
 Deletes a closed instance of the dictionary and associated data. More...
 
ion_status_t bpptree_update (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Updates the value for a given key. More...
 
ion_cursor_status_t bpptree_next (ion_dict_cursor_t *cursor, ion_record_t *record)
 Next function to query and retrieve the next <K,V> that stratifies the predicate of the cursor. More...
 
void bpptree_destroy_cursor (ion_dict_cursor_t **cursor)
 Destroys the cursor. More...
 
ion_err_t bpptree_find (ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
 Finds multiple instances of a keys that satisfy the provided predicate in the dictionary. More...
 
ion_err_t bpptree_open_dictionary (ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_config_info_t *config, ion_dictionary_compare_t compare)
 Opens a specific BppTree instance of a dictionary. More...
 
void bpptree_init (ion_dictionary_handler_t *handler)
 Registers a specific handler for a dictionary instance. More...
 

Function Documentation

ion_err_t bpptree_close_dictionary ( ion_dictionary_t dictionary)

Closes a BppTree instance of a dictionary.

Parameters
dictionaryA pointer to the specific dictionary instance to be closed.
Returns
The status of closing the dictionary.

Definition at line 290 of file bpp_tree_handler.c.

292  {
293  ion_bpptree_t *bpptree;
294  ion_bpp_err_t bErr;
295 
296  bpptree = (ion_bpptree_t *) dictionary->instance;
297  bErr = b_close(bpptree->tree);
298  ion_fclose(bpptree->values.file_handle);
299  free(dictionary->instance);
300  dictionary->instance = NULL;
301 
302  if (bErrOk != bErr) {
304  }
305 
306  return err_ok;
307 }
ion_bpp_err_t b_close(ion_bpp_handle_t handle)
Definition: bpp_tree.c:1040
enum ION_BPP_ERR ion_bpp_err_t
ion_dictionary_parent_t * instance
ion_file_handle_t file_handle
ion_lfb_t values
ion_bpp_handle_t tree
ion_err_t ion_fclose(ion_file_handle_t file)
Definition: ion_file.c:80

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t bpptree_create_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,
ion_dictionary_compare_t  compare,
ion_dictionary_handler_t handler,
ion_dictionary_t dictionary 
)

Creates an instance of a dictionary.

Creates as instance of a dictionary given a key_size and value_size, in bytes. The dictionary_size parameter is not used for this implementation, as there is no size bound.

Parameters
idID of a dictionary that's given to us.
key_typeThe key category given to us.
key_sizeThe size of the key in bytes.
value_sizeThe size of the value in bytes.
dictionary_sizeThe size of the hashmap in discrete units
compareFunction pointer for the comparison function for the dictionary.
handlerTHe handler for the specific dictionary being created.
dictionaryThe pointer declared by the caller that will reference the instance of the dictionary created.
Returns
The status of the creation of the dictionary.

Definition at line 73 of file bpp_tree_handler.c.

82  {
83  UNUSED(dictionary_size);
84 
85 /* if (key_size != sizeof(int)) {
86  return err_invalid_initial_size;
87  }*/
88 
89  ion_bpptree_t *bpptree;
90  ion_bpp_open_t info;
91 
92  bpptree = malloc(sizeof(ion_bpptree_t));
93 
94  if (NULL == bpptree) {
95  return err_out_of_memory;
96  }
97 
98  char value_filename[20];
99 
100  bpptree_get_filename(id, value_filename);
101  bpptree->values.file_handle = ion_fopen(value_filename);
102 
103  bpptree->values.next_empty = ION_FILE_NULL;
104 
105  char addr_filename[ION_MAX_FILENAME_LENGTH];
106 
107  int actual_filename_length = dictionary_get_filename(id, "bpt", addr_filename);
108 
109  if (actual_filename_length >= ION_MAX_FILENAME_LENGTH) {
110  return err_uninitialized;
111  }
112 
113  info.iName = addr_filename;
114  info.keySize = key_size;
115  info.dupKeys = boolean_false;
116  info.sectorSize = 256;
117  info.comp = compare;
118 
119  ion_bpp_err_t bErr = b_open(info, &(bpptree->tree));
120 
121  if (bErrOk != bErr) {
122  return err_uninitialized;
123  }
124 
125  if (NULL == handler) {
126  return err_uninitialized;
127  }
128 
129  dictionary->instance = (ion_dictionary_parent_t *) bpptree;
130  dictionary->instance->compare = compare;
131  dictionary->instance->key_type = key_type;
132  dictionary->instance->record.key_size = key_size;
133  dictionary->instance->record.value_size = value_size;
135  dictionary->handler = handler;
136 
137  return err_ok;
138 }
void bpptree_get_filename(ion_dictionary_id_t id, char *str)
ion_bpp_bool_t dupKeys
Definition: bpp_tree.h:92
enum ION_BPP_ERR ion_bpp_err_t
ion_record_info_t record
ion_dictionary_handler_t * handler
ion_dictionary_parent_t * instance
ion_file_handle_t file_handle
ion_lfb_t values
size_t sectorSize
Definition: bpp_tree.h:93
This is the super type for all dictionaries.
ion_bpp_handle_t tree
int dictionary_get_filename(ion_dictionary_id_t id, char *ext, char *filename)
Given the ID, implementation specific extension, and a buffer to write to, writes back the formatted ...
Definition: dictionary.c:41
ion_bpp_comparison_t comp
Definition: bpp_tree.h:94
ion_file_handle_t ion_fopen(char *name)
Definition: ion_file.c:51
ion_bpp_err_t b_open(ion_bpp_open_t info, ion_bpp_handle_t *handle)
Definition: bpp_tree.c:899
#define ION_MAX_FILENAME_LENGTH
Since the arduino conforms to 8.3 syntax, that&#39;s 8 + 3 = 11 + 1 (null terminator) characters...
Definition: kv_system.h:73
ion_file_offset_t next_empty
ion_key_size_t key_size
Definition: kv_system.h:307
ion_dictionary_type_t type
#define UNUSED(x)
Definition: kv_system.h:102
ion_key_type_t key_type
ion_dictionary_compare_t compare
#define ION_FILE_NULL
Definition: ion_file.h:75
char * iName
Definition: bpp_tree.h:90
ion_value_size_t value_size
Definition: kv_system.h:309

Here is the call graph for this function:

Here is the caller graph for this function:

ion_status_t bpptree_delete ( ion_dictionary_t dictionary,
ion_key_t  key 
)

Deletes the key and associated value from the dictionary instance.

Parameters
dictionaryThe instance of the dictionary to delete from.
keyThe key that is to be deleted.
Returns
The status of the deletion

Definition at line 256 of file bpp_tree_handler.c.

259  {
260  ion_bpptree_t *bpptree;
261  ion_bpp_err_t bErr;
262  ion_file_offset_t offset;
263  ion_status_t status;
264 
265  status = ION_STATUS_INITIALIZE;
266 
267  bpptree = (ion_bpptree_t *) dictionary->instance;
268 
269  bErr = b_delete(bpptree->tree, key, &offset);
270 
271  if (bErrKeyNotFound != bErr) {
272  status.error = lfb_delete_all(&(bpptree->values), offset, &(status.count));
273  }
274  else {
275  status.error = err_item_not_found;
276  }
277 
278  return status;
279 }
enum ION_BPP_ERR ion_bpp_err_t
ion_dictionary_parent_t * instance
ion_lfb_t values
#define key(k)
Definition: bpp_tree.c:75
ion_err_t error
Definition: kv_system.h:291
ion_bpp_handle_t tree
long ion_file_offset_t
Definition: ion_file.h:47
ion_result_count_t count
Definition: kv_system.h:293
ion_err_t lfb_delete_all(ion_lfb_t *bag, ion_file_offset_t offset, ion_result_count_t *count)
Attempt to delete all contents from the bag starting at a given offset.
ion_bpp_err_t b_delete(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1453
#define ION_STATUS_INITIALIZE
Definition: kv_system.h:107
A status object that describes the result of a dictionary operation.
Definition: kv_system.h:290

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t bpptree_delete_dictionary ( ion_dictionary_t dictionary)

Deletes an instance of the dictionary and associated data.

Parameters
dictionaryThe instance of the dictionary to delete.
Returns
The status of the dictionary deletion.

Definition at line 317 of file bpp_tree_handler.c.

319  {
321 
322  char addr_filename[ION_MAX_FILENAME_LENGTH];
323  char value_filename[ION_MAX_FILENAME_LENGTH];
324 
325  int actual_addr_filename_length = dictionary_get_filename(dictionary->instance->id, "bpt", addr_filename);
326  int actual_value_filename_length = dictionary_get_filename(dictionary->instance->id, "val", value_filename);
327 
328  if ((actual_addr_filename_length >= ION_MAX_FILENAME_LENGTH) || (actual_value_filename_length >= ION_MAX_FILENAME_LENGTH)) {
330  }
331 
332  error = bpptree_close_dictionary(dictionary);
333 
334  if (err_ok != error) {
335  return error;
336  }
337 
338  ion_fremove(addr_filename);
339  ion_fremove(value_filename);
340 
341  return err_ok;
342 }
ion_err_t bpptree_close_dictionary(ion_dictionary_t *dictionary)
Closes a BppTree instance of a dictionary.
ion_dictionary_parent_t * instance
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
int dictionary_get_filename(ion_dictionary_id_t id, char *ext, char *filename)
Given the ID, implementation specific extension, and a buffer to write to, writes back the formatted ...
Definition: dictionary.c:41
ion_dictionary_id_t id
ion_err_t ion_fremove(char *name)
Definition: ion_file.c:93
#define ION_MAX_FILENAME_LENGTH
Since the arduino conforms to 8.3 syntax, that&#39;s 8 + 3 = 11 + 1 (null terminator) characters...
Definition: kv_system.h:73
#define error(rc)
Definition: bpp_tree.c:151

Here is the call graph for this function:

Here is the caller graph for this function:

void bpptree_destroy_cursor ( ion_dict_cursor_t **  cursor)

Destroys the cursor.

Destroys the cursor when the user is finished with it. The destroy function will free up internally allocated memory as well as freeing up any reference to the cursor itself. Cursor pointers will be set to NULL as per ION_DB specification for de-allocated pointers.

Parameters
cursorpointer to cursor.

Definition at line 516 of file bpp_tree_handler.c.

518  {
519  (*cursor)->predicate->destroy(&(*cursor)->predicate);
520  free(((ion_bpp_cursor_t *) (*cursor))->cur_key);
521  free((*cursor));
522  *cursor = NULL;
523 }

Here is the caller graph for this function:

ion_err_t bpptree_destroy_dictionary ( ion_dictionary_id_t  id)

Deletes a closed instance of the dictionary and associated data.

Parameters
idThe identifier identifying the dictionary to delete.
Returns
The status of the dictionary deletion.

Definition at line 352 of file bpp_tree_handler.c.

354  {
355  char addr_filename[ION_MAX_FILENAME_LENGTH];
356  char value_filename[ION_MAX_FILENAME_LENGTH];
357 
358  int actual_addr_filename_length = dictionary_get_filename(id, "bpt", addr_filename);
359  int actual_value_filename_length = dictionary_get_filename(id, "val", value_filename);
360 
361  if ((actual_addr_filename_length >= ION_MAX_FILENAME_LENGTH) || (actual_value_filename_length >= ION_MAX_FILENAME_LENGTH)) {
363  }
364 
365  ion_fremove(addr_filename);
366  ion_fremove(value_filename);
367 
368  return err_ok;
369 }
int dictionary_get_filename(ion_dictionary_id_t id, char *ext, char *filename)
Given the ID, implementation specific extension, and a buffer to write to, writes back the formatted ...
Definition: dictionary.c:41
ion_err_t ion_fremove(char *name)
Definition: ion_file.c:93
#define ION_MAX_FILENAME_LENGTH
Since the arduino conforms to 8.3 syntax, that&#39;s 8 + 3 = 11 + 1 (null terminator) characters...
Definition: kv_system.h:73

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t bpptree_find ( ion_dictionary_t dictionary,
ion_predicate_t predicate,
ion_dict_cursor_t **  cursor 
)

Finds multiple instances of a keys that satisfy the provided predicate in the dictionary.

Generates a cursor that allows the traversal of items where the items key satisfies the predicate (if the underlying implementation allows it).

Parameters
dictionaryThe instance of the dictionary to search.
predicateThe predicate to be used as the condition for matching.
cursorThe pointer to a cursor which is caller declared but callee is responsible for populating.
Returns
The status of the operation.

Definition at line 544 of file bpp_tree_handler.c.

548  {
549  ion_bpptree_t *bpptree = (ion_bpptree_t *) dictionary->instance;
550  ion_key_size_t key_size = dictionary->instance->record.key_size;
551 
552  *cursor = malloc(sizeof(ion_bpp_cursor_t));
553 
554  if (NULL == *cursor) {
555  return err_out_of_memory;
556  }
557 
558  ion_bpp_cursor_t *bCursor = (ion_bpp_cursor_t *) (*cursor);
559 
560  bCursor->cur_key = malloc(key_size);
561 
562  if (NULL == bCursor->cur_key) {
563  free(bCursor);
564  return err_out_of_memory;
565  }
566 
567  (*cursor)->dictionary = dictionary;
568  (*cursor)->status = cs_cursor_uninitialized;
569 
570  (*cursor)->destroy = bpptree_destroy_cursor;
571  (*cursor)->next = bpptree_next;
572 
573  (*cursor)->predicate = malloc(sizeof(ion_predicate_t));
574 
575  if (NULL == (*cursor)->predicate) {
576  free(bCursor->cur_key);
577  free(*cursor);
578  return err_out_of_memory;
579  }
580 
581  (*cursor)->predicate->type = predicate->type;
582  (*cursor)->predicate->destroy = predicate->destroy;
583 
584  switch (predicate->type) {
585  case predicate_equality: {
586  ion_key_t target_key = predicate->statement.equality.equality_value;
587 
588  (*cursor)->predicate->statement.equality.equality_value = malloc(key_size);
589 
590  if (NULL == (*cursor)->predicate->statement.equality.equality_value) {
591  free((*cursor)->predicate);
592  free(bCursor->cur_key);
593  free(*cursor);
594  return err_out_of_memory;
595  }
596 
597  memcpy((*cursor)->predicate->statement.equality.equality_value, target_key, key_size);
598 
599  memcpy(bCursor->cur_key, target_key, key_size);
600 
601  ion_bpp_err_t err = b_get(bpptree->tree, target_key, &bCursor->offset);
602 
603  if (bErrOk != err) {
604  /* If this happens, that means the target key doesn't exist */
605  (*cursor)->status = cs_end_of_results;
606  return err_ok;
607  }
608  else {
609  (*cursor)->status = cs_cursor_initialized;
610  return err_ok;
611  }
612 
613  break;
614  }
615 
616  case predicate_range: {
617  (*cursor)->predicate->statement.range.lower_bound = malloc(key_size);
618 
619  if (NULL == (*cursor)->predicate->statement.range.lower_bound) {
620  free((*cursor)->predicate);
621  free(bCursor->cur_key);
622  free(*cursor);
623  return err_out_of_memory;
624  }
625 
626  memcpy((*cursor)->predicate->statement.range.lower_bound, predicate->statement.range.lower_bound, key_size);
627 
628  (*cursor)->predicate->statement.range.upper_bound = malloc(key_size);
629 
630  if (NULL == (*cursor)->predicate->statement.range.upper_bound) {
631  free((*cursor)->predicate->statement.range.lower_bound);
632  free((*cursor)->predicate);
633  free(bCursor->cur_key);
634  free(*cursor);
635  return err_out_of_memory;
636  }
637 
638  memcpy((*cursor)->predicate->statement.range.upper_bound, predicate->statement.range.upper_bound, key_size);
639 
640  /* We search for the FGEQ of the Lower bound. */
641  b_find_first_greater_or_equal(bpptree->tree, (*cursor)->predicate->statement.range.lower_bound, bCursor->cur_key, &bCursor->offset);
642 
643  /* If the key returned doesn't satisfy the predicate, we can exit */
644  if (boolean_false == test_predicate(*cursor, bCursor->cur_key)) {
645  (*cursor)->status = cs_end_of_results;
646  return err_ok;
647  }
648  else {
649  (*cursor)->status = cs_cursor_initialized;
650  return err_ok;
651  }
652 
653  break;
654  }
655 
656  case predicate_all_records: {
657  ion_bpp_err_t err;
658 
659  /* We search for first key in B++ tree. */
660  err = b_find_first_key(bpptree->tree, bCursor->cur_key, &bCursor->offset);
661 
662  (*cursor)->status = cs_cursor_initialized;
663 
664  if (bErrOk != err) {
665  (*cursor)->status = cs_end_of_results;
666  }
667 
668  return err_ok;
669  break;
670  }
671 
672  case predicate_predicate: {
673  break;
674  }
675 
676  default: {
677  return err_invalid_predicate;
678  break;
679  }
680  }
681 
682  return err_ok;
683 }
enum ION_BPP_ERR ion_bpp_err_t
ion_record_info_t record
ion_predicate_statement_t statement
ion_dictionary_parent_t * instance
ion_bpp_err_t b_get(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1074
ion_boolean_t test_predicate(ion_dict_cursor_t *cursor, ion_key_t key)
Tests the supplied key against the predicate registered in the cursor. If the supplied cursor if of t...
Definition: dictionary.c:571
ion_bpp_handle_t tree
void * ion_key_t
A dictionary key.
Definition: kv_system.h:241
void(* destroy)(ion_predicate_t **)
ion_equality_statement_t equality
ion_predicate_type_t type
void bpptree_destroy_cursor(ion_dict_cursor_t **cursor)
Destroys the cursor.
ion_file_offset_t offset
ion_cursor_status_t bpptree_next(ion_dict_cursor_t *cursor, ion_record_t *record)
Next function to query and retrieve the next <K,V> that stratifies the predicate of the cursor...
ion_key_size_t key_size
Definition: kv_system.h:307
A supertype for cursor predicate objects.
int ion_key_size_t
The size (length) of a dictionary key in bytes.
Definition: kv_system.h:251
ion_bpp_err_t b_find_first_key(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1598
ion_range_statement_t range
ion_bpp_err_t b_find_first_greater_or_equal(ion_bpp_handle_t handle, void *key, void *mkey, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1116
ion_dictionary_status_t status

Here is the call graph for this function:

Here is the caller graph for this function:

ion_status_t bpptree_get ( ion_dictionary_t dictionary,
ion_key_t  key,
ion_value_t  value 
)

Queries a dictionary instance for the given key and returns the associated value.

Queries a dictionary instance for the given key and returns the associated value. If the write_concern is set to wc_insert_unique then if the key exists already, an error will be generated as duplicate keys are prevented. If the write_concern is set to wc_update, the updates are allowed. In this case, if the key exists in the hashmap, the value will be updated. If the key does not exist, then a new item will be inserted to hashmap.

Parameters
dictionaryThe instance of the dictionary to query.
keyThe key to search for.
valueA pointer that is used to return the value associated with the provided key. The function will malloc memory for the value and it is up to the consumer the free the associated memory.
Returns
The status of the query.

Definition at line 217 of file bpp_tree_handler.c.

221  {
222  ion_bpptree_t *bpptree;
223  ion_file_offset_t offset;
225  ion_bpp_err_t bErr;
226  ion_err_t err;
227 
228  bpptree = (ion_bpptree_t *) dictionary->instance;
229 
230  bErr = b_get(bpptree->tree, key, &offset);
231 
232  if (bErrOk != bErr) {
234  }
235 
236  err = lfb_get(&(bpptree->values), offset, bpptree->super.record.value_size, (ion_byte_t *) value, &next);
237 
238  if (err_ok == err) {
239  return ION_STATUS_OK(1);
240  }
241 
242  return ION_STATUS_ERROR(err);
243 }
unsigned char ion_byte_t
A byte type.
Definition: kv_system.h:232
enum ION_BPP_ERR ion_bpp_err_t
#define ION_STATUS_ERROR(error)
Definition: kv_system.h:110
ion_record_info_t record
#define next(b)
Definition: bpp_tree.c:82
ion_dictionary_parent_t * instance
ion_dictionary_parent_t super
ion_err_t lfb_get(ion_lfb_t *bag, ion_file_offset_t offset, unsigned int num_bytes, ion_byte_t *write_to, ion_file_offset_t *next)
Add an item to the linked file bag.
ion_lfb_t values
ion_bpp_err_t b_get(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1074
#define ION_STATUS_OK(count)
Definition: kv_system.h:113
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_handle_t tree
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
long ion_file_offset_t
Definition: ion_file.h:47
ion_value_size_t value_size
Definition: kv_system.h:309

Here is the call graph for this function:

Here is the caller graph for this function:

void bpptree_get_filename ( ion_dictionary_id_t  id,
char *  str 
)

Definition at line 40 of file bpp_tree_handler.c.

43  {
44  sprintf(str, "%d.val", id);
45 }

Here is the caller graph for this function:

void bpptree_init ( ion_dictionary_handler_t handler)

Registers a specific handler for a dictionary instance.

Registers functions for handlers. This only needs to be called once for each type of dictionary that is present.

Parameters
handlerThe handler for the dictionary instance that is to be initialized.

Definition at line 711 of file bpp_tree_handler.c.

713  {
714  handler->insert = bpptree_insert;
716  handler->get = bpptree_get;
717  handler->update = bpptree_update;
718  handler->find = bpptree_find;
719  handler->remove = bpptree_delete;
724 }
ion_status_t(* insert)(ion_dictionary_t *, ion_key_t, ion_value_t)
ion_err_t bpptree_close_dictionary(ion_dictionary_t *dictionary)
Closes a BppTree instance of a dictionary.
ion_status_t bpptree_update(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Updates the value for a given key.
ion_status_t(* remove)(ion_dictionary_t *, ion_key_t)
ion_err_t(* destroy_dictionary)(ion_dictionary_id_t id)
ion_err_t bpptree_create_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, ion_dictionary_compare_t compare, ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary)
Creates an instance of a dictionary.
ion_status_t bpptree_insert(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Inserts a key and value into the dictionary.
ion_err_t bpptree_find(ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
Finds multiple instances of a keys that satisfy the provided predicate in the dictionary.
ion_err_t bpptree_destroy_dictionary(ion_dictionary_id_t id)
Deletes a closed instance of the dictionary and associated data.
ion_status_t bpptree_get(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Queries a dictionary instance for the given key and returns the associated value. ...
ion_status_t(* update)(ion_dictionary_t *, ion_key_t, ion_value_t)
ion_err_t(* close_dictionary)(ion_dictionary_t *)
ion_err_t(* open_dictionary)(ion_dictionary_handler_t *, ion_dictionary_t *, ion_dictionary_config_info_t *, ion_dictionary_compare_t)
ion_err_t(* create_dictionary)(ion_dictionary_id_t, ion_key_type_t, ion_key_size_t, ion_value_size_t, ion_dictionary_size_t, ion_dictionary_compare_t, ion_dictionary_handler_t *, ion_dictionary_t *)
ion_status_t bpptree_delete(ion_dictionary_t *dictionary, ion_key_t key)
Deletes the key and associated value from the dictionary instance.
ion_err_t(* delete_dictionary)(ion_dictionary_t *)
ion_err_t(* find)(ion_dictionary_t *, ion_predicate_t *, ion_dict_cursor_t **)
ion_err_t bpptree_delete_dictionary(ion_dictionary_t *dictionary)
Deletes an instance of the dictionary and associated data.
ion_err_t bpptree_open_dictionary(ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_config_info_t *config, ion_dictionary_compare_t compare)
Opens a specific BppTree instance of a dictionary.
ion_status_t(* get)(ion_dictionary_t *, ion_key_t, ion_value_t)

Here is the call graph for this function:

Here is the caller graph for this function:

ion_status_t bpptree_insert ( ion_dictionary_t dictionary,
ion_key_t  key,
ion_value_t  value 
)

Inserts a key and value into the dictionary.

Parameters
dictionaryThe dictionary instance to insert the value into.
keyThe key to use.
valueThe value to use.
Returns
The status on the insertion of the record.

Definition at line 152 of file bpp_tree_handler.c.

156  {
157  ion_bpptree_t *bpptree;
158  ion_bpp_err_t bErr;
159  ion_err_t err;
160  ion_file_offset_t offset;
161 
162  bpptree = (ion_bpptree_t *) dictionary->instance;
163 
164  offset = ION_FILE_NULL;
165  bErr = b_get(bpptree->tree, key, &offset);
166 
167  if (bErrKeyNotFound == bErr) {
168  offset = ION_FILE_NULL;
169  }
170 
171  err = lfb_put(&(bpptree->values), (ion_byte_t *) value, bpptree->super.record.value_size, offset, &offset);
172 
173  if (err_ok == err) {
174  if (bErrKeyNotFound == bErr) {
175  bErr = b_insert(bpptree->tree, key, offset);
176  }
177  else {
178  bErr = b_update(bpptree->tree, key, offset);
179  }
180 
181  if (bErrOk != bErr) {
183  }
184 
185  return ION_STATUS_OK(1);
186  }
187  else {
189  }
190 }
unsigned char ion_byte_t
A byte type.
Definition: kv_system.h:232
enum ION_BPP_ERR ion_bpp_err_t
#define ION_STATUS_ERROR(error)
Definition: kv_system.h:110
ion_bpp_err_t b_insert(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t rec)
Definition: bpp_tree.c:1167
ion_record_info_t record
ion_dictionary_parent_t * instance
ion_dictionary_parent_t super
ion_lfb_t values
ion_bpp_err_t b_get(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1074
#define ION_STATUS_OK(count)
Definition: kv_system.h:113
#define key(k)
Definition: bpp_tree.c:75
ion_bpp_handle_t tree
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
long ion_file_offset_t
Definition: ion_file.h:47
ion_bpp_err_t b_update(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t rec)
Definition: bpp_tree.c:1345
ion_err_t lfb_put(ion_lfb_t *bag, ion_byte_t *to_write, unsigned int num_bytes, ion_file_offset_t next, ion_file_offset_t *wrote_at)
Add an item to the linked file bag.
#define ION_FILE_NULL
Definition: ion_file.h:75
ion_value_size_t value_size
Definition: kv_system.h:309

Here is the call graph for this function:

Here is the caller graph for this function:

ion_cursor_status_t bpptree_next ( ion_dict_cursor_t cursor,
ion_record_t record 
)

Next function to query and retrieve the next <K,V> that stratifies the predicate of the cursor.

Parameters
cursorThe cursor to iterate over the results.
recordThe structure used to hold the returned key value pair. This must be properly initialized and allocated by the user.
Returns
The status of the cursor.

Definition at line 424 of file bpp_tree_handler.c.

427  {
428  ion_bpp_cursor_t *bCursor = (ion_bpp_cursor_t *) cursor;
429  ion_bpptree_t *bpptree = (ion_bpptree_t *) cursor->dictionary->instance;
430 
431  if (cursor->status == cs_cursor_uninitialized) {
432  return cursor->status;
433  }
434  else if (cursor->status == cs_end_of_results) {
435  return cursor->status;
436  }
437  else if ((cursor->status == cs_cursor_initialized) || (cursor->status == cs_cursor_active)) {
438  if (cursor->status == cs_cursor_active) {
439  ion_boolean_t is_valid = boolean_true;
440 
441  switch (cursor->predicate->type) {
442  case predicate_equality: {
443  if (-1 == bCursor->offset) {
444  /* End of results, we can quit */
445  is_valid = boolean_false;
446  }
447 
448  break;
449  }
450 
451  case predicate_range: {
452  /*do b_find_next_key then test_predicate */
453  if (-1 == bCursor->offset) {
454  ion_bpp_err_t bErr = b_find_next_key(bpptree->tree, bCursor->cur_key, &bCursor->offset);
455 
456  if ((bErrOk != bErr) || (boolean_false == test_predicate(cursor, bCursor->cur_key))) {
457  is_valid = boolean_false;
458  }
459  }
460 
461  break;
462  }
463 
464  case predicate_all_records: {
465  if (-1 == bCursor->offset) {
466  ion_bpp_err_t bErr = b_find_next_key(bpptree->tree, bCursor->cur_key, &bCursor->offset);
467 
468  if (bErrOk != bErr) {
469  is_valid = boolean_false;
470  }
471  }
472 
473  break;
474  }
475 
476  case predicate_predicate: {
477  break;
478  }
479  /*No default since we can assume the predicate is valid. */
480  }
481 
482  if (boolean_false == is_valid) {
483  cursor->status = cs_end_of_results;
484  return cursor->status;
485  }
486  }
487  else {
488  /* The status is cs_cursor_initialized */
489  cursor->status = cs_cursor_active;
490  }
491 
492  /* Get key */
493  memcpy(record->key, bCursor->cur_key, cursor->dictionary->instance->record.key_size);
494 
495  /* Get value */
496  lfb_get(&(bpptree->values), bCursor->offset, cursor->dictionary->instance->record.value_size, record->value, &bCursor->offset);
497  return cursor->status;
498  }
499 
500  return cs_invalid_cursor;
501 }
enum ION_BPP_ERR ion_bpp_err_t
ion_record_info_t record
ion_predicate_t * predicate
ion_dictionary_parent_t * instance
ion_value_t value
Definition: kv_system.h:318
ion_dictionary_t * dictionary
ion_err_t lfb_get(ion_lfb_t *bag, ion_file_offset_t offset, unsigned int num_bytes, ion_byte_t *write_to, ion_file_offset_t *next)
Add an item to the linked file bag.
ion_lfb_t values
ion_cursor_status_t status
ion_boolean_t test_predicate(ion_dict_cursor_t *cursor, ion_key_t key)
Tests the supplied key against the predicate registered in the cursor. If the supplied cursor if of t...
Definition: dictionary.c:571
ion_key_t key
Definition: kv_system.h:316
ion_bpp_handle_t tree
ion_predicate_type_t type
ion_file_offset_t offset
ion_key_size_t key_size
Definition: kv_system.h:307
char ion_boolean_t
A boolean type.
Definition: kv_system.h:269
ion_value_size_t value_size
Definition: kv_system.h:309
ion_bpp_err_t b_find_next_key(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1669

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t bpptree_open_dictionary ( ion_dictionary_handler_t handler,
ion_dictionary_t dictionary,
ion_dictionary_config_info_t config,
ion_dictionary_compare_t  compare 
)

Opens a specific BppTree instance of a dictionary.

Parameters
handlerA pointer to the handler for the specific dictionary being opened.
dictionaryThe pointer declared by the caller that will reference the instance of the dictionary opened.
configThe configuration info of the specific dictionary to be opened.
compareFunction pointer for the comparison function for the dictionary.
Returns
The status of opening the dictionary.

Definition at line 701 of file bpp_tree_handler.c.

706  {
707  return bpptree_create_dictionary(config->id, config->type, config->key_size, config->value_size, config->dictionary_size, compare, handler, dictionary);
708 }
ion_err_t bpptree_create_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, ion_dictionary_compare_t compare, ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary)
Creates an instance of a dictionary.
ion_dictionary_size_t dictionary_size

Here is the call graph for this function:

Here is the caller graph for this function:

ion_status_t bpptree_update ( ion_dictionary_t dictionary,
ion_key_t  key,
ion_value_t  value 
)

Updates the value for a given key.

Updates the value for a given key. If the key does not currently exist in the hashmap, it will be created and the value sorted.

Parameters
dictionaryThe instance of the dictionary to be updated.
keyThe key that is to be updated.
valueThe value that is to be updated.
Returns
The status of the update.

Definition at line 386 of file bpp_tree_handler.c.

390  {
391  ion_bpptree_t *bpptree;
392  ion_bpp_err_t bErr;
393  ion_file_offset_t offset;
394  ion_result_count_t count;
395 
396  count = 0;
397  bpptree = (ion_bpptree_t *) dictionary->instance;
398 
399  bErr = b_get(bpptree->tree, key, &offset);
400 
401  if (bErrKeyNotFound != bErr) {
402  lfb_update_all(&(bpptree->values), offset, bpptree->super.record.value_size, (ion_byte_t *) value, &count);
403  }
404  else {
405  return bpptree_insert(dictionary, key, value);
406  }
407 
408  return ION_STATUS_OK(count);
409 }
unsigned char ion_byte_t
A byte type.
Definition: kv_system.h:232
enum ION_BPP_ERR ion_bpp_err_t
ion_record_info_t record
ion_err_t lfb_update_all(ion_lfb_t *bag, ion_file_offset_t offset, unsigned int num_bytes, ion_byte_t *to_write, ion_result_count_t *count)
Attempt to update all records kept within a specific bag, starting at some record at a given offset...
ion_dictionary_parent_t * instance
ion_dictionary_parent_t super
ion_lfb_t values
ion_bpp_err_t b_get(ion_bpp_handle_t handle, void *key, ion_bpp_external_address_t *rec)
Definition: bpp_tree.c:1074
#define ION_STATUS_OK(count)
Definition: kv_system.h:113
#define key(k)
Definition: bpp_tree.c:75
ion_status_t bpptree_insert(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Inserts a key and value into the dictionary.
ion_bpp_handle_t tree
long ion_file_offset_t
Definition: ion_file.h:47
int ion_result_count_t
A type for the number of results changed during an operation.
Definition: kv_system.h:284
ion_value_size_t value_size
Definition: kv_system.h:309

Here is the call graph for this function:

Here is the caller graph for this function: