blob: 2c99640707a4edceb0050c3ef55d092210859e26 [file] [log] [blame]
/**
* @file db_insert.c
* Inserting a key-value pair into a DB
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author Philippe Elie
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "odb.h"
int odb_insert(odb_t * odb, odb_key_t key, odb_value_t value)
{
odb_index_t index;
odb_index_t new_node;
odb_node_t * node;
odb_data_t * data;
data = odb->data;
index = data->hash_base[odb_do_hash(data, key)];
while (index) {
if (index <= 0 || index >= data->descr->current_size) {
return EINVAL;
}
node = &data->node_base[index];
if (node->key == key) {
if (node->value + value >= node->value) {
node->value += value;
} else {
/* post profile tools must handle overflow */
node->value = ~(odb_value_t)0;
}
return 0;
}
index = node->next;
}
/* no locking is necessary: iteration interface retrieve data through
* the node_base array, odb_hash_add_node() increase current_size but
* odb_travel just ignore node with a zero key so on setting the key
* atomically update the node */
new_node = odb_hash_add_node(odb);
if (new_node == ODB_NODE_NR_INVALID) {
return EINVAL;
}
node = &data->node_base[new_node];
node->value = value;
node->key = key;
/* we need to recalculate hash code, hash table has perhaps grown */
index = odb_do_hash(data, key);
node->next = data->hash_base[index];
data->hash_base[index] = new_node;
return 0;
}