ref: 83d26331a5419033927800760e8a59f1bd84d2b9
parent: 8a662861ad3ded8e965ab43e5bc254dd7ee85815
author: Lucas Gabriel Vuotto <[email protected]>
date: Wed Nov 1 12:53:26 EDT 2017
Use new traits to implement hash tables Signed-off-by: Lucas Gabriel Vuotto <[email protected]>
--- a/bench/hashit.myr
+++ b/bench/hashit.myr
@@ -5,21 +5,21 @@
testr.bench([
[.name="hashstr", .fn={ctx;
for var i = 0; i < 1000; i++
- std.strhash("foobar")
+ std.hash("foobar")
;;
}],
[.name="hashint", .fn={ctx
for var i = 0; i < 1000; i++
- std.inthash(123)
+ std.hash(123)
;;
}],
[.name="hashlongstr", .fn={ctx
for var i = 0; i < 1000; i++
- std.strhash(a)
+ std.hash(a)
;;
}],
[.name="htget", .fn={ctx
- var h = std.mkht(std.strhash, std.streq)
+ var h = std.mkht()
std.htput(h, "foo", 123)
for var i = 0; i < 1000; i++
std.htget(h, "foo")
@@ -27,7 +27,7 @@
std.htfree(h)
}],
[.name="htput", .fn={ctx
- var h = std.mkht(std.strhash, std.streq)
+ var h = std.mkht()
for var i = 0; i < 1000; i++
std.htput(h, "foo", 123)
;;
@@ -34,7 +34,7 @@
std.htfree(h)
}],
[.name="htputmany", .fn={ctx
- var h = std.mkht(std.inthash, std.inteq)
+ var h = std.mkht()
for var i = 0; i < 1000; i++
std.htput(h, i, 123)
;;
--- a/lib/date/parse.myr
+++ b/lib/date/parse.myr
@@ -164,7 +164,7 @@
const indexof = {dst, s, set, err
for var i = 0; i < set.len; i++
- if s.len >= set[i].len && std.streq(s[:set[i].len], set[i])
+ if s.len >= set[i].len && std.cmp(s[:set[i].len], set[i])
dst# = i
-> s[set[i].len:]
;;
--- a/lib/fileutil/loopcheck+posixy.myr
+++ b/lib/fileutil/loopcheck+posixy.myr
@@ -14,7 +14,7 @@
var ht : std.htab((int64, int64), void)#
var l
- ht = std.mkht(fidhash, fideq)
+ ht = std.mkht()
l = (ht : loopcheck)
looped(l, cwd)
-> l
@@ -48,18 +48,22 @@
;;
}
-const fidhash = {fid
- var dev, ino
+impl std.hashable (int64, int64) =
+ hash = {fid
+ var dev, ino
- (dev, ino) = fid
- -> std.inthash(dev) ^ std.inthash(ino)
-}
+ (dev, ino) = fid
+ -> std.hash(dev) ^ std.hash(ino)
+ }
+;;
-const fideq = {a, b
- var adev, aino
- var bdev, bino
+impl std.comparable (int64, int64) =
+ cmp = {a, b
+ var adev, aino
+ var bdev, bino
- (adev, aino) = a
- (bdev, bino) = b
- -> adev == bdev && aino == bino
-}
+ (adev, aino) = a
+ (bdev, bino) = b
+ -> adev == bdev && aino == bino
+ }
+;;
--- a/lib/http/parse.myr
+++ b/lib/http/parse.myr
@@ -10,6 +10,19 @@
pkglocal const parsenumber : (str : byte[:]#, base : int -> std.option(int))
;;
+const strcaseeq = {a : byte[:], b : byte[:] -> bool
+ var ca, cb
+
+ while a.len == 0 || b.len == 0
+ (ca, a) = std.strstep(a)
+ (cb, b) = std.strstep(b)
+ if std.tolower(ca) != std.tolower(cb)
+ -> false
+ ;;
+ ;;
+ -> a.len == b.len
+}
+
const parsereq = {s
var r, err
@@ -221,7 +234,7 @@
const findhdr = {r, name
for (k, v) : r.hdrs
- if std.strcaseeq(k, name)
+ if strcaseeq(k, name)
-> `std.Some v
;;
;;
--- a/lib/inifile/parse.myr
+++ b/lib/inifile/parse.myr
@@ -44,7 +44,7 @@
var f
ini = std.mk([
- .elts = std.mkht(keyhash, keyeq)
+ .elts = std.mkht()
])
p = std.mk([
.line = 1,
@@ -138,20 +138,3 @@
-> true
;;
}
-
-const keyhash = {k
- var sect, key
-
- (sect, key) = k
- -> std.strhash(sect) ^ std.strhash(key)
-}
-
-const keyeq = {a, b
- var s1, k1
- var s2, k2
-
- (s1, k1) = a
- (s2, k2) = a
- -> std.streq(s1, s2) && std.streq(k1, k2)
-}
-
--- a/lib/inifile/types.myr
+++ b/lib/inifile/types.myr
@@ -11,4 +11,27 @@
sects : byte[:][:]
elts : std.htab((byte[:], byte[:]), byte[:])#
;;
+
+ impl std.hashable (byte[:], byte[:])
+ impl std.comparable (byte[:], byte[:])
+;;
+
+impl std.hashable (byte[:], byte[:]) =
+ hash = {k
+ var sect, key
+
+ (sect, key) = k
+ -> std.hash(sect) ^ std.hash(key)
+ }
+;;
+
+impl std.comparable (byte[:], byte[:]) =
+ cmp = {a, b
+ var s1, k1
+ var s2, k2
+
+ (s1, k1) = a
+ (s2, k2) = a
+ -> std.cmp(s1, s2) && std.cmp(k1, k2)
+ }
;;
--- a/lib/regex/compile.myr
+++ b/lib/regex/compile.myr
@@ -46,7 +46,7 @@
.nmatch = 1,
.debug = true,
.trace = trace,
- .astloc = std.mkht(std.ptrhash, std.ptreq),
+ .astloc = std.mkht(),
])
res = regexcompile(re, 0)
-> res
--- a/lib/std/bitset.myr
+++ b/lib/std/bitset.myr
@@ -1,12 +1,13 @@
use "alloc"
use "die"
use "extremum"
+use "hashfuncs"
use "mk"
use "slcp"
use "sldup"
use "slfill"
+use "traits"
use "types"
-use "hashfuncs"
pkg std =
type bitset = struct
@@ -28,10 +29,11 @@
const bsdiff : (a : bitset#, b : bitset# -> void)
const bsintersect : (a : bitset#, b : bitset# -> void)
const bsunion : (a : bitset#, b : bitset# -> void)
- const bseq : (a : bitset#, b : bitset# -> bool)
const bsissubset : (a : bitset#, b : bitset# -> bool)
- const bshash : (a : bitset# -> uint64)
+ impl comparable bitset#
+ impl hashable bitset#
+
type bsiter = struct
idx : size
bs : bitset#
@@ -145,25 +147,29 @@
-> true
}
-const bseq = {a, b
- eqsz(a, b)
- for var i = 0; i < a.bits.len; i++
- if a.bits[i] != b.bits[i]
- -> false
+impl comparable bitset# =
+ cmp = {a, b
+ eqsz(a, b)
+ for var i = 0; i < a.bits.len; i++
+ if a.bits[i] != b.bits[i]
+ -> false
+ ;;
;;
- ;;
- -> true
-}
+ -> true
+ }
+;;
-const bshash = {a
- var end : size
+impl hashable bitset# =
+ hash = {a
+ var end : size
- end = a.bits.len
- while end > 0 && a.bits[end - 1] == 0
- end--
- ;;
- -> std.slhash(a.bits[:end])
-}
+ end = a.bits.len
+ while end > 0 && a.bits[end - 1] == 0
+ end--
+ ;;
+ -> std.hash(a.bits[:end])
+ }
+;;
const ensurelen = {bs, len
if bs.bits.len <= len
--- a/lib/std/fmt.myr
+++ b/lib/std/fmt.myr
@@ -21,6 +21,7 @@
use "strsplit"
use "syswrap"
use "syswrap-ss"
+use "traits"
use "types"
use "utf"
use "varargs"
@@ -55,7 +56,7 @@
;;
const __init__ = {
- fmtmap = mkht(strhash, streq)
+ fmtmap = mkht()
}
type fmtdesc = struct
--- a/lib/std/hashfuncs.myr
+++ b/lib/std/hashfuncs.myr
@@ -9,23 +9,8 @@
use "utf"
pkg std =
- const strhash : (s : byte[:] -> uint64)
- const streq : (a : byte[:], b : byte[:] -> bool)
-
- const strcasehash : (s : byte[:] -> uint64)
- const strcaseeq : (a : byte[:], b : byte[:] -> bool)
-
- generic ptrhash : (p : @a# -> uint64)
- generic ptreq : (a : @a#, b : @a# -> bool)
-
- generic inthash : (v : @a::(integral,numeric) -> uint64)
- generic inteq : (a : @a::(integral,numeric), b : @a::(integral,numeric) -> bool)
-
- const murmurhash2 : (data : byte[:], seed : uint32 -> uint32)
const siphash24 : (data : byte[:], seed : byte[16] -> uint64)
- generic slhash : (sl : @a[:] -> uint64)
-
impl comparable @a[:] =
cmp = {a, b
-> sleq(a, b)
@@ -64,119 +49,6 @@
;;
const Seed : byte[16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
-
-generic slhash = {data : @a[:]
- -> strhash(slbytes(data))
-}
-
-generic slbytes = {data : @a[:]
- var n
-
- n = data.len * sizeof(@a)
- -> (data : byte#)[:n]
-}
-
-const strhash = {s
- -> siphash24(s, Seed)
-}
-
-const strcaseeq = {a, b
- var ca, cb
-
- while true
- if a.len == 0 || b.len == 0
- break
- ;;
- (ca, a) = std.charstep(a)
- (cb, b) = std.charstep(b)
- if std.tolower(ca) != std.tolower(cb)
- -> false
- ;;
- ;;
- -> a.len == b.len
-}
-
-const strcasehash = {s
- var chars
- var c, h
-
- chars = [][:]
- while s.len != 0
- (c, s) = std.charstep(s)
- std.slpush(&chars, std.tolower(c))
- ;;
- h = siphash24(slbytes(chars), Seed)
- slfree(chars)
- -> h
-}
-
-const streq = {a, b
- -> sleq(a, b)
-}
-
-generic ptrhash = {p : @a#
- -> inthash((p : intptr))
-}
-
-generic ptreq = {a, b
- -> a == b
-}
-
-generic inthash = {v : @a::(integral,numeric)
- var p
-
- p = (&v : byte#)
- -> siphash24(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] : uint32)
- k |= (data[1] : uint32) << 8
- k |= (data[2] : uint32) << 16
- k |= (data[3] : uint32) << 24
-
- k *= m
- k ^= k >> r
- k *= m
-
- h *= m
- h ^= k
- data = data[4:]
- ;;
-
- match data.len
- | 3:
- h ^= (data[2] : uint32) << 16
- h ^= (data[1] : uint32) << 8
- h ^= (data[0] : uint32)
- h *= m
- | 2:
- h ^= (data[1] : uint32) << 8
- h ^= (data[0] : uint32)
- h *= m
- | 1:
- h ^= (data[0] : uint32)
- h *= m
- | 0: /* nothing */
- | _: die("0 < len < 4 must be true")
- ;;
-
- h ^= h >> 13
- h *= m
- h ^= h >> 15
-
- -> h
-}
const sipround = {v0, v1, v2, v3 -> (uint64, uint64, uint64, uint64)
v0 += v1
--- a/lib/std/htab.myr
+++ b/lib/std/htab.myr
@@ -2,6 +2,7 @@
use "die"
use "extremum"
use "option"
+use "traits"
use "types"
pkg std =
@@ -17,8 +18,8 @@
dead : bool[:]
;;
- generic mkht : (h : (k : @k -> uint64), eq : (a : @k, b : @k -> bool) -> htab(@k, @v)#)
- generic htinit : (ht : htab(@k, @v)#, h : (k : @k -> uint64), eq : (a : @k, b : @k -> bool) -> void)
+ generic mkht : ( -> htab(@k, @v)#)
+ generic htinit : (ht : htab(@k, @v)# -> void)
generic htfree : (ht : htab(@k, @v)# -> void)
generic htput : (ht : htab(@k, @v)#, k : @k, v : @v -> void)
generic htdel : (ht : htab(@k, @v)#, k : @k -> void)
@@ -38,10 +39,10 @@
const Initsz = 32
-generic hash = {ht, k
+generic xhash = {k
var h
- h = ht.hash(k)
+ h = hash(k)
if h == 0
-> 1
else
@@ -82,7 +83,7 @@
var h
di = 0
- h = hash(ht, k)
+ h = xhash(k)
i = h & (ht.keys.len - 1)
while true
while ht.hashes[i] != 0 && !ht.dead[i] && ht.hashes[i] != h
@@ -92,7 +93,7 @@
if ht.hashes[i] == 0
-> `None
;;
- if ht.hashes[i] == h && !ht.dead[i] && ht.eq(ht.keys[i], k)
+ if ht.hashes[i] == h && !ht.dead[i] && cmp(ht.keys[i], k)
break
;;
di++
@@ -101,20 +102,16 @@
-> `Some i
}
-generic mkht = {h, eq
+generic mkht = {
var ht
ht = alloc()
- htinit(ht, h, eq)
+ htinit(ht)
-> ht
}
-generic htinit = {ht, h, eq
-
- ht.hash = h
- ht.eq = eq
-
+generic htinit = {ht
ht.nelt = 0
ht.ndead = 0
ht.keys = slalloc(Initsz)
@@ -137,11 +134,11 @@
var neltincr
di = 0
- h = hash(ht, k)
+ h = xhash(k)
i = h & (ht.keys.len - 1)
neltincr = 1
while ht.hashes[i] != 0 && !ht.dead[i]
- if ht.hashes[i] == h && ht.eq(ht.keys[i], k)
+ if ht.hashes[i] == h && cmp(ht.keys[i], k)
neltincr = 0
break
;;
--- a/lib/std/resolve+posixy.myr
+++ b/lib/std/resolve+posixy.myr
@@ -72,8 +72,8 @@
var nameservers : netaddr[:]
const __init__ = {
- hostmap = mkht(strhash, streq)
- dnscache = mkht(strhash, streq)
+ hostmap = mkht()
+ dnscache = mkht()
loadhosts()
loadresolv()
}
--- a/lib/std/wait+plan9.myr
+++ b/lib/std/wait+plan9.myr
@@ -32,7 +32,7 @@
var statusmap : htab(pid, waitstatus)#
const __init__ = {
- statusmap = mkht(inthash, inteq)
+ statusmap = mkht()
}
const waitany = {
--- a/mbld/deps.myr
+++ b/mbld/deps.myr
@@ -362,8 +362,8 @@
;;
stk = [][:]
- visited = std.mkht(std.ptrhash, std.ptreq)
- looped = std.mkht(std.ptrhash, std.ptreq)
+ visited = std.mkht()
+ looped = std.mkht()
for n : g.nodes
checkloop(g, n, visited, looped, &stk)
;;
--- a/mbld/libs.myr
+++ b/mbld/libs.myr
@@ -119,9 +119,9 @@
var added, diradded, looped
var lo
- added = std.mkht(std.strhash, std.streq)
- looped = std.mkht(std.strhash, std.streq)
- diradded = std.mkht(std.strhash, std.streq)
+ added = std.mkht()
+ looped = std.mkht()
+ diradded = std.mkht()
lo = sl#.len
for l : libs
--- a/mbld/main.myr
+++ b/mbld/main.myr
@@ -140,13 +140,13 @@
var b
b = std.zalloc()
- b.libs = std.mkht(std.strhash, std.streq)
- b.proc = std.mkht(std.inthash, std.inteq)
- b.targs = std.mkht(std.strhash, std.streq)
- b.tags = std.mkht(std.strhash, std.streq)
+ b.libs = std.mkht()
+ b.proc = std.mkht()
+ b.targs = std.mkht()
+ b.tags = std.mkht()
b.deps = std.mk([
- .targs = std.mkht(std.strhash, std.streq),
- .gen = std.mkht(std.strhash, std.streq),
+ .targs = std.mkht(),
+ .gen = std.mkht(),
.leaves = [][:],
.nodes = [][:],
])
--- a/mbld/parse.myr
+++ b/mbld/parse.myr
@@ -61,8 +61,8 @@
var all
all = [][:]
- looped = std.mkht(std.strhash, std.streq)
- marked = std.mkht(std.strhash, std.streq)
+ looped = std.mkht()
+ marked = std.mkht()
for dep : b.all
match gettarg(b.targs, dep)
| `Bin _: all = visit(all, b, "all", dep, looped, marked)
--- a/mbld/syssel.myr
+++ b/mbld/syssel.myr
@@ -27,8 +27,8 @@
.file = file,
.line = line,
.targ = targ,
- ._match = std.mkht(std.strhash, std.streq),
- ._best = std.mkht(std.strhash, std.streq),
+ ._match = std.mkht(),
+ ._best = std.mkht(),
.sysattrs = b.tags
])
-> syssel
--- a/support/dumpleak.myr
+++ b/support/dumpleak.myr
@@ -38,7 +38,7 @@
;;
;;
- stats.tab = std.mkht(std.inthash, std.inteq)
+ stats.tab = std.mkht()
for d : cmd.args
match bio.open(d, bio.Rd)
| `std.Ok f: dump(d, f, &stats)
@@ -99,7 +99,7 @@
const dumptrace = {tab
var aggr
- aggr = std.mkht(hashintsl, std.sleq)
+ aggr = std.mkht()
for (k, (sz, stk)) : std.byhtkeyvals(tab)
match std.htget(aggr, stk[:stackaggr])
| `std.Some (count, total):
@@ -119,14 +119,4 @@
| `std.Ok v: -> v
| res: std.fatal("failed to read {}: {}\n", path, res)
;;
-}
-
-const hashintsl = {sl
- var h
-
- h = 0
- for i : sl
- h ^= std.inthash(i)
- ;;
- -> h
}