implement Dict.withCapacity and improve Dict.fromList

This commit is contained in:
Brendan Hansknecht 2023-12-03 16:05:33 -08:00
parent 6692f5b15d
commit f31a4070e4
No known key found for this signature in database
GPG key ID: 0EA784685083E75B
2 changed files with 39 additions and 13 deletions

View file

@ -150,6 +150,32 @@ empty = \{} ->
size: 0,
}
## Return a dictionary with space allocated for a number of entries. This
## may provide a performance optimization if you know how many entries will be
## inserted.
withCapacity : Nat -> Dict * *
withCapacity = \size ->
if size == 0 then
empty {}
else
cap =
size
|> Num.toU64
|> containingPowerOfTwo
|> Num.max 8
|> Num.toNat
@Dict {
metadata: List.repeat emptySlot cap,
dataIndices: List.repeat 0 cap,
data: List.withCapacity cap,
size: 0,
}
containingPowerOfTwo : U64 -> U64
containingPowerOfTwo = \size ->
Num.shiftLeftBy 1 (64 - Num.countLeadingZeroBits (size - 1))
## Returns the max number of elements the dictionary can hold before requiring a rehash.
## ```
## foodDict =
@ -164,14 +190,6 @@ capacity = \@Dict { dataIndices } ->
Num.subWrap cap (Num.shiftRightZfBy cap 3)
## Return a dictionary with space allocated for a number of entries. This
## may provide a performance optimization if you know how many entries will be
## inserted.
withCapacity : Nat -> Dict * *
withCapacity = \_ ->
# TODO: power of 2 * 8 and actual implementation
empty {}
## Returns a dictionary containing the key and value provided as input.
## ```
## expect
@ -193,8 +211,15 @@ single = \k, v ->
## ```
fromList : List (k, v) -> Dict k v where k implements Hash & Eq
fromList = \data ->
# TODO: make this efficient. Should just set data and then set all indicies in the hashmap.
List.walk data (empty {}) (\dict, (k, v) -> insert dict k v)
# TODO: make more efficient.
# Want to just set the data and then set all indicies in the hashmap.
# That said, we need to also deal with duplicates.
size = List.len data
if size > 0 then
List.walk data (withCapacity size) (\dict, (k, v) -> insert dict k v)
else
empty {}
## Returns the number of values in the dictionary.
## ```

View file

@ -237,9 +237,10 @@ toList = \@Set dict ->
## ```
fromList : List k -> Set k where k implements Hash & Eq
fromList = \list ->
initial = @Set (Dict.withCapacity (List.len list))
List.walk list initial insert
list
|> List.map \k -> (k, {})
|> Dict.fromList
|> @Set
## Combine two `Set` collection by keeping the
## [union](https://en.wikipedia.org/wiki/Union_(set_theory))