Data-HashMap
view release on metacpan or search on metacpan
my $v = hm_ii_get $m, 42;
ok(!defined $v, 'TTL: get after expiry returns undef');
{
my $e = hm_ii_exists $m, 42;
ok(!$e, 'TTL: exists after expiry returns false');
}
}
# ---- Expired entry is tombstoned (size decreases) ----
{
my $m = Data::HashMap::II->new(0, 1);
hm_ii_put $m, 1, 10;
hm_ii_put $m, 2, 20;
is(hm_ii_size $m, 2, 'TTL: size = 2 before expiry');
sleep 2;
# Trigger lazy expiry
hm_ii_get $m, 1;
hm_ii_get $m, 2;
is(hm_ii_size $m, 0, 'TTL: size = 0 after expired gets');
}
# ---- Remove on expired entry returns false ----
{
my $m = Data::HashMap::II->new(0, 1);
hm_ii_put $m, 1, 10;
ok(hm_ii_remove $m, 1, 'TTL: remove before expiry returns true');
hm_ii_put $m, 2, 20;
sleep 2;
{
my $r = hm_ii_remove $m, 2;
ok(!$r, 'TTL: remove after expiry returns false');
}
is(hm_ii_size $m, 0, 'TTL: size = 0 after expired remove');
}
# ---- Non-expired entries returned normally ----
{
my $m = Data::HashMap::II->new(0, 60);
hm_ii_put $m, 1, 10;
hm_ii_put $m, 2, 20;
is(hm_ii_get $m, 1, 10, 'TTL 60s: non-expired get returns value');
is(hm_ii_get $m, 2, 20, 'TTL 60s: non-expired get returns value');
}
# ---- Put refreshes TTL on update ----
{
my $m = Data::HashMap::II->new(0, 3);
hm_ii_put $m, 1, 10;
sleep 1;
# Re-put refreshes TTL
hm_ii_put $m, 1, 20;
sleep 2;
# 3 seconds since original put, but only 2 since refresh (TTL=3)
is(hm_ii_get $m, 1, 20, 'TTL: put refresh keeps entry alive');
}
# ---- Iteration skips expired entries ----
{
my $m = Data::HashMap::II->new(0, 1);
hm_ii_put $m, 1, 10;
hm_ii_put $m, 2, 20;
my @k = sort { $a <=> $b } (hm_ii_keys $m);
is_deeply(\@k, [1, 2], 'TTL iteration: before expiry, all keys');
sleep 2;
@k = hm_ii_keys $m;
is(scalar(@k), 0, 'TTL iteration: after expiry, no keys');
my @v = hm_ii_values $m;
is(scalar(@v), 0, 'TTL iteration: after expiry, no values');
my @items = hm_ii_items $m;
is(scalar(@items), 0, 'TTL iteration: after expiry, no items');
}
# ---- Counter ops on expired key treat as new key ----
{
my $m = Data::HashMap::II->new(0, 1);
hm_ii_put $m, 1, 100;
sleep 2;
# incr on expired key should create new with value 1
is(hm_ii_incr $m, 1, 1, 'TTL counter: incr on expired key returns 1 (new key)');
}
# ---- SS variant TTL ----
{
my $m = Data::HashMap::SS->new(0, 1);
hm_ss_put $m, "hello", "world";
is(hm_ss_get $m, "hello", "world", 'SS TTL: before expiry');
sleep 2;
my $v = hm_ss_get $m, "hello";
ok(!defined $v, 'SS TTL: after expiry returns undef');
}
# ---- SI variant TTL with counters ----
{
my $m = Data::HashMap::SI->new(0, 1);
hm_si_put $m, "x", 42;
sleep 2;
my $v = hm_si_get $m, "x";
ok(!defined $v, 'SI TTL: expired get returns undef');
is(hm_si_incr $m, "x", 1, 'SI TTL: incr on expired key returns 1');
}
( run in 1.541 second using v1.01-cache-2.11-cpan-39bf76dae61 )