RaCoCo result: Red::Driver::Cache::Memory

# Red::Driver::Cache::Memory 18.1%

    use Red::AST;
    use Red::Driver::CacheWithStrKey;
    use Red::Driver::CacheInvalidateOnWrite;

    unit class Red::Driver::Cache::Memory does Red::Driver::CacheWithStrKey does Red::Driver::CacheInvalidateOnWrite;

    has %!cache;
    has %!cache-to-table;
    has %!expires;
    has @!times;
    has Int $.ttl = 10;

    submethod TWEAK(|) {
        start react whenever Supply.interval: 1 {
            CATCH {
                default {
                    .say
                }
            }
            my $time = self!time;
            while (@!times.head // Inf) <= $time { #>
                my $t = @!times.shift;
                for |(%!expires{$t}:delete) -> $key {
                    next without $key;
                    note "remove: $key" if $*RED-CACHE-DEBUG;
                    %!cache{$key}:delete
                }
            }
        }
    }

    method !time { now.Int }

    multi method get-from-cache(Str $key, :$ast)  {
        note "get-from-cache: $key" if $*RED-CACHE-DEBUG;
        %!cache{$key}
    }

    multi method set-on-cache(Str:D $key, @data, :$ast) {
        note "set-on-cache: $key" if $*RED-CACHE-DEBUG;
        %!cache{$key} = @data;
        for $ast.tables -> $table {
            note "save on $table.^table(): $key" if $*RED-CACHE-DEBUG;
            %!cache-to-table.push: $table.^table, $key
        }

        my $time = self!time + $!ttl;
        %!expires.push: $time => $key;
        @!times.push: $time;
    }

    multi method invalidate(Str :$table, *% where ! .elems) {
        with %!cache-to-table{ $table }:delete {
            for .<> // [] -> $key {
                note "invalidate $table: $key" if $*RED-CACHE-DEBUG;
                %!cache{ $key }:delete
            }
        }
    }
    #multi method invalidate(Str :$table, *%columns) { say "invalidate $table, { %columns.kv.map: { $^a => $^b.value } }" }