in storehaus-core/src/main/scala/com/twitter/storehaus/ReadableStore.scala [116:169]
def andThen[K, V, V2, V3 >: V](l: ReadableStore[K, V], r: ReadableStore[V3, V2])
(implicit fc: FutureCollector): ReadableStore[K, V2] =
new ComposedStore[K, V, V2, V3](l, r)
/** unpivot or uncurry a ReadableStore which has a value that is a Map.
* Often it is more efficient to pack values into inner maps, especially when you have very sparse
* stores. This allows you to work with such a packed store as though it was unpacked
*/
def unpivot[K, OuterK, InnerK, V](store: ReadableStore[OuterK, Map[InnerK, V]])
(split: K => (OuterK, InnerK)): ReadableStore[K, V] =
new UnpivotedReadableStore(store)(split)
/** Lazily change the key and value for a store.
* This does not change the representation, only alters before going in or out of the store.
*/
def convert[K1, K2, V1, V2](
store: ReadableStore[K1, V1])(kfn: K2 => K1)(vfn: V1 => Future[V2]): ReadableStore[K2, V2] =
new ConvertedReadableStore(store)(kfn)(vfn)
/** Returns a new ReadableStore that caches reads from the underlying
* store using the supplied mutable cache. */
def withCache[K, V](
store: ReadableStore[K, V], cache: MutableCache[K, Future[Option[V]]]): ReadableStore[K, V] =
new CachedReadableStore(store, cache)
/** Returns a new ReadableStore that caches reads from the underlying
* store using the supplied immutable cache. */
def withCache[K, V](
store: ReadableStore[K, V], cache: Cache[K, Future[Option[V]]]): ReadableStore[K, V] =
new CachedReadableStore(store, cache.toMutable())
/**
* Returns a ReadableStore[K, V] that attempts reads from a store
* multiple times until a predicate is met. The iterable of backoffs
* defines the time interval between two read attempts. If there is
* not read result satisfying the given predicate after all read
* attempts, a NotFoundException will be thrown.
*/
def withRetry[K, V](
store: ReadableStore[K, V], backoffs: Iterable[Duration]
)(pred: Option[V] => Boolean)(implicit timer: Timer): ReadableStore[K, V] =
new RetryingReadableStore(store, backoffs)(pred)
}
/** Main trait to represent asynchronous readable stores
* Here you see the tri-state logic:
* <ul>
* <li>Future(Some(v)) - The store has the item</li>
* <li>Future(None) -
* The store definitely DOES NOT have the item (not the same as no answer).</li>
* <li>Future.exception - Some kind of unexpected failure (including non-answer).</li>
* </ul>
*/
trait ReadableStore[-K, +V] extends Closable { self =>