]> arthur.barton.de Git - netdata.git/commitdiff
replaced simple_hash with the FNV-1a 32bit algorithm
authorCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Thu, 2 Apr 2015 21:14:02 +0000 (00:14 +0300)
committerCosta Tsaousis (ktsaou) <costa@tsaousis.gr>
Thu, 2 Apr 2015 21:14:02 +0000 (00:14 +0300)
src/common.c
src/common.h
src/config.c
src/dictionary.c
src/dictionary.h
src/plugins.d/apps_plugin.c
src/rrd.c
src/rrd.h

index df85ee8fa8dc23eacb0b510e8d5ebfcaa058ae35..a76b78f227b935c715170d3231cf9fa885bc6729 100755 (executable)
 #include "log.h"
 #include "common.h"
 
+/*
 // http://stackoverflow.com/questions/7666509/hash-function-for-string
-unsigned long simple_hash(const char *name)
+uint32_t simple_hash(const char *name)
 {
        const char *s = name;
-       unsigned long hash = 5381;
+       uint32_t hash = 5381;
        int i;
 
        while((i = *s++)) hash = ((hash << 5) + hash) + i;
@@ -27,6 +28,27 @@ unsigned long simple_hash(const char *name)
 
        return hash;
 }
+*/
+
+// http://isthe.com/chongo/tech/comp/fnv/#FNV-1a
+uint32_t simple_hash(const char *name) {
+       unsigned char *s = (unsigned char *)name;
+       uint32_t hval = 0x811c9dc5;
+
+       // FNV-1a algorithm
+       while (*s) {
+               // multiply by the 32 bit FNV magic prime mod 2^32
+               // gcc optimized
+               hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
+
+               // xor the bottom with the current octet
+               hval ^= (uint32_t)*s++;
+       }
+
+       // fprintf(stderr, "HASH: %u = %s\n", hval, name);
+       return hval;
+}
+
 
 void strreverse(char* begin, char* end)
 {
index 2340c01568182f3e6e14c167aa124718fe29c82c..e129e8ba139c15aa4e38fe746fce64ba726da69d 100755 (executable)
@@ -1,10 +1,12 @@
+#include <inttypes.h>
+
 #ifndef NETDATA_COMMON_H
 #define NETDATA_COMMON_H 1
 
 #define abs(x) ((x < 0)? -x : x)
 #define usecdiff(now, last) (((((now)->tv_sec * 1000000ULL) + (now)->tv_usec) - (((last)->tv_sec * 1000000ULL) + (last)->tv_usec)))
 
-extern unsigned long simple_hash(const char *name);
+extern uint32_t simple_hash(const char *name);
 extern void strreverse(char* begin, char* end);
 extern char *mystrsep(char **ptr, char *s);
 extern char *qstrsep(char **ptr);
index 3c8e041ff23093826ee4db5cfb24d5075b0d32fd..e1be0cedd696f7ebc2f3f41cbd6d4bc6d7dde2a0 100755 (executable)
@@ -23,7 +23,7 @@ pthread_rwlock_t config_rwlock = PTHREAD_RWLOCK_INITIALIZER;
 struct config_value {
        avl avl;                                // the index - this has to be first!
 
-       unsigned long hash;             // a simple hash to speed up searching
+       uint32_t hash;                  // a simple hash to speed up searching
                                                        // we first compare hashes, and only if the hashes are equal we do string comparisons
 
        char *name;
@@ -37,7 +37,7 @@ struct config_value {
 struct config {
        avl avl;
 
-       unsigned long hash;             // a simple hash to speed up searching
+       uint32_t hash;                  // a simple hash to speed up searching
                                                        // we first compare hashes, and only if the hashes are equal we do string comparisons
 
        char *name;
@@ -63,7 +63,7 @@ static int config_value_compare(void* a, void* b) {
 #define config_value_index_add(co, cv) avl_insert(&((co)->values_index), (avl *)(cv))
 #define config_value_index_del(co, cv) avl_remove(&((co)->values_index), (avl *)(cv))
 
-static struct config_value *config_value_index_find(struct config *co, const char *name, unsigned long hash) {
+static struct config_value *config_value_index_find(struct config *co, const char *name, uint32_t hash) {
        struct config_value *result = NULL, tmp;
        tmp.hash = (hash)?hash:simple_hash(name);
        tmp.name = (char *)name;
@@ -91,7 +91,7 @@ avl_tree config_root_index = {
 #define config_index_add(cfg) avl_insert(&config_root_index, (avl *)(cfg))
 #define config_index_del(cfg) avl_remove(&config_root_index, (avl *)(cfg))
 
-static struct config *config_index_find(const char *name, unsigned long hash) {
+static struct config *config_index_find(const char *name, uint32_t hash) {
        struct config *result = NULL, tmp;
        tmp.hash = (hash)?hash:simple_hash(name);
        tmp.name = (char *)name;
index afd833c6ab4763074ae220a4cda715cb8ad62a13..74d58920befae76ea34220e5c7f24730a0de53af 100755 (executable)
@@ -23,7 +23,7 @@ static int name_value_compare(void* a, void* b) {
 #define name_value_index_add(dict, cv) avl_insert(&((dict)->values_index), (avl *)(cv))
 #define name_value_index_del(dict, cv) avl_remove(&((dict)->values_index), (avl *)(cv))
 
-static NAME_VALUE *dictionary_name_value_index_find(DICTIONARY *dict, const char *name, unsigned long hash) {
+static NAME_VALUE *dictionary_name_value_index_find(DICTIONARY *dict, const char *name, uint32_t hash) {
        NAME_VALUE *result = NULL, tmp;
        tmp.hash = (hash)?hash:simple_hash(name);
        tmp.name = (char *)name;
index 172e717f03a0cdee5ca99a969078cdf902bd85c0..9822b23c22c47efcb0ea831bf50c030554646d10 100755 (executable)
@@ -6,7 +6,7 @@
 typedef struct name_value {
        avl avl;                                // the index - this has to be first!
 
-       unsigned long hash;             // a simple hash to speed up searching
+       uint32_t hash;                  // a simple hash to speed up searching
                                                        // we first compare hashes, and only if the hashes are equal we do string comparisons
 
        char *name;
index 19b6ae6f0bb809a64db6e9cb8984a254bc44c167..49aa4ed7542932ba370219104639e92a98932cc7 100755 (executable)
@@ -727,7 +727,7 @@ int read_proc_pid_io(struct pid_stat *p) {
 
        snprintf(filename, FILENAME_MAX, "/proc/%d/io", p->pid);
 
-       ff = procfile_reopen(ff, filename, ":");
+       ff = procfile_reopen(ff, filename, "");
        if(!ff) return 1;
 
        ff = procfile_readall(ff);
@@ -801,8 +801,8 @@ int walk_down(pid_t pid, int level) {
 
 struct file_descriptor {
        avl avl;
-       unsigned long magic;
-       unsigned long hash;
+       uint32_t magic;
+       uint32_t hash;
        const char *name;
        int type;
        long count;
@@ -829,7 +829,7 @@ avl_tree all_files_index = {
                file_descriptor_compare
 };
 
-static struct file_descriptor *file_descriptor_find(const char *name, unsigned long hash) {
+static struct file_descriptor *file_descriptor_find(const char *name, uint32_t hash) {
        struct file_descriptor *result = NULL, tmp;
        tmp.hash = (hash)?hash:simple_hash(name);
        tmp.name = name;
@@ -883,9 +883,9 @@ void file_descriptor_not_used(int id)
 unsigned long file_descriptor_find_or_add(const char *name)
 {
        static int last_pos = 0;
-       unsigned long hash = simple_hash(name);
+       uint32_t hash = simple_hash(name);
 
-       if(debug) fprintf(stderr, "apps.plugin: adding or finding name '%s' with hash %lu\n", name, hash);
+       if(debug) fprintf(stderr, "apps.plugin: adding or finding name '%s' with hash %u\n", name, hash);
 
        struct file_descriptor *fd = file_descriptor_find(name, hash);
        if(fd) {
index c6eb742572e5483623a8fd137325781ca0f568de..7de62ef8892d609bea1c6f4648a153f73be29fcf 100755 (executable)
--- a/src/rrd.c
+++ b/src/rrd.c
@@ -50,7 +50,7 @@ avl_tree rrdset_root_index = {
 #define rrdset_index_add(st) avl_insert(&rrdset_root_index, (avl *)(st))
 #define rrdset_index_del(st) avl_remove(&rrdset_root_index, (avl *)(st))
 
-static RRDSET *rrdset_index_find(const char *id, unsigned long hash) {
+static RRDSET *rrdset_index_find(const char *id, uint32_t hash) {
        RRDSET *result = NULL, tmp;
        strncpy(tmp.id, id, RRD_ID_LENGTH_MAX);
        tmp.id[RRD_ID_LENGTH_MAX] = '\0';
@@ -90,7 +90,7 @@ int rrdset_index_add_name(RRDSET *st) {
 
 #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) {
+static RRDSET *rrdset_index_find_name(const char *name, uint32_t hash) {
        void *result = NULL;
        RRDSET tmp;
        tmp.name = name;
@@ -125,7 +125,7 @@ static int rrddim_compare(void* a, void* b) {
 #define rrddim_index_add(st, rd) avl_insert(&((st)->dimensions_index), (avl *)(rd))
 #define rrddim_index_del(st,rd ) avl_remove(&((st)->dimensions_index), (avl *)(rd))
 
-static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, unsigned long hash) {
+static RRDDIM *rrddim_index_find(RRDSET *st, const char *id, uint32_t hash) {
        RRDDIM *result = NULL, tmp;
        tmp.hash = (hash)?hash:simple_hash(id);
        strncpy(tmp.id, id, RRD_ID_LENGTH_MAX);
index 5a02a77b32c7f412b5f166c10363103490428b1c..1287ed14359d717f216f9bdea7fed96aaa9afe75 100755 (executable)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -101,7 +101,7 @@ struct rrddim {
        // ------------------------------------------------------------------------
        // members for temporary data we need for calculations
 
-       unsigned long hash;                                                             // a simple hash of the id, to speed up searching / indexing
+       uint32_t hash;                                                                  // a simple hash of the id, to speed up searching / indexing
                                                                                                        // instead of strcmp() every item in the binary index
                                                                                                        // we first compare the hashes
 
@@ -209,10 +209,10 @@ struct rrdset {
 
        unsigned long long first_entry_t;                               // the timestamp (in microseconds) of the oldest entry in the db
 
-       unsigned long hash;                                                             // a simple hash on the id, to speed up searching
+       uint32_t hash;                                                                  // a simple hash on the id, to speed up searching
                                                                                                        // we first compare hashes, and only if the hashes are equal we do string comparisons
 
-       unsigned long hash_name;                                                // a simple hash on the name
+       uint32_t hash_name;                                                             // a simple hash on the name
 
        unsigned long long usec_since_last_update;              // the time in microseconds since the last collection of data