lib/identity_map/cache.rb in ar-simple-idmap-0.2.2 vs lib/identity_map/cache.rb in ar-simple-idmap-0.2.4

- old
+ new

@@ -1,89 +1,116 @@ -module ActiveRecord - class Base - module ThreadIdentityMap - class ClassIdMap - def initialize(klass) - @objects = {} - @object = klass.allocate - @object.instance_variable_set(:@attributes, {:id=>nil}) - @object.instance_variable_set(:@attributes_cache, {}) - end - - def [](id) - @object.id = id - @objects[@object.id] - end - - def []=(id, v) - @object.id = id - @objects[@object.id] = v - end - - def delete(id) - @object.id = id - @objects.delete(@object.id) - end - end - - class IdMap - - def initialize - @objects = {} - end - - def for_class(klass) - @objects[ klass.base_class ] ||= ClassIdMap.new(klass) - end - - end - - module ClassMethods - def create_identity_map - set_thread_id_map IdMap.new - end - - def drop_identity_map - set_thread_id_map nil - end - - def with_id_map( fresh = true) - old = thread_id_map - create_identity_map if fresh || old.nil? - yield - ensure - set_thread_id_map old - end - - def without_id_map - old = thread_id_map - drop_identity_map - yield - ensure - set_thread_id_map old - end - -# def uncached_with_identity_map( &block ) -# without_id_map do -# uncached_without_identity_map &block -# end -# end - - protected - - def thread_id_map - Thread.current[:ar_identity_map] - end - - def thread_id_map=(v) - Thread.current[:ar_identity_map] = v - end - - alias set_thread_id_map thread_id_map= - - end +module ActiveRecord # :nodoc: + class Base # :nodoc: + module ThreadIdentityMap # :nodoc: + # ClassIdMap do the job of properly use typecasted +id+ value of model object + # for search in a cache + class ClassIdMap + def initialize(klass) + @objects = {} + @object = klass.allocate + @object.instance_variable_set(:@attributes, {:id=>nil}) + @object.instance_variable_set(:@attributes_cache, {}) + end + + def [](id) + @object.id = id + @objects[@object.id] + end + + def []=(id, v) + @object.id = id + @objects[@object.id] = v + end + + def delete(id) + @object.id = id + @objects.delete(@object.id) + end + end + + # Manages separated object caches for each model + class IdMap + + def initialize + @objects = {} + end + + def for_class(klass) + @objects[ klass.base_class ] ||= ClassIdMap.new(klass) + end + + end + + module ClassMethods + # Creates new identity map and put it in thread local storage + # + # For most use cases +with_id_map+ should be used instead. + # + # Usage: + # ActiveRecord::Base.create_identity_map + def create_identity_map + set_thread_id_map IdMap.new + end + + # Remove identity map from thread local storage + # + # For most use cases +without_id_map+ should be used instead. + # + # Usage: + # ActiveRecord::Base.drop_identity_map + def drop_identity_map + set_thread_id_map nil + end + + # Execute block with identity map. + # + # If it called with +true+, then new instance of identity map would be used + # regardless of any present. + # + # If it called with +false+, then it only ensures that identity map created if absent. + # + # Default is +true+ + # + # Usage: + # ActiveRecord::Base.with_id_map do + # #do_some_actions + # end + def with_id_map( fresh = true) + old = thread_id_map + create_identity_map if fresh || old.nil? + yield + ensure + set_thread_id_map old + end + + # Execute block with identity map turned off. + # + # Usage: + # ActiveRecord::Base.without_id_map do + # #do_some_actions + # end + def without_id_map + old = thread_id_map + drop_identity_map + yield + ensure + set_thread_id_map old + end + + protected + + def thread_id_map + Thread.current[:ar_identity_map] + end + + def thread_id_map=(v) + Thread.current[:ar_identity_map] = v + end + + alias set_thread_id_map thread_id_map= + + end end - - extend ThreadIdentityMap::ClassMethods -# self.class.send :alias_method_chain, :uncached, :identity_map + + extend ThreadIdentityMap::ClassMethods end end