A small byte sized table map. (Currently *requires* nightly).
A small table map using single byte key indecies. Designed for maps with tiny keys.
Pages are stored as 256 entry key-value arrays which are indexed by the byte key index. The key is compared for collision check and on collision the next page is checked or inserted if needed.
`smallmap` does not ever need to allocate more than 1 page for types which all invariants can be represented as unique bytes.
## Use cases
Designed for instances where you want a small map with relatively trivial keys (e.g. primitive type).
Designed for instances where you want a small map with relatively trivial keys (e.g. primitive type).
Performance greately outpaces hash-based maps in these cases.
Performance can greately outpace hash-based by an order of magnitude or more in these cases.
### Maybe use if
* You have small keys
* Your map is not at risk of Denial of Service attacks.
* Your keys will have a lot of collisions
### Don't use if
* You have complex keys
* Denial of service is a concern
* Your map will contain a large volume of entries
* Your keys may have a large number of collisions when represented as `u8`.
# Benchmarks
# Benchmarks
Some rudamentary benchmarks
Some crude and basic benchmarks
## char
## char
@ -16,18 +31,19 @@ Some rudamentary benchmarks
| `HashMap` | 16 |
| `HashMap` | 16 |
| `smallmap::Map` | 7 |
| `smallmap::Map` | 7 |
## Iterating a string's chars and incrementing values
/// Insert into the entry if it is empty the value returned by the closure and return a mutable reference to the new value, otherwise return a mutable reference to the already present value.
/// Insert into the entry this value if it is empty and return a mutable reference to the new value, otherwise return a mutable reference to the already present value.
#[inline]pubfnor_insert(self,value: V)-> &'amutV
#[inline]pubfnor_insert(self,value: V)-> &'amutV
{
{
self.or_insert_with(||value)
self.or_insert_with(||value)
@ -105,6 +126,7 @@ impl<'a, K, V> Entry<'a, K, V>
whereK: Collapse,
whereK: Collapse,
V: Default
V: Default
{
{
/// Insert into the entry the default value if it is empty and return a mutable reference to the new value, otherwise return a mutable reference to the already present value.
//! Designed for instances where you want a small map with small key types.
//! Performance greately outpaces complex hash-based maps in these cases.
//!
//! ### When not to use
//! Generally don't use this if your key would have a lot of collisions being represents in 8 bits, otherwise it might be a faster alternative to hash-based maps. You should check yourself before sticking with this crate instead of `std`'s vectorised map implementations.
#![allow(dead_code)]
#![cfg_attr(nightly, feature(test))]
#![cfg_attr(nightly, feature(drain_filter))]
#![cfg_attr(nightly, feature(const_fn))]
#[cfg(nightly)]externcratetest;
#[cfg(nightly)]externcratetest;
constMAX: usize=256;
constMAX: usize=256;
//TODO: Move test
usestd::borrow::Borrow;
//TODO: Document
//TODO: Readme
pubmoditer;
//TODO: LICENSE
useiter::*;
//TODO: Publish and upload to githubxc
pubmodentry;
pubuseentry::Entry;
usestd::{
modinit;
borrow::Borrow,
};
/// Trait for types that can be used as `Map` keys.
///
/// Implementors should try to minimise collisions by making `collapse` return a relatively unique value if possible.
/// But it is not required.
/// Primitive `Eq` types already implement this, as well as `str` and `[u8]`.
/// A simple folding implementation is provided for byte slices here [`collapse_iter()`](collapse_iter).
///
/// Integer types implement this through the modulo of itself over 256, whereas byte slice types implement it through an XOR fold over itself. It doesn't matter though, the programmer is free to implement it how she chooses.
pubtraitCollapse: Eq
pubtraitCollapse: Eq
{
{
/// Create the index key for this instance. This is similar in use to `Hash::hash()`.
fncollapse(&self)-> u8;
fncollapse(&self)-> u8;
}
}
/// A single page in a `Map`. Contains up to 256 key-value entries.