App-Greple-xlate

 view release on metacpan or  search on metacpan

lib/App/Greple/xlate/Cache.pm  view on Meta::CPAN

my %default = (
    name => '',		# cache filename
    saved => undef,	# saved hash
    saved_order => [],  # keys of saved data in file order
    current => undef,	# current using hash
    clear => 0,		# clean up cache data
    accessed => {},	# accessed keys
    order => [],	# accessed keys in order
    accumulate => 0,	# do not delete unused entry
    force_update => 0,	# update cache file anyway
    updated => 0,	# number of updated entries
    format => 'list',	# saving cache file format
    old_pos => undef,   # memoized key-to-position map of saved_order
    # NOTE: reference-valued defaults must get fresh copies in new()
    seed => undef,      # seed cache file for a fresh cache
    seeded => 0,        # true when the seed was actually loaded
    readonly => 0,   # suppress all cache file writes
);

for my $key (keys %default) {
    no strict 'refs';

lib/App/Greple/xlate/Cache.pm  view on Meta::CPAN

sub set {
    my $obj = shift;
    pairmap {
        if (ref $a eq 'ARRAY' and ref $b eq 'ARRAY') {
            @$a == @$b or die;
            $obj->set(mesh $a, $b);
        } else {
            my $c = $obj->current->{$a} //= delete $obj->saved->{$a};
            if (not defined $c or $c ne $b) {
                $obj->current->{$a} = $b;
                $obj->updated++;
            }
        }
    } @_;
    $obj;
}

sub json {
    JSON->new->utf8->canonical->pretty;
}

lib/App/Greple/xlate/Cache.pm  view on Meta::CPAN

        my $v = $obj->saved->{$k} // $obj->current->{$k};
        push @out, [ $k, $v ] if defined $v;
    }
    @out;
}

sub update {
    my $obj = shift;
    return if $obj->readonly;
    my $file = $obj->name || return;
    if (not $obj->force_update and $obj->updated == 0) {
        # accumulate: nothing changed, disk content is already right.
        # otherwise: return only when there is nothing to purge.
        return if not $obj->seeded and ($obj->accumulate or %{$obj->saved} == 0);
    }
    if ($obj->accumulate) {
        # POD promises unused entries survive: adopt them unconditionally
        for my $k (@{$obj->saved_order}, sort keys %{$obj->saved}) {
            next if $obj->accessed->{$k};
            defined(my $v = delete $obj->saved->{$k}) or next;
            $obj->current->{$k} //= $v;

t/11_llm_context.t  view on Meta::CPAN

    my $ctx_json = context_json($calls[0]);
    like($ctx_json, qr/alpha paragraph original text/, 'neighbor source');
    like($ctx_json, qr/ALPHA PARAGRAPH ORIGINAL TEXT/, 'neighbor translation');
    like($ctx_json, qr/beta paragraph revised text/, 'old source pair');
    like($ctx_json, qr/BETA PARAGRAPH REVISED TEXT/, 'old translation pair');
    is($ctx->{revision}{previous_source}, "beta paragraph revised text\n",
       'one-to-one revision identifies the previous source');
    is($ctx->{revision}{current_source}, "beta paragraph rerevised text\n",
       'one-to-one revision identifies the current source');

    like($r->stdout, qr/BETA PARAGRAPH REREVISED TEXT/, 'output updated');
    like($r->stdout, qr/\[xlate\.pm\] Review:/, 'review report is shown');
    like($r->stdout, qr/source \@\d+: "" -> "re"/,
         'review isolates the changed source span');
    like($r->stdout, qr/target \@\d+: "" -> "RE"/,
         'review isolates the changed translation span');
};

subtest 'truncation drops far flanks first' => sub {
    require App::Greple::xlate::llm;
    my $big = "x" x 5000;



( run in 1.918 second using v1.01-cache-2.11-cpan-aadc1410aed )