#!/usr/bin/perl
use strict;
use warnings;
use Test::More;
use_ok 'Cache::Ref::CLOCK';
use_ok 'Cache::Ref::GCLOCK';
foreach my $impl (qw(Cache::Ref::CLOCK Cache::Ref::GCLOCK)) {
{
my $c = $impl->new( size => 3 );
isa_ok( $c, "Cache::Ref" );
$c->set( foo => "blah" );
is( $c->get("foo"), "blah", "foo" );
$c->set( bar => "lala" );
is( $c->get("bar"), "lala", "bar" );
$c->set( baz => "blob" );
is( $c->get("baz"), "blob", "baz" );
$c->set( zot => "quxx" );
is( $c->get("zot"), "quxx", "zot" );
is( $c->get("bar"), "lala", "bar still in cache" );
is( $c->get("foo"), undef, "foo no longer in cache" );
$c->set( quxx => "tmp" );
$c->set( quxx => "dancing" );
is( $c->get("bar"), "lala", "bar still in cache" );
is( $c->get("baz"), undef, "baz no longer in cache" );
is( $c->get("zot"), "quxx", "zot still in cache" );
is( $c->get("quxx"), "dancing", "quxx in cache" );
$c->remove("quxx");
is( $c->get("bar"), "lala", "bar still in cache" );
is( $c->get("baz"), undef, "baz no longer in cache" );
is( $c->get("zot"), "quxx", "zot still in cache" );
is( $c->get("quxx"), undef, "quxx removed from cache" );
is( $c->_index_size, 2, "two elements in cache" );
$c->set( quxx => "blah" );
is( $c->get("bar"), "lala", "bar still in cache" );
is( $c->get("baz"), undef, "baz no longer in cache" );
is( $c->get("zot"), "quxx", "zot still in cache" );
is( $c->get("quxx"), "blah", "quxx in cache" );
if ( $c->isa("Cache::Ref::CLOCK") ) {
$c->set( new => "element" ); # overwrites 'zot' due to current value of _hand
$c->hit("bar");
$c->set( another => "member" );
} else {
$c->hit("bar") for 1 .. 3;
$c->set("new" => "element"); # expires 'quxx'
$c->hit("new"); # otherwise it's less frequently used than 'zot'
$c->set("another" => "member");
}
is( $c->get("bar"), "lala", "bar still in cache" );
is( $c->get("baz"), undef, "baz no longer in cache" );
is( $c->get("zot"), undef,, "zot no longer in cache" );
is( $c->get("quxx"), undef, "quxx no longer in cache" );
is( $c->get("new"), "element", "new still in cache" );
is( $c->get("another"), "member", "another still in cache" );
is_deeply( [ $c->get(qw(bar new nothere)) ], [ qw(lala element), undef ], "mget" );
is( $c->_index_size, 3, "cache size" );
$c->expire(2);
is( $c->_index_size, 1, "expired" );
$c->clear;
is( $c->_index_size, 0, "no elements in cache" );
}
{
my $c = $impl->new( size => 5 );
my ( $hit, $miss ) = ( 0, 0 );
for ( 1 .. 2000 ) {
my $key = 1 + int rand 8;
if ( $c->get($key) ) {
$hit++;
} else {
$miss++;
$c->set($key => $key);
}
}
cmp_ok( $hit, '>=', $miss, "more cache hits than misses during random access of small sigma ($hit >= $miss)" );
( $hit, $miss ) = ( 0, 0 );
for ( 1 .. 100 ) {
foreach my $key ( 1 .. 10 ) {
if ( $c->get($key) ) {
$hit++;
} else {
$miss++;
$c->set($key => $key);
}
}
}
cmp_ok( $hit, '<=', $c->size * 3, "no significant hits during linear scans ($hit)" );
}
}
done_testing;
# ex: set sw=4 et: