Added Set for use in membership tests, optimizing out the expensive call to Array#include?

This commit is contained in:
justindossey 2010-05-25 14:34:47 -07:00 committed by Kyle Banker
parent 51140f8ea1
commit 222040f82d
1 changed files with 11 additions and 1 deletions

View File

@ -20,6 +20,8 @@
# #
# Under Ruby 1.9 and greater, this class has no added methods because Ruby's # Under Ruby 1.9 and greater, this class has no added methods because Ruby's
# Hash already keeps its keys ordered by order of insertion. # Hash already keeps its keys ordered by order of insertion.
require 'set'
module BSON module BSON
class OrderedHash < Hash class OrderedHash < Hash
@ -55,6 +57,7 @@ module BSON
def initialize(*a, &b) def initialize(*a, &b)
super super
@ordered_keys = [] @ordered_keys = []
@ordered_set = Set.new
end end
def keys def keys
@ -63,7 +66,11 @@ module BSON
def []=(key, value) def []=(key, value)
@ordered_keys ||= [] @ordered_keys ||= []
@ordered_keys << key unless @ordered_keys.include?(key) @ordered_set ||= Set.new
unless @ordered_set.member?(key)
@ordered_keys << key
@ordered_set.add(key)
end
super(key, value) super(key, value)
end end
@ -93,6 +100,7 @@ module BSON
@ordered_keys ||= [] @ordered_keys ||= []
@ordered_keys += other.keys # unordered if not an BSON::OrderedHash @ordered_keys += other.keys # unordered if not an BSON::OrderedHash
@ordered_keys.uniq! @ordered_keys.uniq!
@ordered_set = Set.new(@ordered_keys)
super(other) super(other)
end end
@ -106,6 +114,7 @@ module BSON
def delete(key, &block) def delete(key, &block)
@ordered_keys.delete(key) if @ordered_keys @ordered_keys.delete(key) if @ordered_keys
@ordered_set.delete(key) if @ordered_set
super super
end end
@ -119,6 +128,7 @@ module BSON
def clear def clear
super super
@ordered_set.clear
@ordered_keys = [] @ordered_keys = []
end end