Trc
is a performant heap-allocated smart pointer for Rust that implements thread reference counting.
Trc
stands for: Thread Reference Counted.
Trc
provides a shared ownership of the data similar to Arc<T>
and Rc<T>
.
It implements thread reference counting, which is based on the observation that most objects are only used by one thread.
This means that two reference counts can be created: one for thread-local use, and one atomic one for sharing between threads.
Thread reference counting sets the atomic reference count to the number of threads using the data.
A cycle between Trc
pointers cannot be deallocated as the reference counts will never reach zero. The solution is a Weak<T>
.
A Weak<T>
is a non-owning reference to the data held by a Trc<T>
.
They break reference cycles by adding a layer of indirection and act as an observer. They cannot access the data directly, and
must be converted back into a Trc
. Weak
does not keep the value alive (which can be dropped), and only keeps the backing allocation alive.
To soundly implement thread safety Trc
is !Send
and !Sync
. To solve this, Trc
introduces a SharedTrc<T>
, which is Send
and Sync
.
SharedTrc
is the only way to safely send a Trc
's data across threads without using a Weak
.
See SharedTrc
for it's API, which is similar to that of Weak
.
Because Trc
is not part of the standard library, the CoerceUnsized
and Receiver
traits cannot currently be implemented by default. However, Trc
provides dyn_unstable
trait which enables the above traits for Trc
and SharedTrc
and must be used with nightly Rust (cargo +nightly ...
).
See examples here.
Click here for more benchmarks. Multiple different operating systems, CPUs, and architectures are tested.
To use Trc
, simply run cargo add trc
, or add trc = "1.2.3"
. Optionally, you can always use the latest version by adding trc = {git = "https://github.com/EricLBuehler/trc.git"}
.