# Caching Utilities
Clache provides lightweight, easy-to-integrate, caching utilities indexed by arbitrary strings,
with both globally-shared and strongly-typed cache types.
**<u>Note</u>:**
The keys to the cache are commonly referred to as "paths", but they are arbitrary strings.
It could be a filesystem path, URI, UUID, or any other identifying string.
There are two types of caches in Clache, [`GlobalCache`] and [`LocalCache`].
You should use the [`GlobalCache`] when:
- Using dynamic types.
- Want to share data across the whole program.
- Or want to ensure cache keys are unique.
- But be careful: key conflicts can cause problems with downcasting and execution ordering, and
dynamic typing is slower.
You should use a [`LocalCache`] when:
- Using a single, static type.
- Want to control visibility, for a subsystem or value cache for a type.
- And want performance.
- But be careful: `LocalCache`s require much more boilerplate, and two `LocalCache`s may contain
the same key, but have different stored values.
[`GlobalCache`]: https://docs.rs/clache/0.2.0/clache/global_cache/struct.GlobalCache.html
[`LocalCache`]: https://docs.rs/clache/0.2.0/clache/local_cache/struct.LocalCache.html
## Multi-threading and async support
Both types of caches can be shared across threads and share their cached values via [`Arc`].
Cache hits are very fast, but cache misses are very costly, due to locking.
Both [`GlobalCache`] and [`LocalCache`] support async versions of their `get_or_else` methods that
are near the same performance as their blocking counterparts
## Minimal usage example
Only the first access has a large performance penalty; subsequent cache hits are significantly
faster, especially since they don't run loading logic.
```rust
use clache::GlobalCache;
// Slow cache miss and load. Returns Arc<String>
});
// Returns the same Arc<String>, much faster. You could also use `get_or_else`
let config: Arc<String> = GlobalCache::get("data://config.json");
```
[`LocalCache`] works the same, except each has its own storage of paths, so be careful.
```rust
use clache::LocalCache;
use std::sync::Arc;
let cache = LocalCache::new();
// Points to the same cache as 'cache'
let clone = cache.clone();
// Send 'clone' to another thread...
let value_clone = cache.get_or("value:", Arc::new(10));
// On main thread...
let value_cache = cache.get_or("value:", Arc::new(15));
assert!(Arc::ptr_eq(value_clone, value_cache));
// Both are the same allocation, but it could be either 10 or 15, depending on which `get_or` executed first
```