diff options
author | Frederick Cheung <frederick.cheung@gmail.com> | 2008-12-09 20:36:24 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2008-12-10 09:07:47 -0800 |
commit | 355f41d8aafd75d76db25cdda4736e0052b0605c (patch) | |
tree | 0dca4b27bcb61c24d38f28f34f7c6cbdc5ac4596 | |
parent | 014b7994ac1a829845e2882f4c852bc28bd2aa53 (diff) | |
download | rails-355f41d8aafd75d76db25cdda4736e0052b0605c.tar.gz rails-355f41d8aafd75d76db25cdda4736e0052b0605c.tar.bz2 rails-355f41d8aafd75d76db25cdda4736e0052b0605c.zip |
Rework ActiveSupport::OrderedHash to make lookups faster
[#1352 state:committed]
Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
-rw-r--r-- | activerecord/test/cases/calculations_test.rb | 5 | ||||
-rw-r--r-- | activesupport/lib/active_support/ordered_hash.rb | 59 | ||||
-rw-r--r-- | activesupport/test/ordered_hash_test.rb | 10 |
3 files changed, 36 insertions, 38 deletions
diff --git a/activerecord/test/cases/calculations_test.rb b/activerecord/test/cases/calculations_test.rb index 8bd0dd0f6e..080f6a7007 100644 --- a/activerecord/test/cases/calculations_test.rb +++ b/activerecord/test/cases/calculations_test.rb @@ -171,8 +171,9 @@ class CalculationsTest < ActiveRecord::TestCase Account.expects(:columns).at_least_once.returns([column]) c = Account.count(:all, :group => :firm) - assert_equal Firm, c.first.first.class - assert_equal 1, c.first.last + first_key = c.keys.first + assert_equal Firm, first_key.class + assert_equal 1, c[first_key] end end diff --git a/activesupport/lib/active_support/ordered_hash.rb b/activesupport/lib/active_support/ordered_hash.rb index 5de94c67e0..1ed7737017 100644 --- a/activesupport/lib/active_support/ordered_hash.rb +++ b/activesupport/lib/active_support/ordered_hash.rb @@ -4,62 +4,49 @@ module ActiveSupport if RUBY_VERSION >= '1.9' OrderedHash = ::Hash else - class OrderedHash < Array #:nodoc: - def []=(key, value) - if pair = assoc(key) - pair.pop - pair << value - else - self << [key, value] - end - value + class OrderedHash < Hash #:nodoc: + def initialize(*args, &block) + super + @keys = [] end - def [](key) - pair = assoc(key) - pair ? pair.last : nil + def []=(key, value) + if !has_key?(key) + @keys << key + end + super end def delete(key) - pair = assoc(key) - pair ? array_index = index(pair) : nil - array_index ? delete_at(array_index).last : nil + array_index = has_key?(key) && index(key) + if array_index + @keys.delete_at(array_index) + end + super end def keys - collect { |key, value| key } + @keys end def values - collect { |key, value| value } + @keys.collect { |key| self[key] } end def to_hash - returning({}) do |hash| - each { |array| hash[array[0]] = array[1] } - end - end - - def has_key?(k) - !assoc(k).nil? - end - - alias_method :key?, :has_key? - alias_method :include?, :has_key? - alias_method :member?, :has_key? - - def has_value?(v) - any? { |key, value| value == v } + Hash.new(self) end - alias_method :value?, :has_value? - def each_key - each { |key, value| yield key } + @keys.each { |key| yield key } end def each_value - each { |key, value| yield value } + @keys.each { |key| yield self[key]} + end + + def each + keys.each {|key| yield [key, self[key]]} end end end diff --git a/activesupport/test/ordered_hash_test.rb b/activesupport/test/ordered_hash_test.rb index 17dffbd624..094f9316d6 100644 --- a/activesupport/test/ordered_hash_test.rb +++ b/activesupport/test/ordered_hash_test.rb @@ -73,4 +73,14 @@ class OrderedHashTest < Test::Unit::TestCase @ordered_hash.each_value { |v| values << v } assert_equal @values, values end + + def test_each + values = [] + @ordered_hash.each {|key, value| values << value} + assert_equal @values, values + end + + def test_each_with_index + @ordered_hash.each_with_index { |pair, index| assert_equal [@keys[index], @values[index]], pair} + end end |