aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/vlib/hash
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/vlib/hash')
-rw-r--r--v_windows/v/vlib/hash/crc32/crc32.v63
-rw-r--r--v_windows/v/vlib/hash/crc32/crc32_test.v14
-rw-r--r--v_windows/v/vlib/hash/fnv1a/fnv1a.v44
-rw-r--r--v_windows/v/vlib/hash/fnv1a/fnv1a_test.v12
-rw-r--r--v_windows/v/vlib/hash/hash.v20
-rw-r--r--v_windows/v/vlib/hash/wyhash.c.v33
-rw-r--r--v_windows/v/vlib/hash/wyhash.js.v1
-rw-r--r--v_windows/v/vlib/hash/wyhash.v72
8 files changed, 259 insertions, 0 deletions
diff --git a/v_windows/v/vlib/hash/crc32/crc32.v b/v_windows/v/vlib/hash/crc32/crc32.v
new file mode 100644
index 0000000..d29aa12
--- /dev/null
+++ b/v_windows/v/vlib/hash/crc32/crc32.v
@@ -0,0 +1,63 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+
+// This is a very basic crc32 implementation
+// at the moment with no architecture optimizations
+module crc32
+
+// polynomials
+pub const (
+ ieee = u32(0xedb88320)
+ castagnoli = u32(0x82f63b78)
+ koopman = u32(0xeb31d82e)
+)
+
+// The size of a CRC-32 checksum in bytes.
+const (
+ size = 4
+)
+
+struct Crc32 {
+mut:
+ table []u32
+}
+
+fn (mut c Crc32) generate_table(poly int) {
+ for i in 0 .. 256 {
+ mut crc := u32(i)
+ for _ in 0 .. 8 {
+ if crc & u32(1) == u32(1) {
+ crc = (crc >> 1) ^ u32(poly)
+ } else {
+ crc >>= u32(1)
+ }
+ }
+ c.table << crc
+ }
+}
+
+fn (c &Crc32) sum32(b []byte) u32 {
+ mut crc := ~u32(0)
+ for i in 0 .. b.len {
+ crc = c.table[byte(crc) ^ b[i]] ^ (crc >> 8)
+ }
+ return ~crc
+}
+
+pub fn (c &Crc32) checksum(b []byte) u32 {
+ return c.sum32(b)
+}
+
+// pass the polynomial to use
+pub fn new(poly int) &Crc32 {
+ mut c := &Crc32{}
+ c.generate_table(poly)
+ return c
+}
+
+// calculate crc32 using ieee
+pub fn sum(b []byte) u32 {
+ c := new(int(crc32.ieee))
+ return c.sum32(b)
+}
diff --git a/v_windows/v/vlib/hash/crc32/crc32_test.v b/v_windows/v/vlib/hash/crc32/crc32_test.v
new file mode 100644
index 0000000..7355179
--- /dev/null
+++ b/v_windows/v/vlib/hash/crc32/crc32_test.v
@@ -0,0 +1,14 @@
+import hash.crc32
+
+fn test_hash_crc32() {
+ b1 := 'testing crc32'.bytes()
+ sum1 := crc32.sum(b1)
+ assert sum1 == u32(1212124400)
+ assert sum1.hex() == '483f8cf0'
+
+ c := crc32.new(int(crc32.ieee))
+ b2 := 'testing crc32 again'.bytes()
+ sum2 := c.checksum(b2)
+ assert sum2 == u32(1420327025)
+ assert sum2.hex() == '54a87871'
+}
diff --git a/v_windows/v/vlib/hash/fnv1a/fnv1a.v b/v_windows/v/vlib/hash/fnv1a/fnv1a.v
new file mode 100644
index 0000000..275c8a2
--- /dev/null
+++ b/v_windows/v/vlib/hash/fnv1a/fnv1a.v
@@ -0,0 +1,44 @@
+module fnv1a
+
+const (
+ fnv64_prime = u64(1099511628211)
+ fnv64_offset_basis = u64(14695981039346656037)
+ fnv32_offset_basis = u32(2166136261)
+ fnv32_prime = u32(16777619)
+)
+
+[inline]
+pub fn sum32_string(data string) u32 {
+ mut hash := fnv1a.fnv32_offset_basis
+ for i in 0 .. data.len {
+ hash = (hash ^ u32(data[i])) * fnv1a.fnv32_prime
+ }
+ return hash
+}
+
+[inline]
+pub fn sum32(data []byte) u32 {
+ mut hash := fnv1a.fnv32_offset_basis
+ for i in 0 .. data.len {
+ hash = (hash ^ u32(data[i])) * fnv1a.fnv32_prime
+ }
+ return hash
+}
+
+[inline]
+pub fn sum64_string(data string) u64 {
+ mut hash := fnv1a.fnv64_offset_basis
+ for i in 0 .. data.len {
+ hash = (hash ^ u64(data[i])) * fnv1a.fnv64_prime
+ }
+ return hash
+}
+
+[inline]
+pub fn sum64(data []byte) u64 {
+ mut hash := fnv1a.fnv64_offset_basis
+ for i in 0 .. data.len {
+ hash = (hash ^ u64(data[i])) * fnv1a.fnv64_prime
+ }
+ return hash
+}
diff --git a/v_windows/v/vlib/hash/fnv1a/fnv1a_test.v b/v_windows/v/vlib/hash/fnv1a/fnv1a_test.v
new file mode 100644
index 0000000..f775ab1
--- /dev/null
+++ b/v_windows/v/vlib/hash/fnv1a/fnv1a_test.v
@@ -0,0 +1,12 @@
+import hash.fnv1a
+
+fn test_fnv1a() {
+ $if windows {
+ return
+ }
+ a := 'apple'
+ b := fnv1a.sum64_string(a)
+ c := fnv1a.sum64(a.bytes())
+ assert b.hex() == 'f74a62a458befdbf'
+ assert c.hex() == 'f74a62a458befdbf'
+}
diff --git a/v_windows/v/vlib/hash/hash.v b/v_windows/v/vlib/hash/hash.v
new file mode 100644
index 0000000..eabb166
--- /dev/null
+++ b/v_windows/v/vlib/hash/hash.v
@@ -0,0 +1,20 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+module hash
+
+interface Hasher {
+ // Sum appends the current hash to b and returns the resulting array.
+ // It does not change the underlying hash state.
+ sum(b []byte) []byte
+ size() int
+ block_size() int
+}
+
+interface Hash32er {
+ sum32() u32
+}
+
+interface Hash64er {
+ sum64() u64
+}
diff --git a/v_windows/v/vlib/hash/wyhash.c.v b/v_windows/v/vlib/hash/wyhash.c.v
new file mode 100644
index 0000000..3f93d24
--- /dev/null
+++ b/v_windows/v/vlib/hash/wyhash.c.v
@@ -0,0 +1,33 @@
+module hash
+
+//#flag -I @VEXEROOT/thirdparty/wyhash
+//#include "wyhash.h"
+fn C.wyhash(&byte, u64, u64, &u64) u64
+
+fn C.wyhash64(u64, u64) u64
+
+fn init() {
+ _ := {
+ 1: 1
+ }
+}
+
+[inline]
+pub fn wyhash_c(key &byte, len u64, seed u64) u64 {
+ return C.wyhash(key, len, seed, &u64(C._wyp))
+}
+
+[inline]
+pub fn wyhash64_c(a u64, b u64) u64 {
+ return C.wyhash64(a, b)
+}
+
+[inline]
+pub fn sum64_string(key string, seed u64) u64 {
+ return wyhash_c(key.str, u64(key.len), seed)
+}
+
+[inline]
+pub fn sum64(key []byte, seed u64) u64 {
+ return wyhash_c(&byte(key.data), u64(key.len), seed)
+}
diff --git a/v_windows/v/vlib/hash/wyhash.js.v b/v_windows/v/vlib/hash/wyhash.js.v
new file mode 100644
index 0000000..26af4da
--- /dev/null
+++ b/v_windows/v/vlib/hash/wyhash.js.v
@@ -0,0 +1 @@
+module hash
diff --git a/v_windows/v/vlib/hash/wyhash.v b/v_windows/v/vlib/hash/wyhash.v
new file mode 100644
index 0000000..fb438a1
--- /dev/null
+++ b/v_windows/v/vlib/hash/wyhash.v
@@ -0,0 +1,72 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+//
+// this is an implementation of wyhash v4
+// from https://github.com/wangyi-fudan/wyhash
+//
+// TODO: use u128 once implemented
+// currently the C version performs slightly better
+// because it uses 128 bit int when available and
+// branch prediction hints. the C version will be
+// removed once the perfomance is matched.
+// you can test performance by running:
+// `v run cmd/tools/bench/wyhash.v`
+// try running with and without the `-prod` flag
+module hash
+
+const (
+ wyp0 = u64(0xa0761d6478bd642f)
+ wyp1 = u64(0xe7037ed1a0b428db)
+ wyp2 = u64(0x8ebc6af09c88c6e3)
+ wyp3 = u64(0x589965cc75374cc3)
+ wyp4 = u64(0x1d8e4e27c47d124f)
+)
+
+[inline]
+fn wyrotr(v u64, k u32) u64 {
+ return (v >> k) | (v << (64 - k))
+}
+
+[inline]
+pub fn wymum(a u64, b u64) u64 {
+ /*
+ mut r := u128(a)
+ r = r*b
+ return (r>>64)^r
+ */
+ mask32 := u32(4294967295)
+ x0 := a & mask32
+ x1 := a >> 32
+ y0 := b & mask32
+ y1 := b >> 32
+ w0 := x0 * y0
+ t := x1 * y0 + (w0 >> 32)
+ mut w1 := t & mask32
+ w2 := t >> 32
+ w1 += x0 * y1
+ hi := x1 * y1 + w2 + (w1 >> 32)
+ lo := a * b
+ return hi ^ lo
+}
+
+[inline]
+fn wyr3(p &byte, k u64) u64 {
+ unsafe {
+ return (u64(p[0]) << 16) | (u64(p[k >> 1]) << 8) | u64(p[k - 1])
+ }
+}
+
+[inline]
+fn wyr4(p &byte) u64 {
+ unsafe {
+ return u32(p[0]) | (u32(p[1]) << u32(8)) | (u32(p[2]) << u32(16)) | (u32(p[3]) << u32(24))
+ }
+}
+
+[inline]
+fn wyr8(p &byte) u64 {
+ unsafe {
+ return u64(p[0]) | (u64(p[1]) << 8) | (u64(p[2]) << 16) | (u64(p[3]) << 24) | (u64(p[4]) << 32) | (u64(p[5]) << 40) | (u64(p[6]) << 48) | (u64(p[7]) << 56)
+ }
+}