mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
implement Dict.withCapacity and improve Dict.fromList
This commit is contained in:
parent
6692f5b15d
commit
f31a4070e4
2 changed files with 39 additions and 13 deletions
|
@ -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.
|
||||
## ```
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue