cached

Creates a random access cache for lazyly computed elements.

@optmath
Slice!(CachedIterator!(Iterator, CacheIterator, FlagIterator), N, kind)
cached
(
Iterator
SliceKind kind
size_t N
CacheIterator
FlagIterator
)
(
Slice!(Iterator, N, kind) original
,
Slice!(CacheIterator, N, kind) caches
,
Slice!(FlagIterator, N, kind) flags
)

Parameters

original Slice!(Iterator, N, kind)

original ndslice

caches Slice!(CacheIterator, N, kind)

cached values

flags Slice!(FlagIterator, N, kind)

array composed of flags that indicates if values are already computed

Return Value

Type: Slice!(CachedIterator!(Iterator, CacheIterator, FlagIterator), N, kind)

ndslice, which is internally composed of three ndslices: original, allocated cache and allocated bit-ndslice.

Examples

import mir.ndslice.topology: cached, iota, map;
import mir.ndslice.allocation: bitSlice, uninitSlice;

int[] funCalls;

auto v = 5.iota!int
    .map!((i) {
        funCalls ~= i;
        return 2 ^^ i;
    });
auto flags = v.length.bitSlice;
auto cache = v.length.uninitSlice!int;
// cached lazy slice: 1 2 4 8 16
auto sl = v.cached(cache, flags);

assert(funCalls == []);
assert(sl[1] == 2); // remember result
assert(funCalls == [1]);
assert(sl[1] == 2); // reuse result
assert(funCalls == [1]);

assert(sl[0] == 1);
assert(funCalls == [1, 0]);
funCalls = [];

// set values directly
sl[1 .. 3] = 5;
assert(sl[1] == 5);
assert(sl[2] == 5);
// no function calls
assert(funCalls == []);

Cache of immutable elements

import mir.ndslice.slice: DeepElementType;
import mir.ndslice.topology: cached, iota, map, as;
import mir.ndslice.allocation: bitSlice, uninitSlice;

int[] funCalls;

auto v = 5.iota!int
    .map!((i) {
        funCalls ~= i;
        return 2 ^^ i;
    })
    .as!(immutable int);
auto flags = v.length.bitSlice;
auto cache = v.length.uninitSlice!(immutable int);

// cached lazy slice: 1 2 4 8 16
auto sl = v.cached(cache, flags);

static assert(is(DeepElementType!(typeof(sl)) == immutable int));

assert(funCalls == []);
assert(sl[1] == 2); // remember result
assert(funCalls == [1]);
assert(sl[1] == 2); // reuse result
assert(funCalls == [1]);

assert(sl[0] == 1);
assert(funCalls == [1, 0]);

See Also

Meta