summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/librdkafka-2.1.0/src/rdfnv1a.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/librdkafka-2.1.0/src/rdfnv1a.c')
-rw-r--r--fluent-bit/lib/librdkafka-2.1.0/src/rdfnv1a.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/fluent-bit/lib/librdkafka-2.1.0/src/rdfnv1a.c b/fluent-bit/lib/librdkafka-2.1.0/src/rdfnv1a.c
new file mode 100644
index 000000000..e951ec59f
--- /dev/null
+++ b/fluent-bit/lib/librdkafka-2.1.0/src/rdfnv1a.c
@@ -0,0 +1,113 @@
+/*
+ * librdkafka - Apache Kafka C library
+ *
+ * Copyright (c) 2012-2020, Magnus Edenhill
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "rd.h"
+#include "rdunittest.h"
+#include "rdfnv1a.h"
+
+
+/* FNV-1a by Glenn Fowler, Landon Curt Noll, and Kiem-Phong Vo
+ *
+ * Based on http://www.isthe.com/chongo/src/fnv/hash_32a.c
+ * with librdkafka modifications to match the Sarama default Producer
+ * implementation, as seen here:
+ * https://github.com/Shopify/sarama/blob/master/partitioner.go#L203 Note that
+ * this implementation is only compatible with Sarama's default
+ * NewHashPartitioner and not NewReferenceHashPartitioner.
+ */
+uint32_t rd_fnv1a(const void *key, size_t len) {
+ const uint32_t prime = 0x01000193; // 16777619
+ const uint32_t offset = 0x811C9DC5; // 2166136261
+ size_t i;
+ int32_t h = offset;
+
+ const unsigned char *data = (const unsigned char *)key;
+
+ for (i = 0; i < len; i++) {
+ h ^= data[i];
+ h *= prime;
+ }
+
+ /* Take absolute value to match the Sarama NewHashPartitioner
+ * implementation */
+ if (h < 0) {
+ h = -h;
+ }
+
+ return (uint32_t)h;
+}
+
+
+/**
+ * @brief Unittest for rd_fnv1a()
+ */
+int unittest_fnv1a(void) {
+ const char *short_unaligned = "1234";
+ const char *unaligned = "PreAmbleWillBeRemoved,ThePrePartThatIs";
+ const char *keysToTest[] = {
+ "kafka",
+ "giberish123456789",
+ short_unaligned,
+ short_unaligned + 1,
+ short_unaligned + 2,
+ short_unaligned + 3,
+ unaligned,
+ unaligned + 1,
+ unaligned + 2,
+ unaligned + 3,
+ "",
+ NULL,
+ };
+
+ // Acquired via https://play.golang.org/p/vWIhw3zJINA
+ const int32_t golang_hashfnv_results[] = {
+ 0xd33c4e1, // kafka
+ 0x77a58295, // giberish123456789
+ 0x23bdd03, // short_unaligned
+ 0x2dea3cd2, // short_unaligned+1
+ 0x740fa83e, // short_unaligned+2
+ 0x310ca263, // short_unaligned+3
+ 0x65cbd69c, // unaligned
+ 0x6e49c79a, // unaligned+1
+ 0x69eed356, // unaligned+2
+ 0x6abcc023, // unaligned+3
+ 0x7ee3623b, // ""
+ 0x7ee3623b, // NULL
+ };
+
+ size_t i;
+ for (i = 0; i < RD_ARRAYSIZE(keysToTest); i++) {
+ uint32_t h = rd_fnv1a(
+ keysToTest[i], keysToTest[i] ? strlen(keysToTest[i]) : 0);
+ RD_UT_ASSERT((int32_t)h == golang_hashfnv_results[i],
+ "Calculated FNV-1a hash 0x%x for \"%s\", "
+ "expected 0x%x",
+ h, keysToTest[i], golang_hashfnv_results[i]);
+ }
+ RD_UT_PASS();
+}