dictionary.c File Reference

Description

Author
Graeme Douglas, Scott Fazackerley
See also
For more information, refer to dictionary.h.
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 dictionary.c.

Include dependency graph for dictionary.c:

Functions

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 filename for any implementation instance. More...
 
char dictionary_compare_char_array (ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
 Compare any two character (byte) arrays. These are not assumed to be null-terminated. More...
 
char dictionary_compare_null_terminated_string (ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
 Compare any two null-terminated strings. More...
 
ion_dictionary_compare_t dictionary_switch_compare (ion_key_type_t key_type)
 
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. More...
 
ion_status_t dictionary_insert (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Insert a value into a dictionary. More...
 
ion_status_t dictionary_get (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Retrieve a value given a key. More...
 
ion_status_t dictionary_update (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Update all records with a given key. More...
 
ion_err_t dictionary_delete_dictionary (ion_dictionary_t *dictionary)
 Destroys dictionary. More...
 
ion_err_t dictionary_destroy_dictionary (ion_dictionary_handler_t *handler, ion_dictionary_id_t id)
 Destroys dictionary. More...
 
ion_status_t dictionary_delete (ion_dictionary_t *dictionary, ion_key_t key)
 Delete a value given a key. More...
 
char dictionary_compare_unsigned_value (ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
 Compares two unsigned integer numeric keys. More...
 
char dictionary_compare_signed_value (ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
 Compares two signed integer numeric keys. More...
 
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. More...
 
ion_err_t dictionary_close (ion_dictionary_t *dictionary)
 Closes a dictionary. More...
 
void dictionary_destroy_predicate_equality (ion_predicate_t **predicate)
 Destroys an equality predicate. More...
 
void dictionary_destroy_predicate_range (ion_predicate_t **predicate)
 Destroys a range predicate. More...
 
void dictionary_destroy_predicate_all_records (ion_predicate_t **predicate)
 Destroys an all records predicate. More...
 
ion_err_t dictionary_build_predicate (ion_predicate_t *predicate, ion_predicate_type_t type,...)
 Builds a predicate based on the type given. More...
 
ion_err_t dictionary_find (ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
 Uses the given predicate and cursor to search the dictionary. More...
 
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 the type equality, the key is tested for equality with that cursor's equality value and returns boolean_true if the test passes. If the supplied cursor is of the type predicate_range, the key is tested for whether it falls in the range of that cursor's registered upper_bound and lower_bound and returns boolean_true if it does. In the case that the supplied cursor is of the type predicate_all_records, boolean_true is returned. If any of the above tests fail, or if the type of the cursor is not mentioned above, boolean_false is returned. More...
 

Function Documentation

ion_err_t dictionary_build_predicate ( ion_predicate_t predicate,
ion_predicate_type_t  type,
  ... 
)

Builds a predicate based on the type given.

The caller is responsible for allocating the memory needed for the predicate.

Parameters
predicateA pointer to the pre-allocated predicate to be initialized.
typeThe type of predicate to build.
...Extra variables necessary for initializing the predicate. This depends on the type of predicate being initialized. Equality: 1st vparam is target key. Range: 1st vparam is lower bound, 2nd vparam is upper bound. All_records: No vparams used. Predicate: Not yet implemented
Returns
An error describing the result of open operation.

Definition at line 512 of file dictionary.c.

516  {
517  va_list arg_list;
518 
519  va_start(arg_list, type);
520 
521  predicate->type = type;
522 
523  switch (type) {
524  case predicate_equality: {
525  ion_key_t key = va_arg(arg_list, ion_key_t);
526 
527  predicate->statement.equality.equality_value = key;
529  break;
530  }
531 
532  case predicate_range: {
533  ion_key_t lower_bound = va_arg(arg_list, ion_key_t);
534  ion_key_t upper_bound = va_arg(arg_list, ion_key_t);
535 
536  predicate->statement.range.lower_bound = lower_bound;
537  predicate->statement.range.upper_bound = upper_bound;
539  break;
540  }
541 
542  case predicate_all_records: {
544  break;
545  }
546 
547  case predicate_predicate: {
548  return err_invalid_predicate;
549  }
550 
551  default: {
552  return err_invalid_predicate;
553  break;
554  }
555  }
556 
557  va_end(arg_list);
558  return err_ok;
559 }
void dictionary_destroy_predicate_all_records(ion_predicate_t **predicate)
Destroys an all records predicate.
Definition: dictionary.c:502
void dictionary_destroy_predicate_range(ion_predicate_t **predicate)
Destroys a range predicate.
Definition: dictionary.c:482
ion_predicate_statement_t statement
#define key(k)
Definition: bpp_tree.c:75
void dictionary_destroy_predicate_equality(ion_predicate_t **predicate)
Destroys an equality predicate.
Definition: dictionary.c:463
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
ion_range_statement_t range

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t dictionary_close ( ion_dictionary_t dictionary)

Closes a dictionary.

Parameters
dictionaryA pointer to the dictionary object to be closed.
Returns
An error describing the result of open operation.

Definition at line 372 of file dictionary.c.

374  {
375  if (ion_dictionary_status_closed == dictionary->status) {
376  return err_ok;
377  }
378 
379  ion_err_t error = dictionary->handler->close_dictionary(dictionary);
380 
381  if (err_not_implemented == error) {
383  ion_dict_cursor_t *cursor = NULL;
384  ion_record_t record;
385  ion_err_t err;
386 
388  err = dictionary_find(dictionary, &predicate, &cursor);
389 
390  if (err_ok != err) {
391  return err;
392  }
393 
394  int key_size = dictionary->instance->record.key_size;
395  int value_size = dictionary->instance->record.value_size;
396  ion_key_type_t key_type = dictionary->instance->key_type;
397 
398  record.key = alloca(key_size);
399  record.value = alloca(value_size);
400 
401  ion_dictionary_handler_t fallback_handler;
402  ion_dictionary_t fallback_dict;
403 
404  ffdict_init(&fallback_handler);
405 
406  err = dictionary_create(&fallback_handler, &fallback_dict, dictionary->instance->id, key_type, key_size, value_size, 1);
407 
408  if (err_ok != err) {
409  return err;
410  }
411 
412  ion_cursor_status_t cursor_status;
413 
414  while (cs_cursor_active == (cursor_status = cursor->next(cursor, &record)) || cs_cursor_initialized == cursor_status) {
415  ion_status_t status = dictionary_insert(&fallback_dict, record.key, record.value);
416 
417  if (err_ok != status.error) {
418  cursor->destroy(&cursor);
419  dictionary_delete_dictionary(&fallback_dict);
420  return status.error;
421  }
422  }
423 
424  /* Cursor has either reached the end of the result set or there was no
425  result set to traverse, and the cursor remains uninitialized. */
426  if ((cs_end_of_results != cursor_status) && (cs_cursor_uninitialized != cursor_status)) {
427  return err_uninitialized;
428  }
429 
430  cursor->destroy(&cursor);
431 
432  err = dictionary_close(&fallback_dict);
433 
434  if (err_ok != err) {
435  return err;
436  }
437 
438  err = dictionary_delete_dictionary(dictionary);
439 
440  if (err_ok != err) {
441  return err;
442  }
443 
444  error = err_ok;
445  }
446 
447  if (err_ok == error) {
448  dictionary->status = ion_dictionary_status_closed;
449  }
450 
451  return error;
452 }
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_cursor_status_t(* next)(ion_dict_cursor_t *, ion_record_t *record)
ion_record_info_t record
ion_dictionary_handler_t * handler
ion_dictionary_parent_t * instance
ion_value_t value
Definition: kv_system.h:318
void(* destroy)(ion_dict_cursor_t **)
Struct used to maintain key and value.
Definition: kv_system.h:315
ion_err_t error
Definition: kv_system.h:291
ion_status_t dictionary_insert(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Insert a value into a dictionary.
Definition: dictionary.c:151
ion_key_t key
Definition: kv_system.h:316
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
A dictionary contains information regarding an instance of the storage element and the associated han...
ion_dictionary_id_t id
A supertype for dictionary cursor objects.
ion_err_t(* close_dictionary)(ion_dictionary_t *)
void ffdict_init(ion_dictionary_handler_t *handler)
Given the handler instance, bind the appropriate flat file functions.
ion_key_size_t key_size
Definition: kv_system.h:307
A supertype for cursor predicate objects.
ion_err_t dictionary_delete_dictionary(ion_dictionary_t *dictionary)
Destroys dictionary.
Definition: dictionary.c:178
ion_err_t dictionary_close(ion_dictionary_t *dictionary)
Closes a dictionary.
Definition: dictionary.c:372
#define error(rc)
Definition: bpp_tree.c:151
ion_key_type_t key_type
ion_err_t dictionary_find(ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
Uses the given predicate and cursor to search the dictionary.
Definition: dictionary.c:562
ion_dictionary_status_t status
ion_value_size_t value_size
Definition: kv_system.h:309
ion_err_t dictionary_build_predicate(ion_predicate_t *predicate, ion_predicate_type_t type,...)
Builds a predicate based on the type given.
Definition: dictionary.c:512
A dictionary_handler is responsible for dealing with the specific interface for an underlying diction...
char ion_cursor_status_t
A type for the status of a cursor.
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:

char dictionary_compare_char_array ( ion_key_t  first_key,
ion_key_t  second_key,
ion_key_size_t  key_size 
)

Compare any two character (byte) arrays. These are not assumed to be null-terminated.

Parameters
first_keyThe first (left) key being compared.
second_keyThe second (right) key being compared.
key_sizeThe size of the keys being compared.
Returns
The resulting comparison value.

Definition at line 61 of file dictionary.c.

65  {
66  return strncmp((char *) first_key, (char *) second_key, key_size);
67 }

Here is the caller graph for this function:

char dictionary_compare_null_terminated_string ( ion_key_t  first_key,
ion_key_t  second_key,
ion_key_size_t  key_size 
)

Compare any two null-terminated strings.

Parameters
first_keyThe first (left) key being compared.
second_keyThe second (right) key being compared.
key_sizeThe (maximum) size of the keys being compared.
Returns
The resulting comparison value.

Definition at line 80 of file dictionary.c.

84  {
85  return strncmp((char *) first_key, (char *) second_key, key_size);
86 }

Here is the caller graph for this function:

char dictionary_compare_signed_value ( ion_key_t  first_key,
ion_key_t  second_key,
ion_key_size_t  key_size 
)

Compares two signed integer numeric keys.

Compares two ion_key_t assuming that they are of arbitrary length and integer, signed and numeric (ie not a char[]). The following values will be returned:

@p first_key > @p second_key return 1
@p first_key == @p second_key return 0
@p first_key < @p second_key return -1

This works for all integer numeric types for signed values as long as both keys are of the same type.

Parameters
first_keyThe pointer to the first key in the comparison.
second_keyThe pointer to the second key in the comparison.
key_sizeThe length of the key in bytes.
Returns
The resulting comparison value.

Definition at line 239 of file dictionary.c.

243  {
244  int idx;
245  char return_value = ION_RETURN_VALUE;
246 
247  /*
248  * In this case, the endianness of the process does matter as the code does
249  * a direct comparison of bytes in memory starting for MSB.
250  */
251 
252 /* Start at the MSB */
253 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
254  idx = key_size - 1;
255 #else
256  idx = 0;
257 #endif
258 
259  ion_byte_t firstbyte = *((ion_byte_t *) first_key + idx);
260  ion_byte_t secondbyte = *((ion_byte_t *) second_key + idx);
261 
262  /* Do bit comparison on the sign bit to do positive/negative comparison. Lets us exit early in many cases */
263  if ((return_value = (secondbyte >> 7) - (firstbyte >> 7)) != ION_ZERO) {
264  return return_value;
265  }
266 
267 /* In this case, we are of the same sign. Do byte-for-byte comparison. */
268 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
269 
270  for (; idx >= 0; idx--) {
271 #else
272 
273  for (; idx < key_size; idx++) {
274 #endif
275  firstbyte = *((ion_byte_t *) first_key + idx);
276  secondbyte = *((ion_byte_t *) second_key + idx);
277 
278  if ((return_value = (firstbyte > secondbyte) - (firstbyte < secondbyte)) != ION_ZERO) {
279  return return_value;
280  }
281  }
282 
283  return return_value;
284 }
#define ION_RETURN_VALUE
Definition: kv_system.h:68
unsigned char ion_byte_t
A byte type.
Definition: kv_system.h:232
#define ION_ZERO
Definition: kv_system.h:67

Here is the caller graph for this function:

char dictionary_compare_unsigned_value ( ion_key_t  first_key,
ion_key_t  second_key,
ion_key_size_t  key_size 
)

Compares two unsigned integer numeric keys.

Compares two ion_key_t assuming that they are of arbitrary length and integer, unsigned and numeric (ie not a char[]). The following values will be returned:

@p first_key > @p second_key return 1
@p first_key == @p second_key return 0
@p first_key < @p second_key return -1

This works for all integer numeric types for unsigned values as long as both keys are of the same type. You'll notice a weird math expression being expressed when computing the return value. This value is written in this a weird way to give us the desired {-1, 0, 1} range of return values. Draw out a table and the reasoning will become immediately obvious.

Parameters
first_keyThe pointer to the first key in the comparison.
second_keyThe pointer to the second key in the comaparison.
key_sizeThe length of the key in bytes.
Returns
The resulting comparison value.

Definition at line 207 of file dictionary.c.

211  {
212  int idx;
213  char return_value = ION_RETURN_VALUE;
214 
215  /*
216  * In this case, the endianness of the process does matter as the code does
217  * a direct comparison of bytes in memory starting for MSB.
218  */
219 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
220 
221  for (idx = key_size - 1; idx >= 0; idx--) {
222 #else
223 
224  for (idx = 0; idx < key_size; idx++) {
225 #endif
226 
227  ion_byte_t firstbyte = *((ion_byte_t *) first_key + idx);
228  ion_byte_t secondbyte = *((ion_byte_t *) second_key + idx);
229 
230  if ((return_value = (firstbyte > secondbyte) - (firstbyte < secondbyte)) != ION_ZERO) {
231  return return_value;
232  }
233  }
234 
235  return return_value;
236 }
#define ION_RETURN_VALUE
Definition: kv_system.h:68
unsigned char ion_byte_t
A byte type.
Definition: kv_system.h:232
#define ION_ZERO
Definition: kv_system.h:67

Here is the caller graph for this function:

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.

This function is not to be used if you are using the master table.

Parameters
handlerA pointer to a handler object containing pointers to all the functions necessary for this dictionary instance.
dictionaryA pointer to a dictionary object that will be used to access all dictionary operations.
idThe identifier used to identify the dictionary.
key_typeThe type of the key.
key_sizeThe size of the key type to store.
value_sizeThe size of the value to store.
dictionary_sizeThe implementation specific dictionary size. The interpretation of this value is dependent on the dictionary implementaion being used.
Returns
A status describing the result of dictionary creation.

Definition at line 125 of file dictionary.c.

133  {
134  ion_err_t err;
136 
137  err = handler->create_dictionary(id, key_type, key_size, value_size, dictionary_size, compare, handler, dictionary);
138 
139  if (err_ok == err) {
140  dictionary->instance->id = id;
141  dictionary->status = ion_dictionary_status_ok;
142  }
143  else {
144  dictionary->status = ion_dictionary_status_error;
145  }
146 
147  return err;
148 }
ion_dictionary_parent_t * instance
char(* ion_dictionary_compare_t)(ion_key_t, ion_key_t, ion_key_size_t)
Function pointer type for dictionary comparison methods.
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
ion_dictionary_id_t id
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_dictionary_compare_t dictionary_switch_compare(ion_key_type_t key_type)
Definition: dictionary.c:89
ion_dictionary_status_t status

Here is the call graph for this function:

Here is the caller graph for this function:

ion_status_t dictionary_delete ( ion_dictionary_t dictionary,
ion_key_t  key 
)

Delete a value given a key.

Parameters
dictionaryA pointer to the dictionary to be intialized.
keyThe key to retrieve the value for.
Returns
A status describing the result of the deletion.

Definition at line 199 of file dictionary.c.

202  {
203  return dictionary->handler->remove(dictionary, key);
204 }
ion_dictionary_handler_t * handler
ion_status_t(* remove)(ion_dictionary_t *, ion_key_t)
#define key(k)
Definition: bpp_tree.c:75

Here is the caller graph for this function:

ion_err_t dictionary_delete_dictionary ( ion_dictionary_t dictionary)

Destroys dictionary.

Parameters
dictionaryThe dictionary instance to destroy.
Returns
The status of the total destruction of the dictionary.

Definition at line 178 of file dictionary.c.

180  {
181  return dictionary->handler->delete_dictionary(dictionary);
182 }
ion_dictionary_handler_t * handler
ion_err_t(* delete_dictionary)(ion_dictionary_t *)

Here is the caller graph for this function:

ion_err_t dictionary_destroy_dictionary ( ion_dictionary_handler_t handler,
ion_dictionary_id_t  id 
)

Destroys dictionary.

Parameters
handlerA pointer to the implementation of dictionary to destroy.
idThe identifier identifying the dictionary to destroy.
Returns
The status of the total destruction of the dictionary.

Definition at line 185 of file dictionary.c.

188  {
189  ion_err_t error = handler->destroy_dictionary(id);
190 
191  if (err_not_implemented == error) {
192  error = ffdict_destroy_dictionary(id);
193  }
194 
195  return error;
196 }
ion_err_t ffdict_destroy_dictionary(ion_dictionary_id_t id)
Cleans up all files created by the dictionary, and frees any allocated memory, for an already closed ...
ion_err_t(* destroy_dictionary)(ion_dictionary_id_t id)
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
#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 dictionary_destroy_predicate_all_records ( ion_predicate_t **  predicate)

Destroys an all records predicate.

This function should not be called directly. Instead, it is set while building the predicate.

Parameters
predicateA pointer to the pointer to the predicate object being destroyed.

Definition at line 502 of file dictionary.c.

504  {
505  if (*predicate != NULL) {
506  free(*predicate);
507  *predicate = NULL;
508  }
509 }

Here is the caller graph for this function:

void dictionary_destroy_predicate_equality ( ion_predicate_t **  predicate)

Destroys an equality predicate.

This function should not be called directly. Instead, it is set while building the predicate.

Parameters
predicateA pointer to the pointer to the predicate object being destroyed.

Definition at line 463 of file dictionary.c.

465  {
466  if (*predicate != NULL) {
467  free((*predicate)->statement.equality.equality_value);
468  free(*predicate);
469  *predicate = NULL;
470  }
471 }

Here is the caller graph for this function:

void dictionary_destroy_predicate_range ( ion_predicate_t **  predicate)

Destroys a range predicate.

This function should not be called directly. Instead, it is set while building the predicate.

Parameters
predicateA pointer to the pointer to the predicate object being destroyed.

Definition at line 482 of file dictionary.c.

484  {
485  if (*predicate != NULL) {
486  free((*predicate)->statement.range.upper_bound);
487  free((*predicate)->statement.range.lower_bound);
488  free(*predicate);
489  *predicate = NULL;
490  }
491 }

Here is the caller graph for this function:

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

Uses the given predicate and cursor to search the dictionary.

This function will allocate and initialize the cursor. This means that it must freed once we are done. This function sets up a cursor for traversal.

Parameters
dictionaryA pointer to the dictionary object to be created.
predicateA pointer predicate object to be used for the search.
cursorA pointer to the pointer for a cursor object. Note that if the cursor pointer object is pointing to a valid cursor already, we will leak memory.
Returns
An error code describing the result of the operation.

Definition at line 562 of file dictionary.c.

566  {
567  return dictionary->handler->find(dictionary, predicate, cursor);
568 }
ion_dictionary_handler_t * handler
ion_err_t(* find)(ion_dictionary_t *, ion_predicate_t *, ion_dict_cursor_t **)

Here is the caller graph for this function:

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

Retrieve a value given a key.

Parameters
dictionaryA pointer to the dictionary to be intialized.
keyThe key to retrieve the value for.
valueA pointer to the value byte array to copy data into.
Returns
A status describing the result of the retrieval.

Definition at line 160 of file dictionary.c.

164  {
165  return dictionary->handler->get(dictionary, key, value);
166 }
ion_dictionary_handler_t * handler
#define key(k)
Definition: bpp_tree.c:75
ion_status_t(* get)(ion_dictionary_t *, ion_key_t, ion_value_t)

Here is the caller graph for this function:

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 filename for any implementation instance.

Parameters
[in]idGiven ID to use to generate a unique filename.
[in]extGiven implementation specific filename extension to be used.
[out]filenameChar buffer to write-back into. This must be allocated memory.
Returns
How many characters would have been written. It is a good idea to check that this does not exceed ION_MAX_FILENAME_LENGTH.

Definition at line 41 of file dictionary.c.

45  {
46  return snprintf(filename, ION_MAX_FILENAME_LENGTH, "%d.%s", id, ext);
47 }
#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 caller graph for this function:

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

Insert a value into a dictionary.

Parameters
dictionaryThe dictionary that the value is to be inserted to
keyThe key that identifies value.
valueThe value to store under key.
Returns
A status describing the result of the insertion.

Definition at line 151 of file dictionary.c.

155  {
156  return dictionary->handler->insert(dictionary, key, value);
157 }
ion_status_t(* insert)(ion_dictionary_t *, ion_key_t, ion_value_t)
ion_dictionary_handler_t * handler
#define key(k)
Definition: bpp_tree.c:75

Here is the caller graph for this function:

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.

Parameters
handlerA pointer to the dictionary handler object to be used.
dictionaryA pointer to the dictionary object to be manipulated.
configA pointer to the configuration object to be used to open the dictionary with.
Returns
An error describing the result of open operation.

Definition at line 287 of file dictionary.c.

291  {
293 
294  ion_err_t error = handler->open_dictionary(handler, dictionary, config, compare);
295 
296  if (err_not_implemented == error) {
298  ion_dict_cursor_t *cursor = NULL;
299  ion_record_t record;
300  ion_dictionary_handler_t fallback_handler;
301  ion_dictionary_t fallback_dict;
302  ion_err_t err;
303 
304  ffdict_init(&fallback_handler);
305 
306  ion_dictionary_config_info_t fallback_config = {
307  config->id, 0, config->type, config->key_size, config->value_size, 1
308  };
309 
310  err = dictionary_open(&fallback_handler, &fallback_dict, &fallback_config);
311 
312  if (err_ok != err) {
313  return err;
314  }
315 
317  err = dictionary_find(&fallback_dict, &predicate, &cursor);
318 
319  if (err_ok != err) {
320  return err;
321  }
322 
323  record.key = alloca(config->key_size);
324  record.value = alloca(config->value_size);
325 
326  err = dictionary_create(handler, dictionary, config->id, config->type, config->key_size, config->value_size, config->dictionary_size);
327 
328  if (err_ok != err) {
329  return err;
330  }
331 
332  ion_cursor_status_t cursor_status;
333 
334  while (cs_cursor_active == (cursor_status = cursor->next(cursor, &record)) || cs_cursor_initialized == cursor_status) {
335  ion_status_t status = dictionary_insert(dictionary, record.key, record.value);
336 
337  if (err_ok != status.error) {
338  cursor->destroy(&cursor);
339  dictionary_close(&fallback_dict);
340  dictionary_delete_dictionary(dictionary);
341  return status.error;
342  }
343  }
344 
345  if (cursor_status != cs_end_of_results) {
346  return err_uninitialized;
347  }
348 
349  cursor->destroy(&cursor);
350 
351  err = dictionary_delete_dictionary(&fallback_dict);
352 
353  if (err_ok != err) {
354  return err;
355  }
356 
357  error = err_ok;
358  }
359 
360  if (err_ok == error) {
361  dictionary->status = ion_dictionary_status_ok;
362  dictionary->instance->id = config->id;
363  }
364  else {
365  dictionary->status = ion_dictionary_status_error;
366  }
367 
368  return error;
369 }
ion_cursor_status_t(* next)(ion_dict_cursor_t *, ion_record_t *record)
ion_dictionary_parent_t * instance
ion_value_t value
Definition: kv_system.h:318
void(* destroy)(ion_dict_cursor_t **)
Struct used to maintain key and value.
Definition: kv_system.h:315
Struct containing details for opening a dictionary previously created.
ion_err_t error
Definition: kv_system.h:291
ion_status_t dictionary_insert(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Insert a value into a dictionary.
Definition: dictionary.c:151
ion_key_t key
Definition: kv_system.h:316
char(* ion_dictionary_compare_t)(ion_key_t, ion_key_t, ion_key_size_t)
Function pointer type for dictionary comparison methods.
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
A dictionary contains information regarding an instance of the storage element and the associated han...
ion_dictionary_id_t id
A supertype for dictionary cursor objects.
ion_err_t(* open_dictionary)(ion_dictionary_handler_t *, ion_dictionary_t *, ion_dictionary_config_info_t *, ion_dictionary_compare_t)
void ffdict_init(ion_dictionary_handler_t *handler)
Given the handler instance, bind the appropriate flat file functions.
A supertype for cursor predicate objects.
ion_err_t dictionary_delete_dictionary(ion_dictionary_t *dictionary)
Destroys dictionary.
Definition: dictionary.c:178
ion_err_t dictionary_close(ion_dictionary_t *dictionary)
Closes a dictionary.
Definition: dictionary.c:372
#define error(rc)
Definition: bpp_tree.c:151
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
ion_err_t dictionary_find(ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
Uses the given predicate and cursor to search the dictionary.
Definition: dictionary.c:562
ion_dictionary_compare_t dictionary_switch_compare(ion_key_type_t key_type)
Definition: dictionary.c:89
ion_dictionary_status_t status
ion_err_t dictionary_build_predicate(ion_predicate_t *predicate, ion_predicate_type_t type,...)
Builds a predicate based on the type given.
Definition: dictionary.c:512
A dictionary_handler is responsible for dealing with the specific interface for an underlying diction...
char ion_cursor_status_t
A type for the status of a cursor.
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_dictionary_compare_t dictionary_switch_compare ( ion_key_type_t  key_type)

Definition at line 89 of file dictionary.c.

91  {
93 
94  switch (key_type) {
97  break;
98  }
99 
102  break;
103  }
104 
105  case key_type_char_array: {
107  break;
108  }
109 
112  break;
113  }
114 
115  default: {
116  /* do something - you must bind the correct comparison function */
117  break;
118  }
119  }
120 
121  return compare;
122 }
char dictionary_compare_signed_value(ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
Compares two signed integer numeric keys.
Definition: dictionary.c:239
char dictionary_compare_char_array(ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
Compare any two character (byte) arrays. These are not assumed to be null-terminated.
Definition: dictionary.c:61
char dictionary_compare_null_terminated_string(ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
Compare any two null-terminated strings.
Definition: dictionary.c:80
char dictionary_compare_unsigned_value(ion_key_t first_key, ion_key_t second_key, ion_key_size_t key_size)
Compares two unsigned integer numeric keys.
Definition: dictionary.c:207
char(* ion_dictionary_compare_t)(ion_key_t, ion_key_t, ion_key_size_t)
Function pointer type for dictionary comparison methods.

Here is the call graph for this function:

Here is the caller graph for this function:

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

Update all records with a given key.

Parameters
dictionaryA pointer to the dictionary instance to update.
keyThe key to identify records for updating.
valueThe value to update records with.

Definition at line 169 of file dictionary.c.

173  {
174  return dictionary->handler->update(dictionary, key, value);
175 }
ion_dictionary_handler_t * handler
#define key(k)
Definition: bpp_tree.c:75
ion_status_t(* update)(ion_dictionary_t *, ion_key_t, ion_value_t)

Here is the caller graph for this function:

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 the type equality, the key is tested for equality with that cursor's equality value and returns boolean_true if the test passes. If the supplied cursor is of the type predicate_range, the key is tested for whether it falls in the range of that cursor's registered upper_bound and lower_bound and returns boolean_true if it does. In the case that the supplied cursor is of the type predicate_all_records, boolean_true is returned. If any of the above tests fail, or if the type of the cursor is not mentioned above, boolean_false is returned.

Parameters
cursorThe cursor and predicate being used to test key against.
keyThe key to test.
Returns
The result is the key passes or fails the predicate test.

Definition at line 571 of file dictionary.c.

574  {
575  ion_dictionary_parent_t *parent = cursor->dictionary->instance;
576  ion_key_size_t key_size = cursor->dictionary->instance->record.key_size;
577  ion_boolean_t result = boolean_false;
578 
579  switch (cursor->predicate->type) {
580  case predicate_equality: {
581  if (parent->compare(key, cursor->predicate->statement.equality.equality_value, cursor->dictionary->instance->record.key_size) == 0) {
582  result = boolean_true;
583  }
584 
585  break;
586  }
587 
588  case predicate_range: {
589  ion_key_t lower_b = cursor->predicate->statement.range.lower_bound;
590  ion_key_t upper_b = cursor->predicate->statement.range.upper_bound;
591 
592  /* Check if key >= lower bound */
593  ion_boolean_t comp_lower = parent->compare(key, lower_b, key_size) >= 0;
594 
595  /* Check if key <= upper bound */
596  ion_boolean_t comp_upper = parent->compare(key, upper_b, key_size) <= 0;
597 
598  result = comp_lower && comp_upper;
599  break;
600  }
601 
602  case predicate_all_records: {
603  result = boolean_true;
604  break;
605  }
606  }
607 
608  return result;
609 }
ion_record_info_t record
ion_predicate_t * predicate
ion_predicate_statement_t statement
ion_dictionary_parent_t * instance
ion_dictionary_t * dictionary
#define key(k)
Definition: bpp_tree.c:75
This is the super type for all dictionaries.
void * ion_key_t
A dictionary key.
Definition: kv_system.h:241
ion_equality_statement_t equality
ion_predicate_type_t type
ion_key_size_t key_size
Definition: kv_system.h:307
ion_dictionary_compare_t compare
int ion_key_size_t
The size (length) of a dictionary key in bytes.
Definition: kv_system.h:251
char ion_boolean_t
A boolean type.
Definition: kv_system.h:269
ion_range_statement_t range

Here is the caller graph for this function: