Permalink
Browse files

Use ActiveSupport::WeakHash for MRI, JRuby prefers Weakling.

  • Loading branch information...
1 parent 301dd3d commit ada014929b01af5ce8ca5e6fdd13401bc3c392f5 @miloops miloops committed Oct 14, 2010
Showing with 49 additions and 1 deletion.
  1. +3 −1 activerecord/lib/active_record/identity_map.rb
  2. +46 −0 activesupport/lib/active_support/weak_hash.rb
View
4 activerecord/lib/active_record/identity_map.rb
@@ -1,3 +1,5 @@
+require "active_support/weak_hash"
+
module ActiveRecord
# = Active Record Identity Map
#
@@ -23,7 +25,7 @@ class << self
attr_accessor :enabled
def current
- repositories[current_repository_name] ||= Hash.new { |h,k| h[k] = Weakling::WeakHash.new }
+ repositories[current_repository_name] ||= Hash.new { |h,k| h[k] = ActiveSupport::WeakHash.new }
end
def with_repository(name = :default)
View
46 activesupport/lib/active_support/weak_hash.rb
@@ -0,0 +1,46 @@
+module ActiveSupport
+ class WeakHash
+ def initialize(cache = Hash.new)
+ @cache = cache
+ @key_map = {}
+ @rev_cache = Hash.new{|h,k| h[k] = {}}
+ @reclaim_value = lambda do |value_id|
+ if value = @rev_cache.delete(value_id)
+ value.each_key{|key| @cache.delete key}
+ end
+ end
+ end
+
+ def [](key)
+ value_id = @cache[key]
+ value_id && ObjectSpace._id2ref(value_id)
+ rescue RangeError
+ nil
+ end
+
+ def []=(key, value)
+ key2 = case key
+ when Fixnum, Symbol, true, false, nil
+ key
+ else
+ 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)
+ end
+
+ def clear
+ @cache.clear
+ end
+
+ def delete(key)
+ @cache.delete(key)
+ end
+ end
+end
+
+ActiveSupport::WeakHash = ::Weakling::WeakHash if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'

0 comments on commit ada0149

Please sign in to comment.