int main(int argc, char **argv) {
if(argc || argv) {;}
- DICTIONARY *dict = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED);
+// DICTIONARY *dict = dictionary_create(DICTIONARY_FLAG_SINGLE_THREADED|DICTIONARY_FLAG_WITH_STATISTICS);
+ DICTIONARY *dict = dictionary_create(DICTIONARY_FLAG_WITH_STATISTICS);
if(!dict) fatal("Cannot create dictionary.");
struct rusage start, end;
unsigned long long dt;
char buf[100 + 1];
struct myvalue value, *v;
- int i, max = 10000000, max2;
+ int i, max = 100000, max2;
// ------------------------------------------------------------------------
getrusage(RUSAGE_SELF, &start);
- dict->inserts = dict->deletes = dict->searches = 0ULL;
+ dict->stats->inserts = dict->stats->deletes = dict->stats->searches = 0ULL;
fprintf(stderr, "Inserting %d entries in the dictionary\n", max);
for(i = 0; i < max; i++) {
value.i = i;
getrusage(RUSAGE_SELF, &end);
dt = (end.ru_utime.tv_sec * 1000000ULL + end.ru_utime.tv_usec) - (start.ru_utime.tv_sec * 1000000ULL + start.ru_utime.tv_usec);
fprintf(stderr, "Added %d entries in %llu nanoseconds: %llu inserts per second\n", max, dt, max * 1000000ULL / dt);
- fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->inserts, dict->deletes, dict->searches);
+ fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->stats->inserts, dict->stats->deletes, dict->stats->searches);
// ------------------------------------------------------------------------
getrusage(RUSAGE_SELF, &start);
- dict->inserts = dict->deletes = dict->searches = 0ULL;
+ dict->stats->inserts = dict->stats->deletes = dict->stats->searches = 0ULL;
fprintf(stderr, "Retrieving %d entries from the dictionary\n", max);
for(i = 0; i < max; i++) {
value.i = i;
getrusage(RUSAGE_SELF, &end);
dt = (end.ru_utime.tv_sec * 1000000ULL + end.ru_utime.tv_usec) - (start.ru_utime.tv_sec * 1000000ULL + start.ru_utime.tv_usec);
fprintf(stderr, "Read %d entries in %llu nanoseconds: %llu searches per second\n", max, dt, max * 1000000ULL / dt);
- fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->inserts, dict->deletes, dict->searches);
+ fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->stats->inserts, dict->stats->deletes, dict->stats->searches);
// ------------------------------------------------------------------------
getrusage(RUSAGE_SELF, &start);
- dict->inserts = dict->deletes = dict->searches = 0ULL;
+ dict->stats->inserts = dict->stats->deletes = dict->stats->searches = 0ULL;
fprintf(stderr, "Resetting %d entries in the dictionary\n", max);
for(i = 0; i < max; i++) {
value.i = i;
}
getrusage(RUSAGE_SELF, &end);
dt = (end.ru_utime.tv_sec * 1000000ULL + end.ru_utime.tv_usec) - (start.ru_utime.tv_sec * 1000000ULL + start.ru_utime.tv_usec);
- fprintf(stderr, "Reset %d entries in %llu nanoseconds: %llu inserts per second\n", max, dt, max * 1000000ULL / dt);
- fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->inserts, dict->deletes, dict->searches);
+ fprintf(stderr, "Reset %d entries in %llu nanoseconds: %llu resets per second\n", max, dt, max * 1000000ULL / dt);
+ fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->stats->inserts, dict->stats->deletes, dict->stats->searches);
// ------------------------------------------------------------------------
getrusage(RUSAGE_SELF, &start);
- dict->inserts = dict->deletes = dict->searches = 0ULL;
+ dict->stats->inserts = dict->stats->deletes = dict->stats->searches = 0ULL;
fprintf(stderr, "Searching %d non-existing entries in the dictionary\n", max);
max2 = max * 2;
for(i = max; i < max2; i++) {
}
getrusage(RUSAGE_SELF, &end);
dt = (end.ru_utime.tv_sec * 1000000ULL + end.ru_utime.tv_usec) - (start.ru_utime.tv_sec * 1000000ULL + start.ru_utime.tv_usec);
- fprintf(stderr, "Searched %d non-existing entries in %llu nanoseconds: %llu searches per second\n", max, dt, max * 1000000ULL / dt);
- fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->inserts, dict->deletes, dict->searches);
+ fprintf(stderr, "Searched %d non-existing entries in %llu nanoseconds: %llu not found searches per second\n", max, dt, max * 1000000ULL / dt);
+ fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->stats->inserts, dict->stats->deletes, dict->stats->searches);
// ------------------------------------------------------------------------
getrusage(RUSAGE_SELF, &start);
- dict->inserts = dict->deletes = dict->searches = 0ULL;
+ dict->stats->inserts = dict->stats->deletes = dict->stats->searches = 0ULL;
fprintf(stderr, "Deleting %d entries from the dictionary\n", max);
for(i = 0; i < max; i++) {
value.i = i;
getrusage(RUSAGE_SELF, &end);
dt = (end.ru_utime.tv_sec * 1000000ULL + end.ru_utime.tv_usec) - (start.ru_utime.tv_sec * 1000000ULL + start.ru_utime.tv_usec);
fprintf(stderr, "Deleted %d entries in %llu nanoseconds: %llu deletes per second\n", max, dt, max * 1000000ULL / dt);
- fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->inserts, dict->deletes, dict->searches);
+ fprintf(stderr, " > Dictionary: %llu inserts, %llu deletes, %llu searches\n\n", dict->stats->inserts, dict->stats->deletes, dict->stats->searches);
// ------------------------------------------------------------------------
getrusage(RUSAGE_SELF, &start);
- dict->inserts = dict->deletes = dict->searches = 0ULL;
+ dict->stats->inserts = dict->stats->deletes = dict->stats->searches = 0ULL;
fprintf(stderr, "Destroying dictionary\n");
dictionary_destroy(dict);
getrusage(RUSAGE_SELF, &end);
#include "dictionary.h"
+// ----------------------------------------------------------------------------
+// dictionary statistics
+
+static inline void NETDATA_DICTIONARY_STATS_INSERTS_PLUS1(DICTIONARY *dict) {
+ if(likely(dict->stats))
+ dict->stats->inserts++;
+}
+static inline void NETDATA_DICTIONARY_STATS_DELETES_PLUS1(DICTIONARY *dict) {
+ if(likely(dict->stats))
+ dict->stats->deletes++;
+}
+static inline void NETDATA_DICTIONARY_STATS_SEARCHES_PLUS1(DICTIONARY *dict) {
+ if(likely(dict->stats))
+ dict->stats->searches++;
+}
+static inline void NETDATA_DICTIONARY_STATS_ENTRIES_PLUS1(DICTIONARY *dict) {
+ if(likely(dict->stats))
+ dict->stats->entries++;
+}
+static inline void NETDATA_DICTIONARY_STATS_ENTRIES_MINUS1(DICTIONARY *dict) {
+ if(likely(dict->stats))
+ dict->stats->entries--;
+}
+
+
// ----------------------------------------------------------------------------
// dictionary locks
static inline void dictionary_read_lock(DICTIONARY *dict) {
- if(likely(!(dict->flags & DICTIONARY_FLAG_SINGLE_THREADED))) {
+ if(likely(dict->rwlock)) {
// debug(D_DICTIONARY, "Dictionary READ lock");
- pthread_rwlock_rdlock(&dict->rwlock);
+ pthread_rwlock_rdlock(dict->rwlock);
}
}
static inline void dictionary_write_lock(DICTIONARY *dict) {
- if(likely(!(dict->flags & DICTIONARY_FLAG_SINGLE_THREADED))) {
+ if(likely(dict->rwlock)) {
// debug(D_DICTIONARY, "Dictionary WRITE lock");
- pthread_rwlock_wrlock(&dict->rwlock);
+ pthread_rwlock_wrlock(dict->rwlock);
}
}
static inline void dictionary_unlock(DICTIONARY *dict) {
- if(likely(!(dict->flags & DICTIONARY_FLAG_SINGLE_THREADED))) {
+ if(likely(dict->rwlock)) {
// debug(D_DICTIONARY, "Dictionary UNLOCK lock");
- pthread_rwlock_unlock(&dict->rwlock);
+ pthread_rwlock_unlock(dict->rwlock);
}
}
DICTIONARY *dict = calloc(1, sizeof(DICTIONARY));
if(unlikely(!dict)) fatal("Cannot allocate DICTIONARY");
- avl_init(&dict->values_index, name_value_compare);
- pthread_rwlock_init(&dict->rwlock, NULL);
+ if(flags & DICTIONARY_FLAG_WITH_STATISTICS) {
+ dict->stats = calloc(1, sizeof(struct dictionary_stats));
+ if(!dict->stats) fatal("Cannot allocate statistics for DICTIONARY");
+ }
+
+ if(!(flags & DICTIONARY_FLAG_SINGLE_THREADED)) {
+ dict->rwlock = calloc(1, sizeof(pthread_rwlock_t));
+ if(!dict->rwlock) fatal("Cannot allocate pthread_rwlock_t for DICTIONARY");
+ pthread_rwlock_init(dict->rwlock, NULL);
+ }
+ avl_init(&dict->values_index, name_value_compare);
dict->flags = flags;
return dict;
dictionary_unlock(dict);
+ if(dict->stats)
+ free(dict->stats);
+
+ if(dict->rwlock)
+ free(dict->rwlock);
+
free(dict);
}
#ifndef NETDATA_DICTIONARY_H
#define NETDATA_DICTIONARY_H 1
+struct dictionary_stats {
+ unsigned long long inserts;
+ unsigned long long deletes;
+ unsigned long long searches;
+ unsigned long long entries;
+};
+
typedef struct name_value {
avl avl; // the index - this has to be first!
uint8_t flags;
-#ifdef NETDATA_DICTIONARY_WITH_STATISTICS
- unsigned long long inserts;
- unsigned long long deletes;
- unsigned long long searches;
- unsigned long long entries;
-#endif /* NETDATA_DICTIONARY_WITH_STATISTICS */
-
- pthread_rwlock_t rwlock;
+ struct dictionary_stats *stats;
+ pthread_rwlock_t *rwlock;
} DICTIONARY;
-#ifdef NETDATA_DICTIONARY_WITH_STATISTICS
-#define NETDATA_DICTIONARY_STATS_INSERTS_PLUS1(dict) (dict)->inserts++
-#define NETDATA_DICTIONARY_STATS_DELETES_PLUS1(dict) (dict)->deletes++
-#define NETDATA_DICTIONARY_STATS_SEARCHES_PLUS1(dict) (dict)->searches++
-#define NETDATA_DICTIONARY_STATS_ENTRIES_PLUS1(dict) (dict)->entries++
-#define NETDATA_DICTIONARY_STATS_ENTRIES_MINUS1(dict) (dict)->entries--
-#else /* NETDATA_DICTIONARY_WITH_STATISTICS */
-#define NETDATA_DICTIONARY_STATS_INSERTS_PLUS1(dict)
-#define NETDATA_DICTIONARY_STATS_DELETES_PLUS1(dict)
-#define NETDATA_DICTIONARY_STATS_SEARCHES_PLUS1(dict)
-#define NETDATA_DICTIONARY_STATS_ENTRIES_PLUS1(dict)
-#define NETDATA_DICTIONARY_STATS_ENTRIES_MINUS1(dict)
-#endif /* NETDATA_DICTIONARY_WITH_STATISTICS */
-
#define DICTIONARY_FLAG_DEFAULT 0x00000000
#define DICTIONARY_FLAG_SINGLE_THREADED 0x00000001
#define DICTIONARY_FLAG_VALUE_LINK_DONT_CLONE 0x00000002
#define DICTIONARY_FLAG_NAME_LINK_DONT_CLONE 0x00000004
+#define DICTIONARY_FLAG_WITH_STATISTICS 0x00000008
extern DICTIONARY *dictionary_create(uint32_t flags);
extern void dictionary_destroy(DICTIONARY *dict);