2 releases
0.1.1 | Feb 28, 2023 |
---|---|
0.1.0 | Jan 22, 2022 |
#541 in Memory management
7,702 downloads per month
Used in 8 crates
(via golem-wasm-ast)
22KB
336 lines
Provides mappable Rc
and Arc
types.
use mappable_rc::Mrc;
let m: Mrc<[u32]> = vec![1, 2, 3, 4].into();
assert_eq!(m.as_ref(), &[1, 2, 3, 4]);
let m: Mrc<[u32]> = Mrc::map(m, |slice| &slice[1..=2]);
assert_eq!(m.as_ref(), &[2, 3]);
lib.rs
:
Provides mappable Rc
and Arc
implementations.
This crate provides two types: Marc
and [Mrc
], corresponding to std
's [Arc
] and [Rc
]
types. For the most part, these types are near drop in replacements; they also provide shared
ownership via reference countings, many of the same methods, and almost all of the same trait
impls. The key difference is the existence of the map
method on both types. For example, you
can use Mrc::map
to subslice an Mrc<[u32]>
:
use mappable_rc::Mrc;
let m: Mrc<[u32]> = vec![1, 2, 3, 4].into();
assert_eq!(m.as_ref(), &[1, 2, 3, 4]);
let m: Mrc<[u32]> = Mrc::map(m, |slice| &slice[1..=2]);
assert_eq!(m.as_ref(), &[2, 3]);
The map
functions do not require preserving types. For example:
use mappable_rc::Mrc;
struct S(u32);
let m: Mrc<S> = Mrc::new(S(5));
let inner: Mrc<u32> = Mrc::map(m, |s| &s.0);
assert_eq!(inner.as_ref(), &5);
You can use the types provided by this crate even if other code hands you an Rc
or an Arc
.
See the Mrc::from_rc
and Marc::from_arc
methods, and the corresponding From
impls.
Performance
The performance characteristics of the types in this crate are very similar to the corresponding
std
types. The data pointer is stored directly in the struct, and so the referenced data is
only one indirection away. The Marc
implementation internally reuses the Arc
from std
, and
so the atomic operations are expected to be no more or less efficient.
A number of the trait implementations in this crate are more efficient than the corresponding
std
implementsions. Mrc<[T]>: From<Vec<T>>
is implemented like this:
use mappable_rc::Mrc;
let v = vec![1; 1000];
let m: Mrc<Vec<i32>> = Mrc::new(v);
let m: Mrc<[i32]> = Mrc::map(m, |v| &v[..]);
This means that the data in the Vec
is never copied and only a small allocation is performed.
The same implementation for Arc<[T]>
will perform a copy of the Vec
's data, to ensure that
the memory format complies with the more stringent requirements of Arc
.
The main performance downside of these types is that the size of Mrc
and Marc
is two
usize
s greater than the size of the corresponding std
type.
#![no_std]
This crate is #![no_std]
by default, but of course depends on alloc
. There is a non-default
std
feature that provides implementations of std::error::Error
, From<OsString>
and
From<PathBuf>
. Activating this feature introduces an std
dependency.
This crate has no other dependencies.