weakhash entfernt. ref-gem
This commit is contained in:
parent
f6a10c9131
commit
bfe13fcce8
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ pkg
|
||||||
*.gem
|
*.gem
|
||||||
*.gemspec
|
*.gemspec
|
||||||
rdoc
|
rdoc
|
||||||
|
*.rbc
|
||||||
|
|
|
@ -60,7 +60,11 @@ module SBDB
|
||||||
|
|
||||||
def _txn txn
|
def _txn txn
|
||||||
txn ||= @txn
|
txn ||= @txn
|
||||||
txn && t.bdb_object
|
txn && txn.bdb_object
|
||||||
|
end
|
||||||
|
|
||||||
|
def transaction flg = nil, &exe
|
||||||
|
block_given? ? home.transaction( flg, &exe) : home.transaction( flg)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Arguments:
|
# Arguments:
|
||||||
|
|
|
@ -61,7 +61,7 @@ module SBDB
|
||||||
def initialize *args
|
def initialize *args
|
||||||
opts = ::Hash === args.last ? args.pop : {}
|
opts = ::Hash === args.last ? args.pop : {}
|
||||||
opts = {:dir => args[0], :flags => args[1], :mode => args[2]}.update opts
|
opts = {:dir => args[0], :flags => args[1], :mode => args[2]}.update opts
|
||||||
@dbs, @env = WeakHash.new, Bdb::Env.new( 0)
|
@dbs, @env = Ref::WeakValueMap.new, Bdb::Env.new( 0)
|
||||||
@env.log_config opts[:log_config], 1 if opts[:log_config]
|
@env.log_config opts[:log_config], 1 if opts[:log_config]
|
||||||
@env.lg_bsize = opts[:lg_bsize] if opts[:lg_bsize]
|
@env.lg_bsize = opts[:lg_bsize] if opts[:lg_bsize]
|
||||||
@env.lg_max = opts[:lg_max] if opts[:lg_max]
|
@env.lg_max = opts[:lg_max] if opts[:lg_max]
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
module SBDB
|
|
||||||
|
|
||||||
# See http://eigenclass.org/hiki/deferred-finalizers-in-Ruby
|
|
||||||
# Not threadsafe.
|
|
||||||
|
|
||||||
class WeakHash
|
|
||||||
attr_reader :cache
|
|
||||||
def initialize cache = ::Hash.new
|
|
||||||
@cache = cache
|
|
||||||
@key_map = {}
|
|
||||||
@rev_cache = ::Hash.new{|h,k| h[k] = {}}
|
|
||||||
@reclaim_value = lambda do |value_id|
|
|
||||||
if @rev_cache.has_key? value_id
|
|
||||||
@rev_cache[value_id].each_key{|key| @cache.delete key}
|
|
||||||
@rev_cache.delete value_id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@reclaim_key = lambda do |key_id|
|
|
||||||
@cache.delete @key_map.delete(key_id) if @key_map.has_key? key_id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def []= key, value
|
|
||||||
case key
|
|
||||||
when Fixnum, Symbol, true, false
|
|
||||||
key2 = key
|
|
||||||
else
|
|
||||||
key2 = key.dup
|
|
||||||
end
|
|
||||||
@rev_cache[value.object_id][key2] = true
|
|
||||||
@cache[key2] = value.object_id
|
|
||||||
@key_map[key.object_id] = key2
|
|
||||||
|
|
||||||
ObjectSpace.define_finalizer(value, @reclaim_value)
|
|
||||||
ObjectSpace.define_finalizer(key, @reclaim_key)
|
|
||||||
value
|
|
||||||
end
|
|
||||||
|
|
||||||
def [] key
|
|
||||||
value_id = @cache[key]
|
|
||||||
return ObjectSpace._id2ref( value_id) unless value_id.nil?
|
|
||||||
nil
|
|
||||||
rescue RangeError
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def each &e
|
|
||||||
@cache.each do |k, vid|
|
|
||||||
unless vid.nil?
|
|
||||||
obj = begin
|
|
||||||
ObjectSpace._id2ref vid
|
|
||||||
rescue RangeError
|
|
||||||
next
|
|
||||||
end
|
|
||||||
yield k, obj
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
Loading…
Reference in a new issue