add Hasher.reset and Hash.hashUnordered

This commit is contained in:
Brendan Hansknecht 2022-10-12 15:01:16 -07:00
parent ab16effa00
commit e937a9078c
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
3 changed files with 35 additions and 20 deletions

View file

@ -228,6 +228,7 @@ LowLevelHasher := { originalSeed : U64, state : U64 } has [
addI64,
addI128,
complete,
reset,
},
]
@ -244,6 +245,9 @@ combineState = \@LowLevelHasher { originalSeed, state }, { a, b, seed, length }
complete = \@LowLevelHasher { state } -> state
reset = \@LowLevelHasher { originalSeed } ->
@LowLevelHasher { originalSeed, state: originalSeed }
addI8 = \hasher, i8 ->
addU8 hasher (Num.toU8 i8)
addI16 = \hasher, i16 ->

View file

@ -15,8 +15,10 @@ interface Hash
addI64,
addI128,
complete,
reset,
hashStrBytes,
hashList,
hashUnordered,
] imports [
List,
Str,
@ -73,6 +75,10 @@ Hasher has
## accumulated hash state.
complete : a -> U64 | a has Hasher
## Resets the internal state of a hasher
## The hasher should still have all the same parameters and seeds.
reset : a -> a | a has Hasher
## Adds a string into a [Hasher] by hashing its UTF-8 bytes.
hashStrBytes = \hasher, s ->
addBytes hasher (Str.toUtf8 s)
@ -82,22 +88,25 @@ hashList = \hasher, lst ->
List.walk lst hasher \accumHasher, elem ->
hash accumHasher elem
# hashUnordered = \hasher, container, walk ->
# walk
# container
# 0
# (\accum, elem ->
# x =
# hasher
# |> new
# |> hash elem
# |> complete
# nextAccum = Num.addWrap accum x
## Adds a container of [Hash]able elements to a [Hasher] by hashing each element.
## The container is iterated using the walk method passed in.
## The order of the elements does not effect the final hash.
hashUnordered = \hasher, container, walk ->
walk
container
0
(\accum, elem ->
x =
hasher
|> reset
|> hash elem
|> complete
nextAccum = Num.addWrap accum x
# if nextAccum < accum then
# # we dont want to lose a bit of entropy on overflow, so add it back in.
# Num.addWrap nextAccum 1
# else
# nextAccum
# )
# |> \accum -> addU64 hasher accum
if nextAccum < accum then
# we dont want to lose a bit of entropy on overflow, so add it back in.
Num.addWrap nextAccum 1
else
nextAccum
)
|> \accum -> addU64 hasher accum

View file

@ -1530,8 +1530,10 @@ define_builtins! {
12 HASH_ADD_I64: "addI64"
13 HASH_ADD_I128: "addI128"
14 HASH_COMPLETE: "complete"
15 HASH_HASH_STR_BYTES: "hashStrBytes"
16 HASH_HASH_LIST: "hashList"
15 HASH_RESET: "reset"
16 HASH_HASH_STR_BYTES: "hashStrBytes"
17 HASH_HASH_LIST: "hashList"
18 HASH_HASH_UNORDERED: "hashUnordered"
}
14 JSON: "Json" => {
0 JSON_JSON: "Json"