return;
}
+ if(debug) fprintf(stderr, "apps.plugin: decreasing slot %d (count = %ld).\n", id, all_files[id].count);
+
if(all_files[id].count > 0) {
all_files[id].count--;
if(!all_files[id].count) {
+ if(debug) fprintf(stderr, "apps.plugin: >> slot %d is empty.\n", id);
file_descriptor_remove(&all_files[id]);
all_files[id].magic = 0x00000000;
all_files_len--;
struct file_descriptor *fd = file_descriptor_find(name, hash);
if(fd) {
// found
+ if(debug) fprintf(stderr, "apps.plugin: >> found on slot %ld\n", fd->pos);
fd->count++;
return fd->pos;
}
// if the address changed, we have to rebuild the index
// since all pointers are now invalid
if(old && old != (void *)all_files) {
- if(debug) fprintf(stderr, "apps.plugin: re-indexing.\n");
+ if(debug) fprintf(stderr, "apps.plugin: >> re-indexing.\n");
all_files_index.root = NULL;
int i;
for(i = 0; i < all_files_size; i++) {
if(!all_files[i].count) continue;
file_descriptor_add(&all_files[i]);
}
+ for(i = all_files_size; i < (all_files_size + FILE_DESCRIPTORS_INCREASE_STEP); i++) {
+ all_files[i].count = 0;
+ all_files[i].name = NULL;
+ all_files[i].magic = 0x00000000;
+ all_files[i].pos = i;
+ }
+ if(debug) fprintf(stderr, "apps.plugin: >> re-indexing done.\n");
}
if(!all_files_size) all_files_len = 1;
all_files_size += FILE_DESCRIPTORS_INCREASE_STEP;
}
+ if(debug) fprintf(stderr, "apps.plugin: >> searching for empty slot.\n");
+
// search for an empty slot
int i, c;
for(i = 0, c = last_pos ; i < all_files_size ; i++, c++) {
if(c == 0) continue;
if(!all_files[c].count) {
+ if(debug) fprintf(stderr, "apps.plugin: >> eximining slot %d.\n", c);
+
if(all_files[c].magic == 0x0BADCAFE && all_files[c].name && file_descriptor_find(all_files[c].name, all_files[c].hash))
error("apps.plugin: fd on position %d is not cleared properly. It still has %s in it.\n", c, all_files[c].name);
- if(debug) fprintf(stderr, "apps.plugin: re-using fd position %d for %s (last name: %s)\n", c, name, all_files[c].name);
+ if(debug) fprintf(stderr, "apps.plugin: >> %s fd position %d for %s (last name: %s)\n", all_files[c].name?"re-using":"using", c, name, all_files[c].name);
if(all_files[c].name) free((void *)all_files[c].name);
all_files[c].name = NULL;
break;
error("We should find an empty slot, but there isn't any");
return 0;
}
+ if(debug) fprintf(stderr, "apps.plugin: >> updating slot %d.\n", c);
+
all_files_len++;
// else we have an empty slot in 'c'
+#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
return result;
}
+// ----------------------------------------------------------------------------
+// RRDSET name index
+
+#define rrdset_from_avlname(avlname_ptr) ((RRDSET *)((avlname_ptr) - offsetof(RRDSET, avlname)))
+
+static int rrdset_iterator_name(avl *a) { if(a) {}; return 0; }
+
+static int rrdset_compare_name(void* a, void* b) {
+ RRDSET *A = rrdset_from_avlname(a);
+ RRDSET *B = rrdset_from_avlname(b);
+
+ // fprintf(stderr, "COMPARING: %s with %s\n", A->name, B->name);
+
+ if(A->hash_name < B->hash_name) return -1;
+ else if(A->hash_name > B->hash_name) return 1;
+ else return strcmp(A->name, B->name);
+}
+
+avl_tree rrdset_root_index_name = {
+ NULL,
+ rrdset_compare_name
+};
+
+int rrdset_index_add_name(RRDSET *st) {
+ // fprintf(stderr, "ADDING: %s (name: %s)\n", st->id, st->name);
+ return avl_insert(&rrdset_root_index_name, (avl *)(&st->avlname));
+}
+
+#define rrdset_index_del_name(st) avl_remove(&rrdset_root_index_name, (avl *)(&st->avlname))
+
+static RRDSET *rrdset_index_find_name(const char *name, unsigned long hash) {
+ void *result = NULL;
+ RRDSET tmp;
+ tmp.name = name;
+ tmp.hash_name = (hash)?hash:simple_hash(tmp.name);
+
+ // fprintf(stderr, "SEARCHING: %s\n", name);
+ avl_search(&(rrdset_root_index_name), (avl *)(&(tmp.avlname)), rrdset_iterator_name, (avl **)&result);
+ if(result) {
+ RRDSET *st = rrdset_from_avlname(result);
+ if(strcmp(st->magic, RRDSET_MAGIC))
+ error("Search for RRDSET %s returned an invalid RRDSET %s (name %s)", name, st->id, st->name);
+
+ // fprintf(stderr, "FOUND: %s\n", name);
+ return rrdset_from_avlname(result);
+ }
+ // fprintf(stderr, "NOT FOUND: %s\n", name);
+ return NULL;
+}
+
+
// ----------------------------------------------------------------------------
// RRDDIM index
void rrdset_set_name(RRDSET *st, const char *name)
{
+ debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
+
+ if(st->name) rrdset_index_del_name(st);
+
char b[CONFIG_MAX_VALUE + 1];
char n[RRD_ID_LENGTH_MAX + 1];
rrdset_strncpy_name(b, n, CONFIG_MAX_VALUE);
st->name = config_get(st->id, "name", b);
st->hash_name = simple_hash(st->name);
+
+ rrdset_index_add_name(st);
}
// ----------------------------------------------------------------------------
void rrdset_reset(RRDSET *st)
{
+ debug(D_RRD_CALLS, "rrdset_reset() %s", st->name);
+
st->last_collected_time.tv_sec = 0;
st->last_collected_time.tv_usec = 0;
st->last_updated.tv_sec = 0;
st->type = config_get(st->id, "type", type);
st->chart_type = rrdset_type_id(config_get(st->id, "chart type", rrdset_type_name(chart_type)));
- if(name && *name) rrdset_set_name(st, name);
- else rrdset_set_name(st, id);
-
- {
- char varvalue[CONFIG_MAX_VALUE + 1];
- snprintf(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
- st->title = config_get(st->id, "title", varvalue);
- }
-
st->priority = config_get_number(st->id, "priority", priority);
st->enabled = enabled;
pthread_rwlock_init(&st->rwlock, NULL);
pthread_rwlock_wrlock(&rrdset_root_rwlock);
+ if(name && *name) rrdset_set_name(st, name);
+ else rrdset_set_name(st, id);
+
+ {
+ char varvalue[CONFIG_MAX_VALUE + 1];
+ snprintf(varvalue, CONFIG_MAX_VALUE, "%s (%s)", title?title:"", st->name);
+ st->title = config_get(st->id, "title", varvalue);
+ }
+
st->next = rrdset_root;
rrdset_root = st;
void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
{
+ debug(D_RRD_CALLS, "rrddim_set_name() %s.%s", st->name, rd->name);
+
char varname[CONFIG_MAX_NAME + 1];
snprintf(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
config_get(st->id, varname, name);
void rrddim_free(RRDSET *st, RRDDIM *rd)
{
+ debug(D_RRD_CALLS, "rrddim_free() %s.%s", st->name, rd->name);
+
RRDDIM *i = st->dimensions, *last = NULL;
for(i = st->dimensions; i && i != rd ; i = i->next) last = i;
void rrdset_save_all(void)
{
+ debug(D_RRD_CALLS, "rrdset_save_all()");
+
RRDSET *st;
RRDDIM *rd;
RRDSET *rrdset_find(const char *id)
{
- debug(D_RRD_CALLS, "rrd_stats_find() for chart %s", id);
+ debug(D_RRD_CALLS, "rrdset_find() for chart %s", id);
pthread_rwlock_rdlock(&rrdset_root_rwlock);
RRDSET *st = rrdset_index_find(id, 0);
RRDSET *rrdset_find_bytype(const char *type, const char *id)
{
- debug(D_RRD_CALLS, "rrd_stats_find_bytype() for chart %s.%s", type, id);
+ debug(D_RRD_CALLS, "rrdset_find_bytype() for chart %s.%s", type, id);
char buf[RRD_ID_LENGTH_MAX + 1];
RRDSET *rrdset_find_byname(const char *name)
{
- debug(D_RRD_CALLS, "rrd_stats_find_byname() for chart %s", name);
-
- char b[CONFIG_MAX_VALUE + 1];
-
- rrdset_strncpy_name(b, name, CONFIG_MAX_VALUE);
- unsigned long hash = simple_hash(b);
+ debug(D_RRD_CALLS, "rrdset_find_byname() for chart %s", name);
pthread_rwlock_rdlock(&rrdset_root_rwlock);
- RRDSET *st = rrdset_root;
- for ( ; st ; st = st->next ) {
- if(hash == st->hash_name && strcmp(st->name, b) == 0) break;
- }
+ RRDSET *st = rrdset_index_find_name(name, 0);
pthread_rwlock_unlock(&rrdset_root_rwlock);
return(st);
RRDDIM *rrddim_find(RRDSET *st, const char *id)
{
- debug(D_RRD_CALLS, "rrd_stats_dimension_find() for chart %s, dimension %s", st->name, id);
+ debug(D_RRD_CALLS, "rrddim_find() for chart %s, dimension %s", st->name, id);
return rrddim_index_find(st, id, 0);
}
int rrddim_hide(RRDSET *st, const char *id)
{
- debug(D_RRD_CALLS, "rrd_stats_dimension_hide() for chart %s, dimension %s", st->name, id);
+ debug(D_RRD_CALLS, "rrddim_hide() for chart %s, dimension %s", st->name, id);
RRDDIM *rd = rrddim_find(st, id);
if(!rd) {
void rrddim_set_by_pointer(RRDSET *st, RRDDIM *rd, collected_number value)
{
- debug(D_RRD_CALLS, "rrd_stats_dimension_set() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
+ debug(D_RRD_CALLS, "rrddim_set_by_pointer() for chart %s, dimension %s, value " COLLECTED_NUMBER_FORMAT, st->name, rd->name, value);
gettimeofday(&rd->last_collected_time, NULL);
rd->collected_value = value;
void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
{
- debug(D_RRD_CALLS, "rrd_stats_next() for chart %s with microseconds %llu", st->name, microseconds);
+ debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
if(st->debug) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds);
st->usec_since_last_update = microseconds;
unsigned long long rrdset_done(RRDSET *st)
{
- debug(D_RRD_CALLS, "rrd_stats_done() for chart %s", st->name);
+ debug(D_RRD_CALLS, "rrdset_done() for chart %s", st->name);
RRDDIM *rd, *last;
int oldstate, store_this_entry = 1;