Skip to content

Commit

Permalink
Include has poor performance on large arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed May 12, 2012
1 parent db472a6 commit 612c346
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
18 changes: 16 additions & 2 deletions lib/mongoid/identity_map.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,6 +4,21 @@ module Mongoid #:nodoc:
# Defines behaviour for the identity map in Mongoid. # Defines behaviour for the identity map in Mongoid.
class IdentityMap < Hash class IdentityMap < Hash


# Clear the many documents.
#
# @example Clear the docs.
# identity_map.clear_many(Post, selector)
#
# @param [ Class ] klass The klass to clear.
# @param [ Hash ] selector The selector to identify it.
#
# @return [ Array<Document> ] The documents.
#
# @since 2.4.10
def clear_many(klass, selector)
(documents_for(klass)[selector] ||= []).clear
end

# Get a document from the identity map by its id. # Get a document from the identity map by its id.
# #
# @example Get the document from the map. # @example Get the document from the map.
Expand Down Expand Up @@ -62,8 +77,7 @@ def set(document)
# #
# @since 2.2.0 # @since 2.2.0
def set_many(document, selector) def set_many(document, selector)
documents = documents_for(document.class)[selector] ||= [] (documents_for(document.class)[selector] ||= []).push(document)
documents.push(document) unless documents.include?(document)
end end


# Set a document in the identity map for the provided selector. # Set a document in the identity map for the provided selector.
Expand Down
8 changes: 7 additions & 1 deletion lib/mongoid/relations/referenced/many.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -563,9 +563,15 @@ def criteria(metadata, object, type = nil)
# #
# @since 2.2.0 # @since 2.2.0
def eager_load(metadata, ids) def eager_load(metadata, ids)
cleared = false
klass, foreign_key = metadata.klass, metadata.foreign_key klass, foreign_key = metadata.klass, metadata.foreign_key
klass.any_in(foreign_key => ids).each do |doc| klass.any_in(foreign_key => ids).each do |doc|
IdentityMap.set_many(doc, foreign_key => doc.send(foreign_key)) base_id = doc.send(foreign_key)
unless cleared
IdentityMap.clear_many(klass, foreign_key => base_id)
cleared = true
end
IdentityMap.set_many(doc, foreign_key => base_id)
end end
end end


Expand Down

0 comments on commit 612c346

Please sign in to comment.