db_insert.c

Go to the documentation of this file.
00001 
00011 #define _GNU_SOURCE
00012 
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <errno.h>
00017 
00018 #include "odb.h"
00019 
00020 
00021 static inline int add_node(odb_data_t * data, odb_key_t key, odb_value_t value)
00022 {
00023     odb_index_t new_node;
00024     odb_node_t * node;
00025     odb_index_t index;
00026 
00027     /* no locking is necessary: iteration interface retrieve data through
00028      * the node_base array, we doesn't increase current_size now but it's
00029      * done by odb_commit_reservation() so the new slot is visible only
00030      * after the increment
00031      */
00032     if (data->descr->current_size >= data->descr->size) {
00033         if (odb_grow_hashtable(data))
00034             return EINVAL;
00035     }
00036     new_node = data->descr->current_size;
00037 
00038     node = &data->node_base[new_node];
00039     node->value = value;
00040     node->key = key;
00041 
00042     index = odb_do_hash(data, key);
00043     node->next = data->hash_base[index];
00044     data->hash_base[index] = new_node;
00045 
00046     /* FIXME: we need wrmb() here */
00047     odb_commit_reservation(data);
00048 
00049     return 0;
00050 }
00051 
00052 int odb_update_node(odb_t * odb, odb_key_t key)
00053 {
00054     return odb_update_node_with_offset(odb, key, 1);
00055 }
00056 
00057 int odb_update_node_with_offset(odb_t * odb, 
00058                 odb_key_t key, 
00059                 unsigned long int offset)
00060 {
00061     odb_index_t index;
00062     odb_node_t * node;
00063     odb_data_t * data;
00064 
00065     data = odb->data;
00066     index = data->hash_base[odb_do_hash(data, key)];
00067     while (index) {
00068         node = &data->node_base[index];
00069         if (node->key == key) {
00070             if (node->value + offset != 0) {
00071                 node->value += offset;
00072             } else {
00073                 /* post profile tools must handle overflow */
00074                 /* FIXME: the tricky way will be just to add
00075                  * a goto to jump right before the return
00076                  * add_node(), in this way we no longer can
00077                  * overflow. It'll work because new node are
00078                  * linked at the start of the node list for
00079                  * this bucket so this loop will see first a
00080                  * non overflowed node if one exist. When we
00081                  * grow the hashtable the most recently
00082                  * allocated node for this key will be setup
00083                  * last, so again it'll be linked at start of
00084                  * the list. pp tools looke like ok with this
00085                  * change.
00086                  *
00087                  * This change doesn't involve any file format
00088                  * change but perhaps it's a bit hacky to do
00089                  * this w/o bumping the sample file format
00090                  * version. The drawback of this is the added
00091                  * node are additive not multiplicative.
00092                  * (multiplicative as if we add more bits to
00093                  * store a value)
00094                  */
00095             }
00096             return 0;
00097         }
00098 
00099         index = node->next;
00100     }
00101 
00102     return add_node(data, key, offset);
00103 }
00104 
00105 
00106 int odb_add_node(odb_t * odb, odb_key_t key, odb_value_t value)
00107 {
00108     return add_node(odb->data, key, value);
00109 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1