1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
//! Cache used by [CachingBlockIter] for [reduce] operations.
//!
//! # Memory footprint
//!
//! Cache for one [BitSet] costs 2 pointers.
//!
//! [BitSet]: crate::BitSet
//! [CachingBlockIter]: crate::iter::CachingBlockIter
//! [reduce]: crate::reduce()

use crate::binary_op::BinaryOp;
use crate::bitset_interface::{BitSetBase, LevelMasksExt};
use crate::reduce::{DynamicCacheImpl, FixedCacheImpl, NonCachedImpl, ReduceCacheImpl};

/// Cache is not used.
///
/// This also discards cache usage for all underlying [reduce] operations.
/// Cache still can be applied on top of NoCache operation.
///
/// # Example
///
/// TODO
/// 
/// [reduce]: crate::reduce()
#[derive(Default, Copy, Clone)]
pub struct NoCache;

/// Cache with fixed capacity.
///
/// This cache is noop to construct.
/// Should be your default choice.
///
/// N.B. Pay attention to stack-mem usage when working with
/// reduce on reduce on reduce ...
#[derive(Default, Copy, Clone)]
pub struct FixedCache<const N:usize>;

/// Dynamically built in-heap cache.
///
/// You want this, when your cache doesn't fit stack.
/// This can happened, when you work with enormously large number of sets,
/// and/or work with deep [reduce] operations. Alternatively, you
/// can use [NoCache].
/// 
/// [reduce]: crate::reduce()
#[derive(Default, Copy, Clone)]
pub struct DynamicCache;

pub trait ReduceCache: Default + 'static{
    /// usize::MAX - if unlimited.
    const MAX_LEN: usize;
    type Impl<Op, S>
        : ReduceCacheImpl<
            Sets = S,
            Config = <S::Item as BitSetBase>::Config
        >
    where
        Op: BinaryOp,
        S: Iterator + Clone,
        S::Item: LevelMasksExt;
}

impl ReduceCache for NoCache{
    const MAX_LEN: usize = usize::MAX;
    type Impl<Op, S> = NonCachedImpl<Op, S>
    where
        Op: BinaryOp,
        S: Iterator + Clone,
        S::Item: LevelMasksExt;
}

impl<const N: usize> ReduceCache for FixedCache<N>{
    const MAX_LEN: usize = N;
    type Impl<Op, S> = FixedCacheImpl<Op, S, N>
    where
        Op: BinaryOp,
        S: Iterator + Clone,
        S::Item: LevelMasksExt;
}

impl ReduceCache for DynamicCache{
    const MAX_LEN: usize = usize::MAX;
    type Impl<Op, S> = DynamicCacheImpl<Op, S>
    where
        Op: BinaryOp,
        S: Iterator + Clone,
        S::Item: LevelMasksExt;
}