Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ratel-rust/toolshed

Arena allocator and a handful of useful data structures
https://github.com/ratel-rust/toolshed

Last synced: 23 days ago
JSON representation

Arena allocator and a handful of useful data structures

Awesome Lists containing this project

README

        

# Toolshed

This crate contains an `Arena` allocator, along with a few common data
structures that can be used in tandem with it.

For all those times when you need to create a recursively nested tree
of `enum`s and find yourself in pain having to put everything in
`Box`es all the time.

## Features

+ Paginated `Arena`: internally preallocates 64KiB _pages_ on the heap and
allows `Copy` types to be put on that heap.

+ `CopyCell`: virtually identical to `std::cell::Cell` but requires that
internal types implement `Copy`, and implements `Copy` itself.

+ `List`, `Map` and `Set`: your basic data structures that allocate on the
`Arena` and use internal mutability via `CopyCell`. Never worry about
sharing pointers again!

+ `BloomMap` and `BloomSet`: special variants of `Map` and `Set` with a
very simple but very fast bloom filter. If a map / set is often queried
for keys / elements it doesn't contain, the bloom filter check will
reduce the need to do a full tree lookup, greatly increasing performance.
The overhead compared to a regular `Map` or `Set` is also minimal.

+ All data structures implement expected traits, such as `Debug` or `PartialEq`.

+ Optional **serde** `Serialize` support behind a feature flag.

## Example

```rust
extern crate toolshed;

use toolshed::Arena;
use toolshed::map::Map;

// Only `Copy` types can be allocated on the `Arena`!
#[derive(Debug, PartialEq, Clone, Copy)]
enum Foo<'arena> {
Integer(u64),

// Recursive enum without `Box`es!
Nested(&'arena Foo<'arena>),
}

fn main() {
// Create a new arena
let arena = Arena::new();

// We allocate first instance of `Foo` in the arena.
//
// Please note that the `alloc` method returns a `&mut` reference.
// Since we want to share our references around, we are going to
// dereference and re-reference them to immutable ones with `&*`.
let child: &Foo = &*arena.alloc(Foo::Integer(42));

// Next instance of `Foo` will contain the child reference.
let parent: &Foo = &*arena.alloc(Foo::Nested(child));

// Empty map does not allocate
let map = Map::new();

// Inserting stuff in the map requires a reference to the `Arena`.
// The reference can be shared, since `Arena` uses interior mutability.
map.insert(&arena, "child", child);

// We can put our `map` on the arena as well. Once again we use the `&*`
// operation to change the reference to be immutable, just to demonstrate
// that our `Map` implementation is perfectly happy with internal mutability.
let map: &Map<&str, &Foo> = &*arena.alloc(map);

// Each insert allocates a small chunk of data on the arena. Since arena is
// preallocated on the heap, these inserts are very, very fast.
//
// We only have a non-mutable reference to `map` now, however `Map` is also
// using interior mutability on references to allow exactly this kind of
// behavior in a safe manner.
map.insert(&arena, "parent", parent);

assert_eq!(map.get("child"), Some(&Foo::Integer(42)));
assert_eq!(map.get("parent"), Some(&Foo::Nested(&Foo::Integer(42))));
assert_eq!(map.get("heh"), None);
}
```

## Benches

Here is a very biased benchmark of the different sets:

```
running 8 tests
test bloom_set_create ... bench: 49 ns/iter (+/- 0)
test bloom_set_read ... bench: 181 ns/iter (+/- 10)
test fxhash_set_create ... bench: 86 ns/iter (+/- 1)
test fxhash_set_read ... bench: 312 ns/iter (+/- 4)
test hash_set_create ... bench: 152 ns/iter (+/- 94)
test hash_set_read ... bench: 1,105 ns/iter (+/- 1)
test set_create ... bench: 37 ns/iter (+/- 0)
test set_read ... bench: 440 ns/iter (+/- 1)
```

* `set` and `bloom_set` are benchmarks of `Set` and `BloomSet` from this crate.
* `hash_set` is the default stdlib `HashSet`.
* `fxhash_set` is a `HashSet` using the `fxhash` crate hash.

## License

This crate is distributed under the terms of both the MIT license
and the Apache License (Version 2.0). Choose whichever one works best for you.

See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.