* breaking changes to the API. Some of the weird decisions from before
are changed to what would be more expected.
- `get` returns `?V`, use `getEntry` for the old API.
- `put` returns `!void`, use `fetchPut` for the old API.
* HashMap now has a comptime parameter of whether to store hashes with
entries. AutoHashMap has heuristics on whether to set this parameter.
For example, for integers, it is false, since equality checking is
cheap, but for strings, it is true, since equality checking is
probably expensive.
* The implementation has a separate array for entry_index /
distance_from_start_index. Entries no longer has holes; it is an
ArrayList, and iteration is simpler and more cache coherent.
This is inspired by Python's new dictionaries.
* HashMap is separated into an "unmanaged" and a "managed" API. The
unmanaged API is where the actual implementation is; the managed API
wraps it and provides a more convenient API, storing the allocator.
* Memory usage: When there are less than or equal to 8 entries, HashMap
now incurs only a single pointer-size integer as overhead, opposed to
using an ArrayList.
* Since the entries array is separate from the indexes array, the holes
in the indexes array take up less room than the holes in the entries
array otherwise would. However the entries array also allocates
additional capacity for appending into the array.
* HashMap now maintains insertion order. Deletion performs a "swap
remove". It's now possible to modify the HashMap while iterating.
This adds these two fields to a HashMap Entry:
uint32_t hash
uint32_t distance_from_start_index
Compared to master branch, standard library tests compiled 8.4% faster
and took negligible (0.001%) more memory to complete. The amount of
memory used is still down from before 8b82c40104 which moved indexes
to be stored separately from entries.
So, it turns out, keeping robin hood hashing plus separating indexes
did result in a performance improvement. What happened previously is
that the gains from separating indexes balanced out the losses from
removing robin hood hashing, resulting in a wash.
This also serves as an inspiration for adding a benchmark to
std.AutoHashMap and improving the implementation.
The indexes are stored separately using an array of
uint8_t, uint16_t, uint32_t, or size_t, depending on the number of
entries in the map.
Entries only contain a key and a value, no longer have
distance_from_start_index or is_used.
In theory this should be both faster and use less memory.
In practice it seems to have little to no effect. For the standard
library tests, vs master branch, the time had no discernable
difference, and it shaved off only 13 MiB of peak rss usage.
This is direct result of review comments left by andrewrk and
daurnimator. It makes sense to map `ENOTCAPABLE` into a more generic
`error.AccessDenied`.
This commit adds `error.NotCapable` enum value and makes sure that
every applicable WASI syscall that can return `ENOTCAPABLE` errno
remaps it to `error.NotCapable.
In codegen.zig, the std.Target.Cpu.Arch is now generally available as a
comptime value where needed. This is a tradeoff that causes the compiler
binary to be more bloated, but gives us higher performance, since the
optimizer can optimize per architecture (which is usually how compilers
are designed anyway, with different code per-architecture), and it also
allows us to use per-architecture types, such as a Register enum that is
specific to the comptime-known architecture.
Adds abiSize method to Type.