File: cache.rb

package info (click to toggle)
zonecheck 2.0.4-3
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,416 kB
  • ctags: 1,177
  • sloc: ruby: 9,582; xml: 731; sh: 404; makefile: 71
file content (154 lines) | stat: -rw-r--r-- 3,303 bytes parent folder | download | duplicates (3)
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# $Id: cache.rb,v 1.10 2003/07/25 22:51:25 sdalu Exp $

# 
# CONTACT     : zonecheck@nic.fr
# AUTHOR      : Stephane D'Alu <sdalu@nic.fr>
#
# CREATED     : 2002/08/02 13:58:17
# REVISION    : $Revision: 1.10 $ 
# DATE        : $Date: 2003/07/25 22:51:25 $
#
# CONTRIBUTORS: (see also CREDITS file)
#
#
# LICENSE     : GPL v2 (or MIT/X11-like after agreement)
# COPYRIGHT   : AFNIC (c) 2003
#
# This file is part of ZoneCheck.
#
# ZoneCheck is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# ZoneCheck is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with ZoneCheck; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#

require 'sync'
require 'dbg'


##
##
##
class Cache
    Nothing = Object::new	# Another way to express nil

    #
    # Initialize the cache mechanisme
    #
    def initialize(name='0x%x'%__id__)
	@name  = name
	@mutex = Sync::new
	@list  = {}
    end


    #
    # Is caching enabled?
    #
    def enabled?
	! $dbg.enabled?(DBG::NOCACHE)
    end


    #
    # Clear the items (all if none specified)
    #
    def clear(*items)
	@mutex.synchronize {
	    # Clear item content
	    list = items.empty? ? @list.keys : items
	    list.each { |item| 
		# Sanity check
		if ! @list.has_key?(item)
		    raise ArgumentError, "Cache item '#{item}' not defined"
		end
		
		# Clear 
		@list[item] = {} 
	    }
	}
    end


    #
    # Define cacheable item
    #
    def create(*items)
	items.each { |item| 
	    # Sanity check
	    if @list.has_key?(item)
		raise ArgumentError, "Cache item '#{item}' already defined"
	    end
	    # Create item
	    @list[item] = {}
	}
    end


    #
    # Use a cacheable item
    #
    def use(item, args=nil, force=false)
	# Sanity check
	if ! @list.has_key?(item)
	    raise ArgumentError, "Cache item '#{item}' not defined"
	end

	# Caching enabled?
	return yield unless enabled?
	
	# Compute key to use for retrieval
	key = case args
	      when NilClass then nil
	      when Array    then case args.length
				 when 0 then nil
				 when 1 then args[0]
				 else        args
				 end
	      else               args
	      end

	# Retrieve information
	computed, r = nil, nil
	@mutex.synchronize {
	    r		= @list[item][key]
	    computed	= force || r.nil?
	    if computed
		r = yield
		r = Nothing if r.nil?
		@list[item][key] = r
	    end
	    r = nil if r == Nothing
	}

	# Debugging information
	$dbg.msg(DBG::CACHE_INFO) {
	    l = case args
		when NilClass then "#{item}"
		when Array    then case args.length
				   when 0 then "#{item}"
				   when 1 then "#{item}[#{args[0]}]"
				   else        "#{item}[#{args.join(',')}]"
				   end
		else               "#{item}[#{args}]"
		end
		    
	    if computed
	    then "computed(#{@name}): #{l}=#{r}"
	    else "cached  (#{@name}): #{l}=#{r}"
	    end
	}

	# Returns result
	r
    end
end