luro02 / array-map Goto Github PK
View Code? Open in Web Editor NEWAn array based `HashMap`
An array based `HashMap`
The implementation uses a number of unstable features, which have to be stabilized, before it can be published to crates.io.
[(); N].map(|_| None)
is used to initialize an array with None
: rust-lang/rust#75243ArrayMap::get_each_key_value_mut
requires [T; N]::each_mut
: rust-lang/rust#76118TryFromIterator
uses the "never-type" (!
) for an implementation, which can be replaced with core::convert::Infallible
: rust-lang/lang-team#60[T; N]::try_map
is not implemented in the standard library, so a custom implementation is used, which requires maybe_uninit_uninit_array
, maybe_uninit_array_assume_init
and try_trait_v2
: rust-lang/rust#79711stmt_expr_attributes
required for making ahash
optional in the array_map
macro: rust-lang/rust#15701This is to keep it working with future RawTable
that do return a different error type.
With the IndexTable
one could have an IndexMap
:
https://docs.rs/indexmap
The tests for DrainFilter
may fail randomly (just execute cargo test
multiple times to reproduce).
Depends on how likely it is that one runs out of capacity? I think it would be good to provide both a panicking and non-panicking method.
The problem is that try_insert
seems to be used differently in std
/hashbrown
, so a different name is needed.
Currently, each removal causes the entire ArrayMap
/ArrayTable
to be rebuilt.
This is very inefficient and with linear probing it is possible to remove the entries in O(1)
, which was done before c8a2e0e, but the implementation did not behave correctly, so it has been replaced with the current implementation, which is inefficient, but correct.
See tracking issue, which discusses this feature: rust-lang/rust#56167
Additionally, to miri one could run this in CI to check for undefined behaviour:
https://github.com/sslab-gatech/Rudra
ArrayMap::capacity
ArrayMap::clear
ArrayMap::contains_key
ArrayMap::drain
ArrayMap::drain_filter
ArrayMap::entry
ArrayMap::get
ArrayMap::get_key_value
ArrayMap::get_key_value_mut
ArrayMap::get_mut
ArrayMap::hasher
ArrayMap::insert
ArrayMap::is_empty
ArrayMap::iter
ArrayMap::iter_mut
ArrayMap::keys
ArrayMap::len
ArrayMap::new
ArrayMap::raw_entry
ArrayMap::raw_entry_mut
ArrayMap::remove
ArrayMap::remove_entry
ArrayMap::retain
ArrayMap::try_insert
ArrayMap::values
ArrayMap::values_mut
ArrayMap::with_hasher
ArrayMap::get_each_key_value_mut
ArrayMap::get_each_mut
Copy
Clone
Debug
Default
PartialEq
Eq
Extend<(&K, &V)>
TryExtend<(&K, &V)>
Extend<(K, V)>
TryExtend<(K, V)>
FromIterator<(K, V)>
TryFromIterator<(K, V)>
Index<&Q>
IntoIterator
for &ArrayMap
, &mut ArrayMap
and ArrayMap
serde::Serialize
serde::Deserialize
Send
Sync
Unpin
UnwindSafe
RefUnwindSafe
Should be fixed after this PR will be merged:
rust-lang/rust#87468
See: rust-lang/rust#84111
The TryFrom
implementation is already kind of implemented by TryFromIterator
and rust 2021 edition (with the new edition arrays implement IntoIterator
trait):
let table = ArrayMap::try_from_iterator([
(1, 2),
(3, 4),
(5, 6)
]).expect("failed to create the hash map");
Currently, aHash
is used, but there are other crates available:
ArraySet::new
ArraySet::capacity
ArraySet::iter
ArraySet::len
ArraySet::is_empty
ArraySet::drain
ArraySet::retain
ArraySet::drain_filter
ArraySet::clear
ArraySet::with_build_hasher
ArraySet::with_hasher
ArraySet::hasher
ArraySet::build_hasher
ArraySet::difference
ArraySet::symmetric_difference
ArraySet::intersection
ArraySet::union
ArraySet::contains
ArraySet::get
ArraySet::get_or_insert
ArraySet::get_or_insert_owned
ArraySet::get_or_insert_with
ArraySet::is_disjoint
ArraySet::is_subset
ArraySet::is_superset
ArraySet::insert
(ArraySet::try_insert
)ArraySet::replace
ArraySet::remove
ArraySet::take
Copy
Clone
Debug
Default
PartialEq
Eq
BitAnd
BitOr
BitXor
Deserialize
Serialize
TryExtend<&'a T>
TryExtend<T>
From<ArrayMap<T, (), R, B>>
TryFromIterator<T>
IntoIterator
Sub
ArrayMapFacade
could implement this:
impl<K, V, R, B, const N: usize> TryFrom<[(K, V); N]> for ArrayMapFacade<K, V, R, B>
where
K: Eq + Hash,
R: RawTable<(K, V)> + Default,
B: BuildHasher + Default,
{
type Error = CapacityError;
fn try_from(value: [(K, V); N]) -> Result<Self, Self::Error> {
let mut result = Self::with_build_hasher(B::default());
for (key, value) in value {
result.insert(key, value)?;
}
Ok(result)
}
}
but it conflicts with the "specialized" implementation for FixedSizeTable
s:
Lines 1064 to 1081 in 4390c72
The new edition will be stabilized with rust version 1.56 (October 21st, 2021).
https://blog.rust-lang.org/2021/07/21/Rust-2021-public-testing.html
The doc shows the @helper
cases too, which makes it harder to read. Those should be put in a helper macro?
This is because IndexMap
is an alias of ArrayMapFacade
. The indexmap
's IndexMap
has the same implementation, but this is something that should be documented.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.