void rrdset_set_name(RRDSET *st, const char *name)
{
- debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
+ if(unlikely(st->name && !strcmp(st->name, name)))
+ return;
- if(st->name) {
- rrdset_index_del_name(&localhost, st);
- rrdsetvar_rename_all(st);
- }
+ debug(D_RRD_CALLS, "rrdset_set_name() old: %s, new: %s", st->name, name);
char b[CONFIG_MAX_VALUE + 1];
char n[RRD_ID_LENGTH_MAX + 1];
snprintfz(n, RRD_ID_LENGTH_MAX, "%s.%s", st->type, name);
rrdset_strncpyz_name(b, n, CONFIG_MAX_VALUE);
- st->name = config_get(st->id, "name", b);
- st->hash_name = simple_hash(st->name);
+
+ if(st->name) {
+ rrdset_index_del_name(&localhost, st);
+ st->name = config_set_default(st->id, "name", b);
+ st->hash_name = simple_hash(st->name);
+ rrdsetvar_rename_all(st);
+ }
+ else {
+ st->name = config_get(st->id, "name", b);
+ st->hash_name = simple_hash(st->name);
+ }
+
+ pthread_rwlock_wrlock(&st->rwlock);
+ RRDDIM *rd;
+ for(rd = st->dimensions; rd ;rd = rd->next)
+ rrddimvar_rename_all(rd);
+ pthread_rwlock_unlock(&st->rwlock);
rrdset_index_add_name(&localhost, st);
}
rd->last_collected_time.tv_sec = 0;
rd->last_collected_time.tv_usec = 0;
rd->counter = 0;
- bzero(rd->values, rd->entries * sizeof(storage_number));
+ memset(rd->values, 0, rd->entries * sizeof(storage_number));
+ }
+}
+static long align_entries_to_pagesize(long entries) {
+ if(entries < 5) entries = 5;
+ if(entries > RRD_HISTORY_ENTRIES_MAX) entries = RRD_HISTORY_ENTRIES_MAX;
+
+#ifdef NETDATA_LOG_ALLOCATIONS
+ long page = (size_t)sysconf(_SC_PAGESIZE);
+
+ long size = sizeof(RRDDIM) + entries * sizeof(storage_number);
+ if(size % page) {
+ size -= (size % page);
+ size += page;
+
+ long n = (size - sizeof(RRDDIM)) / sizeof(storage_number);
+ return n;
}
+
+ return entries;
+#else
+ return entries;
+#endif
}
RRDSET *rrdset_create(const char *type, const char *id, const char *name, const char *family, const char *context, const char *title, const char *units, long priority, int update_every, int chart_type)
char fullid[RRD_ID_LENGTH_MAX + 1];
char fullfilename[FILENAME_MAX + 1];
- RRDSET *st = NULL;
snprintfz(fullid, RRD_ID_LENGTH_MAX, "%s.%s", type, id);
- st = rrdset_find(fullid);
+ RRDSET *st = rrdset_find(fullid);
if(st) {
error("Cannot create rrd stats for '%s', it already exists.", fullid);
return st;
}
- long entries = config_get_number(fullid, "history", rrd_default_history_entries);
- if(entries < 5) entries = config_set_number(fullid, "history", 5);
- if(entries > RRD_HISTORY_ENTRIES_MAX) entries = config_set_number(fullid, "history", RRD_HISTORY_ENTRIES_MAX);
+ long rentries = config_get_number(fullid, "history", rrd_default_history_entries);
+ long entries = align_entries_to_pagesize(rentries);
+ if(entries != rentries) entries = config_set_number(fullid, "history", entries);
int enabled = config_get_boolean(fullid, "enabled", 1);
if(!enabled) entries = 5;
if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
errno = 0;
info("Initializing file %s.", fullfilename);
- bzero(st, size);
+ memset(st, 0, size);
}
else if(strcmp(st->id, fullid) != 0) {
errno = 0;
error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
// munmap(st, size);
// st = NULL;
- bzero(st, size);
+ memset(st, 0, size);
}
else if(st->memsize != size || st->entries != entries) {
errno = 0;
error("File %s does not have the desired size. Clearing it.", fullfilename);
- bzero(st, size);
+ memset(st, 0, size);
}
else if(st->update_every != update_every) {
errno = 0;
error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
- bzero(st, size);
+ memset(st, 0, size);
}
else if((time(NULL) - st->last_updated.tv_sec) > update_every * entries) {
errno = 0;
error("File %s is too old. Clearing it.", fullfilename);
- bzero(st, size);
+ memset(st, 0, size);
}
}
if(strcmp(rd->magic, RRDDIMENSION_MAGIC) != 0) {
errno = 0;
info("Initializing file %s.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(rd->memsize != size) {
errno = 0;
error("File %s does not have the desired size. Clearing it.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(rd->multiplier != multiplier) {
errno = 0;
error("File %s does not have the same multiplier. Clearing it.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(rd->divisor != divisor) {
errno = 0;
error("File %s does not have the same divisor. Clearing it.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(rd->algorithm != algorithm) {
errno = 0;
error("File %s does not have the same algorithm. Clearing it.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(rd->update_every != st->update_every) {
errno = 0;
error("File %s does not have the same refresh frequency. Clearing it.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(usec_dt(&now, &rd->last_collected_time) > (rd->entries * rd->update_every * 1000000ULL)) {
errno = 0;
error("File %s is too old. Clearing it.", fullfilename);
- bzero(rd, size);
+ memset(rd, 0, size);
}
else if(strcmp(rd->id, id) != 0) {
errno = 0;
error("File %s contents are not for dimension %s. Clearing it.", fullfilename, id);
// munmap(rd, size);
// rd = NULL;
- bzero(rd, size);
+ memset(rd, 0, size);
}
}
void rrddim_set_name(RRDSET *st, RRDDIM *rd, const char *name)
{
- debug(D_RRD_CALLS, "rrddim_set_name() %s.%s", st->name, rd->name);
+ if(unlikely(rd->name && !strcmp(rd->name, name)))
+ return;
+
+ debug(D_RRD_CALLS, "rrddim_set_name() from %s.%s to %s.%s", st->name, rd->name, st->name, name);
char varname[CONFIG_MAX_NAME + 1];
snprintfz(varname, CONFIG_MAX_NAME, "dim %s name", rd->id);
- config_set_default(st->id, varname, name);
+ rd->name = config_set_default(st->id, varname, name);
rrddimvar_rename_all(rd);
}
return rrddim_set_by_pointer(st, rd, value);
}
-void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
+void rrdset_next_usec_unfiltered(RRDSET *st, unsigned long long microseconds)
{
- if(!microseconds) rrdset_next(st);
- else {
- debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
-
- if(unlikely(st->debug)) debug(D_RRD_STATS, "%s: NEXT: %llu microseconds", st->name, microseconds);
- st->usec_since_last_update = microseconds;
+ if(unlikely(!st->last_collected_time.tv_sec || !microseconds)) {
+ // the first entry
+ microseconds = st->update_every * 1000000ULL;
}
+ st->usec_since_last_update = microseconds;
}
-void rrdset_next(RRDSET *st)
+void rrdset_next_usec(RRDSET *st, unsigned long long microseconds)
{
- unsigned long long microseconds = 0;
+ struct timeval now;
+ gettimeofday(&now, NULL);
- if(likely(st->last_collected_time.tv_sec)) {
- struct timeval now;
- gettimeofday(&now, NULL);
+ if(unlikely(!st->last_collected_time.tv_sec)) {
+ // the first entry
+ microseconds = st->update_every * 1000000ULL;
+ }
+ else if(unlikely(!microseconds)) {
+ // no dt given by the plugin
microseconds = usec_dt(&now, &st->last_collected_time);
}
- // prevent infinite loop
- else microseconds = st->update_every * 1000000ULL;
+ else {
+ // microseconds has the time since the last collection
+ unsigned long long now_usec = timeval_usec(&now);
+ unsigned long long last_usec = timeval_usec(&st->last_collected_time);
+ unsigned long long since_last_usec = usec_dt(&now, &st->last_collected_time);
- rrdset_next_usec(st, microseconds);
-}
+ // verify the microseconds given is good
+ if(unlikely(microseconds > since_last_usec)) {
+ debug(D_RRD_CALLS, "dt %llu usec given is too big - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, microseconds - since_last_usec, st->name, st->id);
-void rrdset_next_plugins(RRDSET *st)
-{
- rrdset_next(st);
+#ifdef NETDATA_INTERNAL_CHECKS
+ if(unlikely(last_usec + microseconds > now_usec + 1000))
+ error("dt %llu usec given is too big - it leads %llu usec to the future, for chart '%s' (%s).", microseconds, microseconds - since_last_usec, st->name, st->id);
+#endif
+
+ microseconds = since_last_usec;
+ }
+ else if(unlikely(microseconds < since_last_usec * 0.8)) {
+ debug(D_RRD_CALLS, "dt %llu usec given is too small - expected %llu usec up to -20%%, for chart '%s' (%s).", microseconds, since_last_usec, st->name, st->id);
+
+#ifdef NETDATA_INTERNAL_CHECKS
+ error("dt %llu usec given is too small - expected %llu usec up to -20%%, for chart '%s' (%s).", microseconds, since_last_usec, st->name, st->id);
+#endif
+ microseconds = since_last_usec;
+ }
+ }
+ debug(D_RRD_CALLS, "rrdset_next_usec() for chart %s with microseconds %llu", st->name, microseconds);
+
+ if(unlikely(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)
break;
}
- if(unlikely(!store_this_entry))
+ if(unlikely(!store_this_entry)) {
+ rd->values[st->current_entry] = pack_storage_number(0, SN_NOT_EXISTS);
continue;
+ }
if(likely(rd->updated && rd->counter > 1 && iterations < st->gap_when_lost_iterations_above)) {
rd->values[st->current_entry] = pack_storage_number(new_value, storage_flags );