1 /** 2 * @file db_insert.c 3 * Inserting a key-value pair into a DB 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Philippe Elie 9 */ 10 11 #define _GNU_SOURCE 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <errno.h> 17 18 #include "odb.h" 19 20 21 static inline int add_node(odb_data_t * data, odb_key_t key, odb_value_t value) 22 { 23 odb_index_t new_node; 24 odb_node_t * node; 25 odb_index_t index; 26 27 /* no locking is necessary: iteration interface retrieve data through 28 * the node_base array, we doesn't increase current_size now but it's 29 * done by odb_commit_reservation() so the new slot is visible only 30 * after the increment 31 */ 32 if (data->descr->current_size >= data->descr->size) { 33 if (odb_grow_hashtable(data)) 34 return EINVAL; 35 } 36 new_node = data->descr->current_size; 37 38 node = &data->node_base[new_node]; 39 node->value = value; 40 node->key = key; 41 42 index = odb_do_hash(data, key); 43 node->next = data->hash_base[index]; 44 data->hash_base[index] = new_node; 45 46 /* FIXME: we need wrmb() here */ 47 odb_commit_reservation(data); 48 49 return 0; 50 } 51 52 int odb_update_node(odb_t * odb, odb_key_t key) 53 { 54 return odb_update_node_with_offset(odb, key, 1); 55 } 56 57 int odb_update_node_with_offset(odb_t * odb, 58 odb_key_t key, 59 unsigned long int offset) 60 { 61 odb_index_t index; 62 odb_node_t * node; 63 odb_data_t * data; 64 65 data = odb->data; 66 index = data->hash_base[odb_do_hash(data, key)]; 67 while (index) { 68 node = &data->node_base[index]; 69 if (node->key == key) { 70 if (node->value + offset != 0) { 71 node->value += offset; 72 } else { 73 /* post profile tools must handle overflow */ 74 /* FIXME: the tricky way will be just to add 75 * a goto to jump right before the return 76 * add_node(), in this way we no longer can 77 * overflow. It'll work because new node are 78 * linked at the start of the node list for 79 * this bucket so this loop will see first a 80 * non overflowed node if one exist. When we 81 * grow the hashtable the most recently 82 * allocated node for this key will be setup 83 * last, so again it'll be linked at start of 84 * the list. pp tools looke like ok with this 85 * change. 86 * 87 * This change doesn't involve any file format 88 * change but perhaps it's a bit hacky to do 89 * this w/o bumping the sample file format 90 * version. The drawback of this is the added 91 * node are additive not multiplicative. 92 * (multiplicative as if we add more bits to 93 * store a value) 94 */ 95 } 96 return 0; 97 } 98 99 index = node->next; 100 } 101 102 return add_node(data, key, offset); 103 } 104 105 106 int odb_add_node(odb_t * odb, odb_key_t key, odb_value_t value) 107 { 108 return add_node(odb->data, key, value); 109 } 110