flat_file_dictionary_handler.c File Reference

Description

Function definitions at the dictionary interface level for the flat file store.

Author
Eric Huang
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 flat_file_dictionary_handler.c.

Include dependency graph for flat_file_dictionary_handler.c:

Functions

ion_cursor_status_t ffdict_next (ion_dict_cursor_t *cursor, ion_record_t *record)
 Fetches the next record to be returned from a cursor that has already been initialized. More...
 
void ffdict_destroy_cursor (ion_dict_cursor_t **cursor)
 Destroys and frees the given cursor. More...
 
ion_err_t ffdict_open_dictionary (ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_config_info_t *config, ion_dictionary_compare_t compare)
 Re-instances a previously created flat file store instance and prepares it to be used again. More...
 
ion_err_t ffdict_close_dictionary (ion_dictionary_t *dictionary)
 Closes this flat file store and persists everything to disk to be brought back later using dictionary_open. More...
 
ion_err_t ffdict_find (ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
 Initializes a cursor query and returns an allocated cursor object. More...
 
void ffdict_init (ion_dictionary_handler_t *handler)
 Given the handler instance, bind the appropriate flat file functions. More...
 
ion_status_t ffdict_insert (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Given a record ( key, value ), insert it into the dictionary. More...
 
ion_status_t ffdict_get (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Performs a "get" operation on the dictionary to retrieve a single record. More...
 
ion_err_t ffdict_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 flat file backed dictionary. More...
 
ion_status_t ffdict_delete (ion_dictionary_t *dictionary, ion_key_t key)
 Removes all instances of any record with key equal to key. More...
 
ion_err_t ffdict_delete_dictionary (ion_dictionary_t *dictionary)
 Cleans up all files created by the dictionary, and frees any allocated memory. More...
 
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 dictionary. More...
 
ion_status_t ffdict_update (ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
 Updates all records stored at key to have value equal to value. More...
 

Function Documentation

ion_err_t ffdict_close_dictionary ( ion_dictionary_t dictionary)

Closes this flat file store and persists everything to disk to be brought back later using dictionary_open.

Parameters
[in]dictionaryWhich instance of a flat file store to close.
Returns
The resuling status of the operation.

Definition at line 178 of file flat_file_dictionary_handler.c.

180  {
181  ion_err_t err = flat_file_close((ion_flat_file_t *) dictionary->instance);
182 
183  free(dictionary->instance);
184  dictionary->instance = NULL;
185 
186  if (err_ok != err) {
187  return err;
188  }
189 
190  return err_ok;
191 }
Metadata container that holds flat file specific information.
ion_dictionary_parent_t * instance
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
ion_err_t flat_file_close(ion_flat_file_t *flat_file)
Closes and frees any memory associated with the flat file.
Definition: flat_file.c:624

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t ffdict_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 flat file backed dictionary.

Parameters
[in]idThe ID to assign to the dictionary. This is either user defined or is given by the master table.
[in]key_typeThe category of key used by the dictionary. See ION_KEY_TYPE for more information.
[in]key_sizeThe size of the keys used for this dictionary, specified in bytes. It is strongly recommended to use a sizeof() directive to specify this size to avoid painful problems.
[in]value_sizeSame as above, for values.
[in]dictionary_sizeDesignates how many records we buffer in memory. Higher means better overall performance at the cost of increased memory usage.
[in]compareThe function pointer that designates how to compare two keys. This is given by the upper dictionary layers.
[in]handlerThe allocated, initialized handler that will be bound to the dictionary instance.
[in]dictionaryThe allocated dictionary instance that we are going to initialize.
Returns
The resulting status of the operation.

Definition at line 398 of file flat_file_dictionary_handler.c.

407  {
408  dictionary->instance = malloc(sizeof(ion_flat_file_t));
409 
410  if (NULL == dictionary->instance) {
411  return err_out_of_memory;
412  }
413 
414  dictionary->instance->compare = compare;
416 
417  ion_err_t result = flat_file_initialize((ion_flat_file_t *) dictionary->instance, id, key_type, key_size, value_size, dictionary_size);
418 
419  if ((err_ok == result) && (NULL != handler)) {
420  dictionary->handler = handler;
421  }
422 
423  return result;
424 }
Metadata container that holds flat file specific information.
ion_err_t flat_file_initialize(ion_flat_file_t *flat_file, 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)
Initializes the flat file implementation and creates all necessary files.
Definition: flat_file.c:40
ion_dictionary_handler_t * handler
ion_dictionary_parent_t * instance
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
ion_dictionary_type_t type
ion_dictionary_compare_t compare

Here is the call graph for this function:

Here is the caller graph for this function:

ion_status_t ffdict_delete ( ion_dictionary_t dictionary,
ion_key_t  key 
)

Removes all instances of any record with key equal to key.

Parameters
[in]dictionaryWhich dictionary to delete from.
[in]keyDesignated key to look for and remove.
Returns
The resulting status of the operation.

Definition at line 427 of file flat_file_dictionary_handler.c.

430  {
431  return flat_file_delete((ion_flat_file_t *) dictionary->instance, key);
432 }
Metadata container that holds flat file specific information.
ion_dictionary_parent_t * instance
#define key(k)
Definition: bpp_tree.c:75
ion_status_t flat_file_delete(ion_flat_file_t *flat_file, ion_key_t key)
Deletes all records stored with the given key.
Definition: flat_file.c:495

Here is the call graph for this function:

Here is the caller graph for this function:

ion_err_t ffdict_delete_dictionary ( ion_dictionary_t dictionary)

Cleans up all files created by the dictionary, and frees any allocated memory.

Parameters
[in]dictionaryWhich dictionary instance to delete.
Returns
The resulting status of the operation.

Definition at line 435 of file flat_file_dictionary_handler.c.

437  {
438  ion_err_t result = flat_file_destroy((ion_flat_file_t *) dictionary->instance);
439 
440  free(dictionary->instance);
441  dictionary->instance = NULL;
442  return result;
443 }
Metadata container that holds flat file specific information.
ion_err_t flat_file_destroy(ion_flat_file_t *flat_file)
Destroys and cleans up any implementation specific memory or files.
Definition: flat_file.c:134
ion_dictionary_parent_t * instance
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226

Here is the call graph for this function:

Here is the caller graph for this function:

void ffdict_destroy_cursor ( ion_dict_cursor_t **  cursor)

Destroys and frees the given cursor.

This function should not be called directly, but instead accessed through the interface the cursor object.

Parameters
[in]cursorWhich cursor to destroy.

Definition at line 134 of file flat_file_dictionary_handler.c.

136  {
137  (*cursor)->predicate->destroy(&(*cursor)->predicate);
138  free(*cursor);
139  *cursor = NULL;
140 }

Here is the caller graph for this function:

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 dictionary.

Parameters
[in]idThe identifier identifying the dictionary to delete.
Returns
The resulting status of the operation.

Definition at line 446 of file flat_file_dictionary_handler.c.

448  {
449  char filename[ION_MAX_FILENAME_LENGTH];
450 
451  dictionary_get_filename(id, "ffs", filename);
452 
453  if (0 != fremove(filename)) {
454  return err_file_delete_error;
455  }
456 
457  return err_ok;
458 }
#define fremove(x)
Definition: kv_system.h:56
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
#define ION_MAX_FILENAME_LENGTH
Since the arduino conforms to 8.3 syntax, that'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 ffdict_find ( ion_dictionary_t dictionary,
ion_predicate_t predicate,
ion_dict_cursor_t **  cursor 
)

Initializes a cursor query and returns an allocated cursor object.

Given a predicate that was previously initialized by dictionary_build_predicate, Build a cursor object that acts as the iterator for the desired query through the dictionary.

Parameters
[in]dictionaryWhich dictionary to query on.
[in]predicateAn allocated, initialized predicate object that defines the parameters of the query.
[out]cursorA cursor pointer should be initialized to NULL, and then given to this function. This function shall allocate appropriate memory and redirect cursor to point to the allocated memory. NOTE: Anything originally pointed to by this cursor will effectively be lost, if there is no other reference to said thing.
Returns
The resulting status of the operation.

Definition at line 209 of file flat_file_dictionary_handler.c.

213  {
214  *cursor = malloc(sizeof(ion_flat_file_cursor_t));
215 
216  ion_flat_file_t *flat_file = (ion_flat_file_t *) dictionary->instance;
217 
218  if (NULL == *cursor) {
219  return err_out_of_memory;
220  }
221 
222  (*cursor)->dictionary = dictionary;
223  (*cursor)->status = cs_cursor_uninitialized;
224 
225  (*cursor)->destroy = ffdict_destroy_cursor;
226  (*cursor)->next = ffdict_next;
227 
228  (*cursor)->predicate = malloc(sizeof(ion_predicate_t));
229 
230  if (NULL == (*cursor)->predicate) {
231  free(*cursor);
232  return err_out_of_memory;
233  }
234 
235  (*cursor)->predicate->type = predicate->type;
236  (*cursor)->predicate->destroy = predicate->destroy;
237 
238  ion_key_size_t key_size = dictionary->instance->record.key_size;
239 
240  switch (predicate->type) {
241  case predicate_equality: {
242  ion_key_t target_key = predicate->statement.equality.equality_value;
243 
244  (*cursor)->predicate->statement.equality.equality_value = malloc(key_size);
245 
246  if (NULL == (*cursor)->predicate->statement.equality.equality_value) {
247  free((*cursor)->predicate);
248  free(*cursor);
249  return err_out_of_memory;
250  }
251 
252  memcpy((*cursor)->predicate->statement.equality.equality_value, target_key, key_size);
253 
254  ion_fpos_t loc = -1;
256  ion_err_t scan_result = flat_file_scan(flat_file, -1, &loc, &row, ION_FLAT_FILE_SCAN_FORWARDS, flat_file_predicate_key_match, target_key);
257 
258  if (err_file_hit_eof == scan_result) {
259  /* If this happens, that means the target key doesn't exist */
260  (*cursor)->status = cs_end_of_results;
261  return err_ok;
262  }
263  else if (err_ok == scan_result) {
264  (*cursor)->status = cs_cursor_initialized;
265 
266  ion_flat_file_cursor_t *flat_file_cursor = (ion_flat_file_cursor_t *) (*cursor);
267 
268  flat_file_cursor->current_location = loc;
269  return err_ok;
270  }
271  else {
272  /* File scan hit an error condition */
273  return scan_result;
274  }
275 
276  break;
277  }
278 
279  case predicate_range: {
280  (*cursor)->predicate->statement.range.lower_bound = malloc(key_size);
281 
282  if (NULL == (*cursor)->predicate->statement.range.lower_bound) {
283  free((*cursor)->predicate);
284  free(*cursor);
285  return err_out_of_memory;
286  }
287 
288  memcpy((*cursor)->predicate->statement.range.lower_bound, predicate->statement.range.lower_bound, key_size);
289 
290  (*cursor)->predicate->statement.range.upper_bound = malloc(key_size);
291 
292  if (NULL == (*cursor)->predicate->statement.range.upper_bound) {
293  free((*cursor)->predicate->statement.range.lower_bound);
294  free((*cursor)->predicate);
295  free(*cursor);
296  return err_out_of_memory;
297  }
298 
299  memcpy((*cursor)->predicate->statement.range.upper_bound, predicate->statement.range.upper_bound, key_size);
300 
301  /* Find the first satisfactory key. */
302  ion_fpos_t loc = -1;
304  ion_err_t scan_result = flat_file_scan(flat_file, -1, &loc, &row, ION_FLAT_FILE_SCAN_FORWARDS, flat_file_predicate_within_bounds, (*cursor)->predicate->statement.range.lower_bound, (*cursor)->predicate->statement.range.upper_bound);
305 
306  if (err_file_hit_eof == scan_result) {
307  /* This means the returned node is smaller than the lower bound, which means that there are no valid records to return */
308  (*cursor)->status = cs_end_of_results;
309  return err_ok;
310  }
311  else if (err_ok == scan_result) {
312  (*cursor)->status = cs_cursor_initialized;
313 
314  ion_flat_file_cursor_t *flat_file_cursor = (ion_flat_file_cursor_t *) (*cursor);
315 
316  flat_file_cursor->current_location = loc;
317  return err_ok;
318  }
319  else {
320  /* Scan failed due to external error */
321  return scan_result;
322  }
323 
324  break;
325  }
326 
327  case predicate_all_records: {
328  ion_flat_file_cursor_t *flat_file_cursor = (ion_flat_file_cursor_t *) (*cursor);
329 
330  ion_fpos_t loc = -1;
332  ion_err_t scan_result = flat_file_scan(flat_file, -1, &loc, &row, ION_FLAT_FILE_SCAN_FORWARDS, flat_file_predicate_not_empty);
333 
334  if (err_file_hit_eof == scan_result) {
335  (*cursor)->status = cs_end_of_results;
336  }
337  else if (err_ok == scan_result) {
338  flat_file_cursor->current_location = loc;
339  (*cursor)->status = cs_cursor_initialized;
340  }
341  else {
342  /* Scan failure */
343  return scan_result;
344  }
345 
346  return err_ok;
347  break;
348  }
349 
350  case predicate_predicate: {
351  break;
352  }
353 
354  default: {
355  return err_invalid_predicate;
356  break;
357  }
358  }
359 
360  return err_ok;
361 }
ion_record_info_t record
Container for the rows written in the flat file data file.
Metadata container that holds flat file specific information.
ion_predicate_statement_t statement
ion_dictionary_parent_t * instance
ion_boolean_t flat_file_predicate_within_bounds(ion_flat_file_t *flat_file, ion_flat_file_row_t *row, va_list *args)
Predicate function to return any row that has a key such that lower_bound <= key <= upper_bound holds...
Definition: flat_file.c:291
char ion_err_t
The error type used to store error codes.
Definition: kv_system.h:226
void * ion_key_t
A dictionary key.
Definition: kv_system.h:241
void(* destroy)(ion_predicate_t **)
ion_equality_statement_t equality
ion_err_t flat_file_scan(ion_flat_file_t *flat_file, ion_fpos_t start_location, ion_fpos_t *location, ion_flat_file_row_t *row, ion_byte_t scan_direction, ion_flat_file_predicate_t predicate,...)
Performs a linear scan of the flat file writing the first location seen that satisfies the given pred...
Definition: flat_file.c:157
ion_predicate_type_t type
Implementation cursor type for the flat file store cursor.
ion_cursor_status_t ffdict_next(ion_dict_cursor_t *cursor, ion_record_t *record)
Fetches the next record to be returned from a cursor that has already been initialized.
ion_key_size_t key_size
Definition: kv_system.h:307
void ffdict_destroy_cursor(ion_dict_cursor_t **cursor)
Destroys and frees the given cursor.
A supertype for cursor predicate objects.
#define ION_FLAT_FILE_SCAN_FORWARDS
Signals to flat_file_scan to scan in a forward direction.
ion_boolean_t flat_file_predicate_key_match(ion_flat_file_t *flat_file, ion_flat_file_row_t *row, va_list *args)
Predicate function to return any row that has an exact match to the given target key.
Definition: flat_file.c:280
long ion_fpos_t
A file position type.
Definition: kv_system.h:237
int ion_key_size_t
The size (length) of a dictionary key in bytes.
Definition: kv_system.h:251
ion_boolean_t flat_file_predicate_not_empty(ion_flat_file_t *flat_file, ion_flat_file_row_t *row, va_list *args)
Predicate function to return any row that is not empty or deleted.
Definition: flat_file.c:268
ion_range_statement_t range
ion_dictionary_status_t status

Here is the call graph for this function:

Here is the caller graph for this function:

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

Performs a "get" operation on the dictionary to retrieve a single record.

Given a key, returns the associated value stored under that key. If there are duplicate records all with the same key, the exact one that is returned is undefined. If you need to get all records stored under a specific key, use a cursor query.

Parameters
[in]dictionaryWhich dictionary to perform the operation on.
[in]keyThe desired search key.
[out]valueThe output location in which to write the returned value. This space must be allocated by the user to at least value_size bytes, as originally defined on dictionary creation.
Returns
The resulting status of the operation.

Definition at line 389 of file flat_file_dictionary_handler.c.

393  {
394  return flat_file_get((ion_flat_file_t *) dictionary->instance, key, value);
395 }
ion_status_t flat_file_get(ion_flat_file_t *flat_file, ion_key_t key, ion_value_t value)
Fetches the record stored with the given key.
Definition: flat_file.c:439
Metadata container that holds flat file specific information.
ion_dictionary_parent_t * instance
#define key(k)
Definition: bpp_tree.c:75

Here is the call graph for this function:

Here is the caller graph for this function:

void ffdict_init ( ion_dictionary_handler_t handler)

Given the handler instance, bind the appropriate flat file functions.

Parameters
[in]handlerThe handler is assumed to be memory that is allocated and initialized by the user.

Definition at line 364 of file flat_file_dictionary_handler.c.

366  {
367  handler->insert = ffdict_insert;
369  handler->get = ffdict_get;
370  handler->update = ffdict_update;
371  handler->find = ffdict_find;
372  handler->remove = ffdict_delete;
377 }
ion_status_t ffdict_delete(ion_dictionary_t *dictionary, ion_key_t key)
Removes all instances of any record with key equal to key.
ion_status_t(* insert)(ion_dictionary_t *, ion_key_t, ion_value_t)
ion_status_t ffdict_update(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Updates all records stored at key to have value equal to value.
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 ffdict_find(ion_dictionary_t *dictionary, ion_predicate_t *predicate, ion_dict_cursor_t **cursor)
Initializes a cursor query and returns an allocated cursor object.
ion_status_t(* remove)(ion_dictionary_t *, ion_key_t)
ion_err_t(* destroy_dictionary)(ion_dictionary_id_t id)
ion_err_t ffdict_open_dictionary(ion_dictionary_handler_t *handler, ion_dictionary_t *dictionary, ion_dictionary_config_info_t *config, ion_dictionary_compare_t compare)
Re-instances a previously created flat file store instance and prepares it to be used again...
ion_err_t ffdict_close_dictionary(ion_dictionary_t *dictionary)
Closes this flat file store and persists everything to disk to be brought back later using dictionary...
ion_status_t ffdict_get(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Performs a "get" operation on the dictionary to retrieve a single record.
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_err_t(* delete_dictionary)(ion_dictionary_t *)
ion_err_t ffdict_delete_dictionary(ion_dictionary_t *dictionary)
Cleans up all files created by the dictionary, and frees any allocated memory.
ion_err_t(* find)(ion_dictionary_t *, ion_predicate_t *, ion_dict_cursor_t **)
ion_status_t ffdict_insert(ion_dictionary_t *dictionary, ion_key_t key, ion_value_t value)
Given a record ( key, value ), insert it into the dictionary.
ion_err_t ffdict_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 flat file backed 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 ffdict_insert ( ion_dictionary_t dictionary,
ion_key_t  key,
ion_value_t  value 
)

Given a record ( key, value ), insert it into the dictionary.

Parameters
[in]dictionaryThe initialized dictionary instance we want to insert into.
[in]keyThe key portion of the record to be inserted.
[in]valueThe value portion of the record to be inserted.
Returns
The resulting status of the operation.

Definition at line 380 of file flat_file_dictionary_handler.c.

384  {
385  return flat_file_insert((ion_flat_file_t *) dictionary->instance, key, value);
386 }
Metadata container that holds flat file specific information.
ion_dictionary_parent_t * instance
#define key(k)
Definition: bpp_tree.c:75
ion_status_t flat_file_insert(ion_flat_file_t *flat_file, ion_key_t key, ion_value_t value)
Inserts the given record into the flat file store.
Definition: flat_file.c:388

Here is the call graph for this function:

Here is the caller graph for this function:

ion_cursor_status_t ffdict_next ( ion_dict_cursor_t cursor,
ion_record_t record 
)

Fetches the next record to be returned from a cursor that has already been initialized.

The returned record is written back to record, and then the cursor is advanced to the next record. The returned status code signifies whether or not there are more results to traverse. This function should not be called directly, but instead will be bound to the cursor like a method.

Parameters
[in]cursorWhich cursor to fetch results from.
[out]recordAn initialized record struct with the key and value appropriately allocated to fit the returned key and value. This function will write back data to the struct.
Returns
The resulting status of the operation.

Definition at line 53 of file flat_file_dictionary_handler.c.

56  {
57  ion_flat_file_t *flat_file = (ion_flat_file_t *) cursor->dictionary->instance;
58  ion_flat_file_cursor_t *flat_file_cursor = (ion_flat_file_cursor_t *) cursor;
59 
60  if (cursor->status == cs_cursor_uninitialized) {
61  return cursor->status;
62  }
63  else if (cursor->status == cs_end_of_results) {
64  return cursor->status;
65  }
66  else if ((cursor->status == cs_cursor_initialized) || (cursor->status == cs_cursor_active)) {
67  if (cursor->status == cs_cursor_active) {
68  ion_flat_file_row_t throwaway_row;
70 
71  switch (cursor->predicate->type) {
72  case predicate_equality: {
73  err = flat_file_scan(flat_file, flat_file_cursor->current_location + 1, &flat_file_cursor->current_location, &throwaway_row, ION_FLAT_FILE_SCAN_FORWARDS, flat_file_predicate_key_match, cursor->predicate->statement.equality.equality_value);
74 
75  break;
76  }
77 
78  case predicate_range: {
79  err = flat_file_scan(flat_file, flat_file_cursor->current_location + 1, &flat_file_cursor->current_location, &throwaway_row, ION_FLAT_FILE_SCAN_FORWARDS, flat_file_predicate_within_bounds, cursor->predicate->statement.range.lower_bound, cursor->predicate->statement.range.upper_bound);
80 
81  break;
82  }
83 
84  case predicate_all_records: {
85  err = flat_file_scan(flat_file, flat_file_cursor->current_location + 1, &flat_file_cursor->current_location, &throwaway_row, ION_FLAT_FILE_SCAN_FORWARDS, flat_file_predicate_not_empty);
86 
87  break;
88  }
89 
90  case predicate_predicate: {
91  break;
92  }
93  }
94 
95  if (err_file_hit_eof == err) {
96  cursor->status = cs_end_of_results;
97  return cursor->status;
98  }
99  else if (err_ok != err) {
101  return cursor->status;
102  }
103  }
104  else {
105  /* The status is cs_cursor_initialized */
106  cursor->status = cs_cursor_active;
107  }
108 
110  ion_err_t err = flat_file_read_row(flat_file, flat_file_cursor->current_location, &row);
111 
112  if (err_ok != err) {
113  return cs_invalid_index;
114  }
115 
116  /*Copy both key and value into user provided struct */
117  memcpy(record->key, row.key, cursor->dictionary->instance->record.key_size);
118  memcpy(record->value, row.value, cursor->dictionary->instance->record.value_size);
119 
120  return cursor->status;
121  }
122 
123  return cs_invalid_cursor;
124 }
ion_record_info_t record
Container for the rows written in the flat file data file.
Metadata container that holds flat file specific information.
ion_predicate_t * predicate
ion_predicate_statement_t statement
ion_dictionary_parent_t * instance
ion_value_t value
Definition: kv_system.h:318
ion_dictionary_t * dictionary
ion_boolean_t flat_file_predicate_within_bounds(ion_flat_file_t *flat_file, ion_flat_file_row_t *row, va_list *args)
Predicate function to return any row that has a key such that lower_bound <= key <= upper_bound holds...
Definition: flat_file.c:291
ion_cursor_status_t status
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 flat_file_read_row(ion_flat_file_t *flat_file, ion_fpos_t location, ion_flat_file_row_t *row)
Reads the row specified by the given location into the buffer.
Definition: flat_file.c:350
ion_equality_statement_t equality
ion_err_t flat_file_scan(ion_flat_file_t *flat_file, ion_fpos_t start_location, ion_fpos_t *location, ion_flat_file_row_t *row, ion_byte_t scan_direction, ion_flat_file_predicate_t predicate,...)
Performs a linear scan of the flat file writing the first location seen that satisfies the given pred...
Definition: flat_file.c:157
ion_predicate_type_t type
Implementation cursor type for the flat file store cursor.
ion_key_size_t key_size
Definition: kv_system.h:307
#define ION_FLAT_FILE_SCAN_FORWARDS
Signals to flat_file_scan to scan in a forward direction.
ion_boolean_t flat_file_predicate_key_match(ion_flat_file_t *flat_file, ion_flat_file_row_t *row, va_list *args)
Predicate function to return any row that has an exact match to the given target key.
Definition: flat_file.c:280
ion_boolean_t flat_file_predicate_not_empty(ion_flat_file_t *flat_file, ion_flat_file_row_t *row, va_list *args)
Predicate function to return any row that is not empty or deleted.
Definition: flat_file.c:268
ion_range_statement_t range
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_err_t ffdict_open_dictionary ( ion_dictionary_handler_t handler,
ion_dictionary_t dictionary,
ion_dictionary_config_info_t config,
ion_dictionary_compare_t  compare 
)

Re-instances a previously created flat file store instance and prepares it to be used again.

Parameters
[in]handlerA handler that must be bound with the flat file's functions.
[in]dictionaryA dictionary that is allocated but not initialized. We will store the details of the re-instanced flat file store in here.
[in]configThe configuration parameters previously used by the flat file store we are opening. This must either be provided directly if dictionaries are being managed manually, or will be provided by the dictionary manager that is currently in use.
[in]compareThe comparison function that will be given by higher layers, based on the destined key type.
Returns
The resulting status of the operation.

Definition at line 161 of file flat_file_dictionary_handler.c.

166  {
167  return ffdict_create_dictionary(config->id, config->type, config->key_size, config->value_size, config->dictionary_size, compare, handler, dictionary);
168 }
ion_err_t ffdict_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 flat file backed 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 ffdict_update ( ion_dictionary_t dictionary,
ion_key_t  key,
ion_value_t  value 
)

Updates all records stored at key to have value equal to value.

If no records are stored at key, then an "upsert" (insert instead of update) is performed.

Parameters
[in]dictionaryWhich dictionary to update.
[in]keyTarget key to update.
[in]valueNew value to update to.
Returns
The resulting status of the operation.

Definition at line 461 of file flat_file_dictionary_handler.c.

465  {
466  return flat_file_update((ion_flat_file_t *) dictionary->instance, key, value);
467 }
Metadata container that holds flat file specific information.
ion_status_t flat_file_update(ion_flat_file_t *flat_file, ion_key_t key, ion_value_t value)
Updates all records stored with the given key to have value.
Definition: flat_file.c:560
ion_dictionary_parent_t * instance
#define key(k)
Definition: bpp_tree.c:75

Here is the call graph for this function:

Here is the caller graph for this function: