Skip to content
Browse files

Include has poor performance on large arrays

  • Loading branch information...
1 parent db472a6 commit 612c346b2a6ed209db75f3a549e91a887751a809 @durran durran committed
Showing with 23 additions and 3 deletions.
  1. +16 −2 lib/mongoid/identity_map.rb
  2. +7 −1 lib/mongoid/relations/referenced/many.rb
View
18 lib/mongoid/identity_map.rb
@@ -4,6 +4,21 @@ module Mongoid #:nodoc:
# Defines behaviour for the identity map in Mongoid.
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.
#
# @example Get the document from the map.
@@ -62,8 +77,7 @@ def set(document)
#
# @since 2.2.0
def set_many(document, selector)
- documents = documents_for(document.class)[selector] ||= []
- documents.push(document) unless documents.include?(document)
+ (documents_for(document.class)[selector] ||= []).push(document)
end
# Set a document in the identity map for the provided selector.
View
8 lib/mongoid/relations/referenced/many.rb
@@ -563,9 +563,15 @@ def criteria(metadata, object, type = nil)
#
# @since 2.2.0
def eager_load(metadata, ids)
+ cleared = false
klass, foreign_key = metadata.klass, metadata.foreign_key
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

0 comments on commit 612c346

Please sign in to comment.
Something went wrong with that request. Please try again.