summaryrefslogtreecommitdiffstats
path: root/utils/tracking_collisions.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/tracking_collisions.c')
-rw-r--r--utils/tracking_collisions.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/utils/tracking_collisions.c b/utils/tracking_collisions.c
new file mode 100644
index 0000000..f521111
--- /dev/null
+++ b/utils/tracking_collisions.c
@@ -0,0 +1,76 @@
+/* This is a small program used in order to understand the collision rate
+ * of CRC64 (ISO version) VS other stronger hashing functions in the context
+ * of hashing keys for the Redis "tracking" feature (client side caching
+ * assisted by the server).
+ *
+ * The program attempts to hash keys with common names in the form of
+ *
+ * prefix:<counter>
+ *
+ * And counts the resulting collisions generated in the 24 bits of output
+ * needed for the tracking feature invalidation table (16 millions + entries)
+ *
+ * Compile with:
+ *
+ * cc -O2 ./tracking_collisions.c ../src/crc64.c ../src/sha1.c
+ * ./a.out
+ *
+ * --------------------------------------------------------------------------
+ *
+ * Copyright (C) 2019 Salvatore Sanfilippo
+ * This code is released under the BSD 2 clause license.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include "../src/crc64.h"
+#include "../src/sha1.h"
+
+#define TABLE_SIZE (1<<24)
+int Table[TABLE_SIZE];
+
+uint64_t crc64Hash(char *key, size_t len) {
+ return crc64(0,(unsigned char*)key,len);
+}
+
+uint64_t sha1Hash(char *key, size_t len) {
+ SHA1_CTX ctx;
+ unsigned char hash[20];
+
+ SHA1Init(&ctx);
+ SHA1Update(&ctx,(unsigned char*)key,len);
+ SHA1Final(hash,&ctx);
+ uint64_t hash64;
+ memcpy(&hash64,hash,sizeof(hash64));
+ return hash64;
+}
+
+/* Test the hashing function provided as callback and return the
+ * number of collisions found. */
+unsigned long testHashingFunction(uint64_t (*hash)(char *, size_t)) {
+ unsigned long collisions = 0;
+ memset(Table,0,sizeof(Table));
+ char *prefixes[] = {"object", "message", "user", NULL};
+ for (int i = 0; prefixes[i] != NULL; i++) {
+ for (int j = 0; j < TABLE_SIZE/2; j++) {
+ char keyname[128];
+ size_t keylen = snprintf(keyname,sizeof(keyname),"%s:%d",
+ prefixes[i],j);
+ uint64_t bucket = hash(keyname,keylen) % TABLE_SIZE;
+ if (Table[bucket]) {
+ collisions++;
+ } else {
+ Table[bucket] = 1;
+ }
+ }
+ }
+ return collisions;
+}
+
+int main(void) {
+ printf("SHA1 : %lu\n", testHashingFunction(sha1Hash));
+ printf("CRC64: %lu\n", testHashingFunction(crc64Hash));
+ return 0;
+}