Permalink
Browse files

Faster CriteriaHash#simple?

Was creating 3 sets for each simple? check. Now shortcuiting if key
size is too great or using sort to do comparision against constants.
Fewer objects and sort is faster than set. Also increased test coverage.
  • Loading branch information...
1 parent dcc2f47 commit 7617e6c0caca203438dfc4b406666a5aaa393dec @jnunemaker jnunemaker committed Oct 10, 2012
Showing with 19 additions and 2 deletions.
  1. +14 −2 lib/plucky/criteria_hash.rb
  2. +5 −0 spec/plucky/criteria_hash_spec.rb
@@ -3,6 +3,17 @@ module Plucky
class CriteriaHash
attr_reader :source, :options
+ # Internal: Used to determine if criteria keys match simple id lookup.
+ SimpleIdQueryKeys = [:_id]
+
+ # Internal: Used to determine if criteria keys match simple id and type
+ # lookup (for single collection inheritance).
+ SimpleIdAndTypeQueryKeys = [:_id, :_type]
+
+ # Internal: Used to quickly check if it is possible that the
+ # criteria hash is simple.
+ SimpleQueryMaxSize = [SimpleIdQueryKeys.size, SimpleIdAndTypeQueryKeys.size].max
+
NestingOperators = [:$or, :$and, :$nor]
def initialize(hash={}, options={})
@@ -102,8 +113,9 @@ def object_ids=(value)
# If this is the case, you can use IdentityMap in library to not perform
# query and instead just return from map.
def simple?
- key_set = keys.to_set
- key_set == [:_id].to_set || key_set == [:_id, :_type].to_set
+ return false if keys.size > SimpleQueryMaxSize
+ sorted_keys = keys.sort
+ sorted_keys == SimpleIdQueryKeys || sorted_keys == SimpleIdAndTypeQueryKeys
end
private
@@ -348,6 +348,11 @@
it "returns true if only filtering by Sci" do
described_class.new(:_id => 'id', :_type => 'Foo').should be_simple
+ described_class.new(:_type => 'Foo', :_id => 'id').should be_simple # reverse order
+ end
+
+ it "returns false if querying by more than max number of simple keys" do
+ described_class.new(:one => 1, :two => 2, :three => 3).should_not be_simple
end
it "returns false if querying by anthing other than _id/Sci" do

0 comments on commit 7617e6c

Please sign in to comment.