91 lines
1.7 KiB
Ruby
91 lines
1.7 KiB
Ruby
|
|
class LogAn::Cache
|
|
READ = 1
|
|
WRITE = 2
|
|
attr_reader :source, :data
|
|
|
|
def initialize source, type = nil, data = nil
|
|
type ||= READ | WRITE
|
|
@source, @data, self.type = source, data || {}, type
|
|
end
|
|
|
|
def flush!
|
|
@data.each {|k,v| @source[k] = v }
|
|
@data = {}
|
|
end
|
|
|
|
def dget k
|
|
@data[k] ||= @source[k]
|
|
end
|
|
|
|
def oget k
|
|
@data[k] || @source[k]
|
|
end
|
|
|
|
def dset k, v
|
|
@data[k] ||= v
|
|
end
|
|
|
|
def oset k, v
|
|
@source[k] = v
|
|
end
|
|
|
|
def type= type
|
|
self.read_cache, self.write_cache = type & 1 > 0, type & 2 > 0
|
|
type
|
|
end
|
|
|
|
def read_cache= type
|
|
@type &= ~ (type ? 0 : 1)
|
|
define_singleton_method :[], method( type ? :oget : :dget)
|
|
end
|
|
|
|
def write_cache= type
|
|
@type &= ~ (type ? 0 : 2)
|
|
define_singleton_method :[]=, method( type ? :oset : :dset)
|
|
end
|
|
|
|
include Enumerable
|
|
def each *paras
|
|
return Enumerator.new self, :each unless block_given?
|
|
flush! if @type&2 == 2
|
|
@source.each_keys( *paras) do |key|
|
|
yield key, self[key]
|
|
end
|
|
self
|
|
end
|
|
end
|
|
|
|
class LogAn::AutoValueConvertHash
|
|
include Enumerable
|
|
attr_reader :decode, :encode, :source
|
|
|
|
def initialize source, encode = nil, each = nil, &decode
|
|
@source, @encoder = source, decode.nil? ? encode || Marshal.method( :dump) : nil,
|
|
@each = each || source.method( :each) rescue NameError
|
|
@decode = decode || Marshal.method( :restore)
|
|
end
|
|
|
|
def [] k
|
|
@decode.call @source[k]
|
|
end
|
|
|
|
def []= k, v
|
|
@source[k] = @encode.call v
|
|
end
|
|
|
|
def each *paras
|
|
return Enumerator.new self, :each unless block_given?
|
|
@each.call *paras do |k, v|
|
|
yield k, @decode.call( v)
|
|
end
|
|
end
|
|
|
|
def each_keys *paras
|
|
return Enumerator.new self, :each_keys unless block_given?
|
|
@each.call *paras do |k, v|
|
|
yield k
|
|
end
|
|
end
|
|
end
|