File: CacheManager.pm

package info (click to toggle)
tiarra 20100212-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,732 kB
  • ctags: 1,712
  • sloc: perl: 32,032; lisp: 193; sh: 109; makefile: 10
file content (89 lines) | stat: -rw-r--r-- 2,230 bytes parent folder | download | duplicates (4)
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
89
# -----------------------------------------------------------------------------
# $Id: CacheManager.pm 11365 2008-05-10 14:58:28Z topia $
# -----------------------------------------------------------------------------
# このクラスは共通のインスタンスを持ちます。
# キャッシュサイズや有効期限などの設定はAuto::Cacheが行ないます。
#
# 実際のチャンネルの管理は面倒なので、キャッシュ本体は
# ChannelInfoのremarks/cache-of-auto-modulesに保存します。
#
# cache-of-auto-modules: ARRAY
# 要素: [発言内容,発言時刻]
# -----------------------------------------------------------------------------
package Auto::CacheManager;
use strict;
use warnings;
use Tiarra::SharedMixin;
our $_shared_instance;

sub _new {
    my ($class) = @_;
    my $this = {
	size => 0, # デフォルトのキャッシュサイズ。
	expire => 600, # デフォルトの有効期限。単位は秒。
    };
    bless $this,$class;
}

sub cached_p {
    # ch: ChannelInfo
    # str: SCALAR
    # キャッシュされていたら1を返します。
    my ($this,$ch,$str) = @_;
    my $cache = $this->get_cache($ch);
    $this->expire($cache);
    
    foreach (@$cache) {
	if ($_->[0] eq $str) {
	    return 1;
	}
    }
    undef;
}

sub cache {
    my ($this,$ch,$str) = @_;
    my $cache = $this->get_cache($ch);
    $this->expire($cache);
    
    # キャッシュに追加
    push @$cache,[$str,time];
    # キャッシュサイズから溢れた分は削除
    if (@$cache > $this->{size}) {
	splice @$cache,(@$cache - $this->{size});
    }
}

sub get_cache {
    my ($this,$ch) = @_;
    my $cache = $ch->remarks('cache-of-auto-modules');
    if (!defined $cache) {
	$cache = [];
	$ch->remarks('cache-of-auto-modules',$cache);
    }
    $cache;
}

sub expire {
    my ($this,$cache) = @_;
    # まずはexpireされる項目が一つでもあるかどうかを調べる。
    my $limit = time - $this->{expire};
    
    my $expired_some = sub {
	foreach (@$cache) {
	    if ($_->[1] < $limit) {
		return 1;
	    }
	}
	undef;
    }->();

    if ($expired_some) {
	# キャッシュを再構成
	@$cache = grep {
	    $_->[1] >= $limit;
	} @$cache;
    }
}

1;