// SPDX-License-Identifier: GPL-3.0-or-later
#define NETDATA_RRD_INTERNALS
#include "rrd.h"
RRDHOST *localhost = NULL;
size_t rrd_hosts_available = 0;
netdata_rwlock_t rrd_rwlock = NETDATA_RWLOCK_INITIALIZER;
time_t rrdset_free_obsolete_time = 3600;
time_t rrdhost_free_orphan_time = 3600;
// ----------------------------------------------------------------------------
// RRDHOST index
int rrdhost_compare(void* a, void* b) {
if(((RRDHOST *)a)->hash_machine_guid < ((RRDHOST *)b)->hash_machine_guid) return -1;
else if(((RRDHOST *)a)->hash_machine_guid > ((RRDHOST *)b)->hash_machine_guid) return 1;
else return strcmp(((RRDHOST *)a)->machine_guid, ((RRDHOST *)b)->machine_guid);
}
avl_tree_lock rrdhost_root_index = {
.avl_tree = { NULL, rrdhost_compare },
.rwlock = AVL_LOCK_INITIALIZER
};
RRDHOST *rrdhost_find_by_guid(const char *guid, uint32_t hash) {
debug(D_RRDHOST, "Searching in index for host with guid '%s'", guid);
RRDHOST tmp;
strncpyz(tmp.machine_guid, guid, GUID_LEN);
tmp.hash_machine_guid = (hash)?hash:simple_hash(tmp.machine_guid);
return (RRDHOST *)avl_search_lock(&(rrdhost_root_index), (avl *) &tmp);
}
RRDHOST *rrdhost_find_by_hostname(const char *hostname, uint32_t hash) {
if(unlikely(!strcmp(hostname, "localhost")))
return localhost;
if(unlikely(!hash)) hash = simple_hash(hostname);
rrd_rdlock();
RRDHOST *host;
rrdhost_foreach_read(host) {
if(unlikely((hash == host->hash_hostname && !strcmp(hostname, host->hostname)))) {
rrd_unlock();
return host;
}
}
rrd_unlock();
return NULL;
}
#define rrdhost_index_add(rrdhost) (RRDHOST *)avl_insert_lock(&(rrdhost_root_index), (avl *)(rrdhost))
#define rrdhost_index_del(rrdhost) (RRDHOST *)avl_remove_lock(&(rrdhost_root_index), (avl *)(rrdhost))
// ----------------------------------------------------------------------------
// RRDHOST - internal helpers
static inline void rrdhost_init_tags(RRDHOST *host, const char *tags) {
if(host->tags && tags && !strcmp(host->tags, tags))
return;
void *old = (void *)host->tags;
host->tags = (tags && *tags)?strdupz(tags):NULL;
freez(old);
}
static inline void rrdhost_init_hostname(RRDHOST *host, const char *hostname) {
if(host->hostname && hostname && !strcmp(host->hostname, hostname))
return;
void *old = host->hostname;
host->hostname = strdupz(hostname?hostname:"localhost");
host->hash_hostname = simple_hash(host->hostname);
freez(old);
}
static inline void rrdhost_init_os(RRDHOST *host, const char *os) {
if(host->os && os && !strcmp(host->os, os))
return;
void *old = (void *)host->os;
host->os = strdupz(os?os:"unknown");
freez(old);
}
static inline void rrdhost_init_timezone(RRDHOST *host, const char *timezone) {
if(host->timezone && timezone && !strcmp(host->timezone, timezone))
return;
void *old = (void *)host->timezone;
host->timezone = strdupz((timezone && *timezone)?timezone:"unknown");
freez(old);
}
static inline void rrdhost_init_machine_guid(RRDHOST *host, const char *machine_guid) {
strncpy(host->machine_guid, machine_guid, GUID_LEN);
host->machine_guid[GUID_LEN] = '\0';
host->hash_machine_guid = simple_hash(host