Skip to content

Commit 222040f

Browse files
justindosseybanker
authored andcommitted
Added Set for use in membership tests, optimizing out the expensive call to Array#include?
1 parent 51140f8 commit 222040f

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

lib/bson/ordered_hash.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#
2121
# Under Ruby 1.9 and greater, this class has no added methods because Ruby's
2222
# Hash already keeps its keys ordered by order of insertion.
23+
require 'set'
24+
2325
module BSON
2426
class OrderedHash < Hash
2527

@@ -55,6 +57,7 @@ def self.[] *args
5557
def initialize(*a, &b)
5658
super
5759
@ordered_keys = []
60+
@ordered_set = Set.new
5861
end
5962

6063
def keys
@@ -63,7 +66,11 @@ def keys
6366

6467
def []=(key, value)
6568
@ordered_keys ||= []
66-
@ordered_keys << key unless @ordered_keys.include?(key)
69+
@ordered_set ||= Set.new
70+
unless @ordered_set.member?(key)
71+
@ordered_keys << key
72+
@ordered_set.add(key)
73+
end
6774
super(key, value)
6875
end
6976

@@ -93,6 +100,7 @@ def merge!(other)
93100
@ordered_keys ||= []
94101
@ordered_keys += other.keys # unordered if not an BSON::OrderedHash
95102
@ordered_keys.uniq!
103+
@ordered_set = Set.new(@ordered_keys)
96104
super(other)
97105
end
98106

@@ -106,6 +114,7 @@ def inspect
106114

107115
def delete(key, &block)
108116
@ordered_keys.delete(key) if @ordered_keys
117+
@ordered_set.delete(key) if @ordered_set
109118
super
110119
end
111120

@@ -119,6 +128,7 @@ def delete_if(&block)
119128

120129
def clear
121130
super
131+
@ordered_set.clear
122132
@ordered_keys = []
123133
end
124134

0 commit comments

Comments
 (0)