shithub: mc

Download patch

ref: efb1de08fbc7c6d5ee8966362549c95bca536067
parent: 6ac0e591f2297ee9c3a5519844d9825e25db037b
parent: e53b3a2d57e7162903c7312a25e37cb61b88a015
author: Ori Bernstein <[email protected]>
date: Wed Apr 23 09:02:59 EDT 2014

Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc

--- a/libstd/hashfuncs.myr
+++ b/libstd/hashfuncs.myr
@@ -10,17 +10,15 @@
 
 	generic inthash	: (v : @a::(integral,numeric)	-> uint32)
 	generic inteq	: (a : @a::(integral,numeric), b : @a::(integral,numeric) -> bool)
+
+	const murmurhash2	: (data : byte[:], seed : uint32 -> uint32)
 ;;
 
+const Seed = 1234
+
 /* Supremely simple djb hash. */
 const strhash = {s
-	var h
-	
-	h = 5381
-	for b in s
-		h = (h << 5) + h + (b castto(uint32))
-	;;
-	-> h
+	-> murmurhash2(s, Seed)
 }
 
 const streq = {a, b
@@ -27,14 +25,11 @@
 	-> sleq(a, b)
 }
 
-/* FIXME: come up with a *good* hash function */
-generic ptrhash = {p
+generic ptrhash = {p : @a#
 	var x
 
-	x = p castto(intptr)
-	/* Mix the top bits in to the bottom, and multiply by a large prime. */
-	x = x ^ (x >> 32) * 357913941	
-	-> x castto(uint32)
+	x = &p castto(byte#)
+	-> murmurhash2(x[0:sizeof(@a)], Seed)
 }
 
 generic ptreq = {a, b
@@ -41,16 +36,54 @@
 	-> a == b
 }
 
-/* FIXME: come up with a *good* hash function */
-generic inthash = {v
-	var x
+generic inthash = {v : @a::(integral,numeric)
+	var p
 
-	x = v castto(uint64)
-	/* Mix the top bits in to the bottom, and multiply by a large prime. */
-	x = x ^ (x >> 32) * 357913941	
-	-> x castto(uint32)
+	p = &v castto(byte#)
+	-> murmurhash2(p[0:sizeof(@a)], Seed)
 }
 
 generic inteq = {a, b
 	-> a == b
+}
+
+const murmurhash2 = {data, seed
+	const m = 0x5bd1e995;
+	const r = 24
+	var h, k
+	
+	h = seed ^ data.len
+	while data.len >= 4
+		k = (data[0] castto(uint32))
+		k |= (data[1] castto(uint32)) << 8
+		k |= (data[2] castto(uint32)) << 16
+		k |= (data[3] castto(uint32)) << 24
+
+		k *= m
+		k ^= k >> r
+		k *= m
+
+		h *= m
+		h ^= k
+		data = data[4:]
+	;;
+
+	match data.len
+	| 3:
+		h ^= (data[2] castto(uint32)) << 16
+		h ^= (data[1] castto(uint32)) <<8
+		h ^= (data[0] castto(uint32))
+	| 2:
+		h ^= (data[1] castto(uint32)) <<8
+		h ^= (data[0] castto(uint32))
+	| 1:
+		h ^= (data[0] castto(uint32))
+	;;
+	h *= m
+
+	h ^= h >> 13
+	h *= m
+	h ^= h >> 15
+
+	-> h
 }
--- /dev/null
+++ b/test/exporttrait.myr
@@ -1,0 +1,14 @@
+pkg =
+	trait t @a
+	impl t int
+;;
+
+trait t @a =
+	frob    : (v : @a -> @a)
+;;
+
+impl t int =
+	frob = {v
+		-> v*2
+	}
+;;
--- a/test/tests
+++ b/test/tests
@@ -121,6 +121,7 @@
 B strjoin	C
 B stdslcp	C
 B bigint	C
+B exporttrait
 # B local-labels	E	10 ## BUGGERED
 F declmismatch
 F infermismatch