Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote branch 'siggy/master'

  • Loading branch information...
commit 63ddf142e0a989c79b9c51ac39e77a9019c7a7e3 2 parents f115ad9 + 1da91e9
@ryanking ryanking authored
View
14 lib/cassandra/columns.rb
@@ -22,7 +22,7 @@ def column_name_class_for_key(column_family, comparator_key)
case $1
when "LongType" then Long
when "LexicalUUIDType", "TimeUUIDType" then SimpleUUID::UUID
- else
+ else
String # UTF8, Ascii, Bytes, anything else
end
end
@@ -41,13 +41,13 @@ def multi_column_to_hash!(hash)
end
def multi_columns_to_hash!(column_family, hash)
- hash.each do |key, columns|
+ hash.each do |key, columns|
hash[key] = columns_to_hash(column_family, columns)
end
end
def multi_sub_columns_to_hash!(column_family, hash)
- hash.each do |key, sub_columns|
+ hash.each do |key, sub_columns|
hash[key] = sub_columns_to_hash(column_family, sub_columns)
end
end
@@ -64,11 +64,11 @@ def columns_to_hash_for_classes(columns, column_name_class, sub_column_name_clas
hash = OrderedHash.new
Array(columns).each do |c|
c = c.super_column || c.column if c.is_a?(CassandraThrift::ColumnOrSuperColumn)
- hash[column_name_class.new(c.name)] = case c
- when CassandraThrift::SuperColumn
- columns_to_hash_for_classes(c.columns, sub_column_name_class) # Pop the class stack, and recurse
+ case c
+ when CassandraThrift::SuperColumn
+ hash.[]=(column_name_class.new(c.name), columns_to_hash_for_classes(c.columns, sub_column_name_class)) # Pop the class stack, and recurse
when CassandraThrift::Column
- c.value
+ hash.[]=(column_name_class.new(c.name), c.value, c.timestamp)
end
end
hash
View
73 lib/cassandra/ordered_hash.rb
@@ -2,9 +2,9 @@
class Cassandra
# Hash is ordered in Ruby 1.9!
if RUBY_VERSION >= '1.9'
- OrderedHash = ::Hash
+ OrderedHashInt = ::Hash
else
- class OrderedHash < Hash #:nodoc:
+ class OrderedHashInt < Hash #:nodoc:
def initialize(*args, &block)
super
@keys = []
@@ -52,7 +52,7 @@ def delete(key)
end
super
end
-
+
def delete_if
super
sync_keys!
@@ -127,10 +127,6 @@ def replace(other)
self
end
- def inspect
- "#<OrderedHash #{super}>"
- end
-
private
def sync_keys!
@@ -138,4 +134,67 @@ def sync_keys!
end
end
end
+
+ class OrderedHash < OrderedHashInt #:nodoc:
+ def initialize(*args, &block)
+ @timestamps = Hash.new
+ super
+ end
+
+ def initialize_copy(other)
+ @timestamps = other.timestamps
+ super
+ end
+
+ def []=(key, value, timestamp = nil)
+ @timestamps[key] = timestamp
+ super(key, value)
+ end
+
+ def delete(key)
+ @timestamps.delete(key)
+ super
+ end
+
+ def delete_if
+ @timestamps.delete_if
+ super
+ end
+
+ def reject!
+ @timestamps.reject!
+ super
+ end
+
+ def timestamps
+ @timestamps.dup
+ end
+
+ def clear
+ @timestamps.clear
+ super
+ end
+
+ def shift
+ k, v = super
+ @timestamps.delete(k)
+ [k, v]
+ end
+
+ def replace(other)
+ @timestamps = other.timestamps
+ super
+ end
+
+ def inspect
+ "#<OrderedHash #{super}\n#{@timestamps.inspect}>"
+ end
+
+ private
+
+ def sync_keys!
+ @timestamps.delete_if {|k,v| !has_key?(k)}
+ super
+ end
+ end
end
View
43 test/cassandra_test.rb
@@ -27,6 +27,7 @@ def test_inspect
def test_get_key
@twitter.insert(:Users, key, {'body' => 'v', 'user' => 'v'})
assert_equal({'body' => 'v', 'user' => 'v'}, @twitter.get(:Users, key))
+ assert_equal(['body', 'user'].sort, @twitter.get(:Users, key).timestamps.keys.sort)
assert_equal({}, @twitter.get(:Users, 'bogus'))
end
@@ -42,13 +43,14 @@ def test_get_key_preserving_order
hash = OrderedHash['b', '', 'c', '', 'd', '', 'a', '']
@twitter.insert(:Users, key, hash)
assert_equal(hash.keys.sort, @twitter.get(:Users, key).keys)
+ assert_equal(hash.timestamps.keys.sort, @twitter.get(:Users, key).timestamps.keys.sort)
assert_not_equal(hash.keys, @twitter.get(:Users, key).keys)
end
def test_get_first_time_uuid_column
- @blogs.insert(:Blogs, key,
+ @blogs.insert(:Blogs, key,
{@uuids[0] => 'I like this cat', @uuids[1] => 'Buttons is cuter', @uuids[2] => 'I disagree'})
-
+
assert_equal({@uuids[0] => 'I like this cat'}, @blogs.get(:Blogs, key, :count => 1))
assert_equal({@uuids[2] => 'I disagree'}, @blogs.get(:Blogs, key, :count => 1, :reversed => true))
assert_equal({}, @blogs.get(:Blogs, 'bogus'))
@@ -62,12 +64,15 @@ def test_get_multiple_time_uuid_columns
end
def test_get_first_long_column
- @blogs_long.insert(:Blogs, key,
+ @blogs_long.insert(:Blogs, key,
{@longs[0] => 'I like this cat', @longs[1] => 'Buttons is cuter', @longs[2] => 'I disagree'})
assert_equal({@longs[0] => 'I like this cat'}, @blogs_long.get(:Blogs, key, :count => 1))
assert_equal({@longs[2] => 'I disagree'}, @blogs_long.get(:Blogs, key, :count => 1, :reversed => true))
assert_equal({}, @blogs_long.get(:Blogs, 'bogus'))
+
+ assert_equal([@longs[0]], @blogs_long.get(:Blogs, key, :count => 1).timestamps.keys)
+ assert_equal([@longs[2]], @blogs_long.get(:Blogs, key, :count => 1, :reversed => true).timestamps.keys)
end
def test_long_remove_bug
@@ -77,12 +82,15 @@ def test_long_remove_bug
@blogs_long.insert(:Blogs, key, {@longs[0] => 'I really like this cat'})
assert_equal({@longs[0] => 'I really like this cat'}, @blogs_long.get(:Blogs, key, :count => 1))
+ assert_equal([@longs[0]], @blogs_long.get(:Blogs, key, :count => 1).timestamps.keys)
end
def test_get_with_count
@twitter.insert(:Statuses, key, {'1' => 'v', '2' => 'v', '3' => 'v'})
assert_equal 1, @twitter.get(:Statuses, key, :count => 1).size
assert_equal 2, @twitter.get(:Statuses, key, :count => 2).size
+ assert_equal 1, @twitter.get(:Statuses, key, :count => 1).timestamps.size
+ assert_equal 2, @twitter.get(:Statuses, key, :count => 2).timestamps.size
end
def test_get_value
@@ -103,6 +111,7 @@ def test_get_super_key
columns = {'user_timelines' => {@uuids[4] => '4', @uuids[5] => '5'}}
@twitter.insert(:StatusRelationships, key, columns)
assert_equal(columns, @twitter.get(:StatusRelationships, key))
+ assert_equal(columns.keys, @twitter.get(:StatusRelationships, key).timestamps.keys)
assert_equal({}, @twitter.get(:StatusRelationships, 'bogus'))
end
@@ -113,6 +122,7 @@ def test_get_several_super_keys
@twitter.insert(:StatusRelationships, key, columns)
assert_equal(columns, @twitter.get(:StatusRelationships, key))
+ assert_equal(columns.keys, @twitter.get(:StatusRelationships, key).timestamps.keys)
assert_equal({}, @twitter.get(:StatusRelationships, 'bogus'))
end
@@ -123,6 +133,10 @@ def test_get_super_sub_keys_with_count
@twitter.get(:StatusRelationships, key, "user_timelines", :count => 1))
assert_equal({@uuids[3] => 'v3'},
@twitter.get(:StatusRelationships, key, "user_timelines", :count => 1, :reversed => true))
+ assert_equal([@uuids[1]],
+ @twitter.get(:StatusRelationships, key, "user_timelines", :count => 1).timestamps.keys)
+ assert_equal([@uuids[3]],
+ @twitter.get(:StatusRelationships, key, "user_timelines", :count => 1, :reversed => true).timestamps.keys)
end
def test_get_super_sub_keys_with_ranges
@@ -139,12 +153,16 @@ def test_get_super_sub_keys_with_ranges
assert_equal({@uuids[1] => 'v1'}, @twitter.get(:StatusRelationships, key, "user_timelines", :finish => @uuids[2], :count => 1))
assert_equal({@uuids[2] => 'v2'}, @twitter.get(:StatusRelationships, key, "user_timelines", :start => @uuids[2], :count => 1))
assert_equal 4, @twitter.get(:StatusRelationships, key, "user_timelines", :start => @uuids[2], :finish => @uuids[5]).size
+ assert_equal([@uuids[1]], @twitter.get(:StatusRelationships, key, "user_timelines", :finish => @uuids[2], :count => 1).timestamps.keys)
+ assert_equal([@uuids[2]], @twitter.get(:StatusRelationships, key, "user_timelines", :start => @uuids[2], :count => 1).timestamps.keys)
+ assert_equal 4, @twitter.get(:StatusRelationships, key, "user_timelines", :start => @uuids[2], :finish => @uuids[5]).timestamps.size
end
def test_get_super_sub_key
columns = {@uuids[1] => 'v1', @uuids[2] => 'v2'}
@twitter.insert(:StatusRelationships, key, {'user_timelines' => columns})
assert_equal(columns, @twitter.get(:StatusRelationships, key, 'user_timelines'))
+ assert_equal(columns.keys.sort, @twitter.get(:StatusRelationships, key, 'user_timelines').timestamps.keys.sort)
assert_equal({}, @twitter.get(:StatusRelationships, 'bogus', 'user_timelines'))
# FIXME Not sure if this is valid
# assert_nil @twitter.exists?(:StatusRelationships, 'bogus', 'user_timelines')
@@ -167,7 +185,7 @@ def test_get_super_value
# @twitter.insert(:Statuses, '6', {'body' => '1'})
# assert_equal(['3', '4', '5'], @twitter.get_range(:Statuses, :start => '3', :finish => '5'))
# end
-
+
def test_get_range_count
@twitter.insert(:Statuses, '2', {'body' => '1'})
@twitter.insert(:Statuses, '3', {'body' => '1'})
@@ -185,11 +203,13 @@ def test_multi_get
result = @twitter.multi_get(:Users, [key + '1', key + '2', 'bogus'])
assert_equal expected, result
assert_equal expected.keys, result.keys
+ assert_equal expected.keys.sort, @twitter.multi_get(:Users, [key + '1', key + '2', 'bogus']).timestamps.keys.sort
expected = OrderedHash[key + '2', {'body' => 'v2', 'user' => 'v2'}, 'bogus', {}, key + '1', {'body' => 'v1', 'user' => 'v1'}]
result = @twitter.multi_get(:Users, [key + '2', 'bogus', key + '1'])
assert_equal expected, result
assert_equal expected.keys, result.keys
+ assert_equal expected.keys.sort, @twitter.multi_get(:Users, [key + '2', 'bogus', key + '1']).timestamps.keys.sort
end
def test_remove_key
@@ -204,6 +224,7 @@ def test_remove_value
@twitter.insert(:Statuses, key, {'body' => 'v'})
@twitter.remove(:Statuses, key, 'body')
assert_nil @twitter.get(:Statuses, key, 'body')
+ assert_nil @twitter.get(:Statuses, key).timestamps['body']
end
def test_remove_super_key
@@ -223,6 +244,7 @@ def test_remove_super_value
@twitter.insert(:StatusRelationships, key, {'user_timelines' => columns})
@twitter.remove(:StatusRelationships, key, 'user_timelines', columns.keys.first)
assert_nil @twitter.get(:StatusRelationships, key, 'user_timelines', columns.keys.first)
+ assert_nil @twitter.get(:StatusRelationships, key, 'user_timelines').timestamps[columns.keys.first]
end
def test_clear_column_family
@@ -236,12 +258,14 @@ def test_clear_column_family
def test_insert_key
@twitter.insert(:Statuses, key, {'body' => 'v', 'user' => 'v'})
assert_equal({'body' => 'v', 'user' => 'v'}, @twitter.get(:Statuses, key))
+ assert_equal(['body', 'user'], @twitter.get(:Statuses, key).timestamps.keys)
end
def test_insert_super_key
columns = {@uuids[1] => 'v1', @uuids[2] => 'v2'}
@twitter.insert(:StatusRelationships, key, {'user_timelines' => columns})
assert_equal(columns, @twitter.get(:StatusRelationships, key, 'user_timelines'))
+ assert_equal(columns.keys.sort, @twitter.get(:StatusRelationships, key, 'user_timelines').timestamps.keys.sort)
end
def test_get_columns
@@ -273,6 +297,12 @@ def test_multi_get_columns
assert_equal(
OrderedHash[key + '2', ['v2', 'v2'], 'bogus', [nil, nil], key + '1', ['v1', 'v1']],
@twitter.multi_get_columns(:Users, [key + '2', 'bogus', key + '1'], ['body', 'user']))
+ assert_equal(
+ OrderedHash[key + '1', ['v1', 'v1'], key + '2', ['v2', 'v2'], 'bogus', [nil, nil]].keys.sort,
+ @twitter.multi_get_columns(:Users, [key + '1', key + '2', 'bogus'], ['body', 'user']).timestamps.keys.sort)
+ assert_equal(
+ OrderedHash[key + '2', ['v2', 'v2'], 'bogus', [nil, nil], key + '1', ['v1', 'v1']].keys.sort,
+ @twitter.multi_get_columns(:Users, [key + '2', 'bogus', key + '1'], ['body', 'user']).timestamps.keys.sort)
end
def test_count_keys
@@ -338,6 +368,11 @@ def test_batch_mutate
assert_equal({'body' => 'v4', 'user' => 'v4'}, @twitter.get(:Users, k + '4')) # Written
assert_equal({'body' => 'v'}, @twitter.get(:Statuses, k + '3')) # Written
assert_equal({}, @twitter.get(:Users, k + '1')) # Removed
+
+ assert_equal({'body' => 'v2', 'user' => 'v2'}.keys.sort, @twitter.get(:Users, k + '2').timestamps.keys.sort) # Written
+ assert_equal({'body' => 'v3', 'user' => 'v3', 'location' => 'v3'}.keys.sort, @twitter.get(:Users, k + '3').timestamps.keys.sort) # Written and compacted
+ assert_equal({'body' => 'v4', 'user' => 'v4'}.keys.sort, @twitter.get(:Users, k + '4').timestamps.keys.sort) # Written
+ assert_equal({'body' => 'v'}.keys.sort, @twitter.get(:Statuses, k + '3').timestamps.keys.sort) # Written
end
def test_complain_about_nil_key
View
185 test/ordered_hash_test.rb
@@ -1,6 +1,6 @@
require File.expand_path(File.dirname(__FILE__) + '/test_helper')
-class OrderedHashTest < Test::Unit::TestCase
+class OrderedHashTestInt < Test::Unit::TestCase
def setup
@keys = %w( blue green red pink orange )
@values = %w( 000099 009900 aa0000 cc0066 cc6633 )
@@ -152,7 +152,7 @@ def test_shift
assert_equal [@keys.first, @values.first], pair
assert !@ordered_hash.keys.include?(pair.first)
end
-
+
def test_keys
original = @ordered_hash.keys.dup
@ordered_hash.keys.pop
@@ -198,4 +198,183 @@ def test_replace_updates_keys
assert_same original, @ordered_hash
assert_equal @other_ordered_hash.keys, @ordered_hash.keys
end
-end
+end
+
+class OrderedHashTest < Test::Unit::TestCase
+ def setup
+ @keys = %w( blue green red pink orange )
+ @values = %w( 000099 009900 aa0000 cc0066 cc6633 )
+ @timestamps = %w( 12 34 56 78 90 )
+ @hash = Hash.new
+ @timestamps_hash = Hash.new
+ @ordered_hash = Cassandra::OrderedHash.new
+
+ @keys.each_with_index do |key, index|
+ @hash[key] = @values[index]
+ @timestamps_hash[key] = @timestamps[index]
+ @ordered_hash.[]=(key, @values[index], @timestamps[index])
+ end
+ end
+
+ def test_order
+ assert_equal @keys, @ordered_hash.keys
+ assert_equal @values, @ordered_hash.values
+ assert_equal @timestamps_hash, @ordered_hash.timestamps
+ end
+
+ def test_access
+ assert @hash.all? { |k, v| @ordered_hash[k] == v }
+ assert @timestamps_hash.all? { |k, v| @ordered_hash.timestamps[k] == v }
+ end
+
+ def test_assignment
+ key, value, timestamp = 'purple', '5422a8', '1234'
+
+ @ordered_hash.[]=(key, value, timestamp)
+
+ assert_equal @keys.length + 1, @ordered_hash.length
+ assert_equal key, @ordered_hash.keys.last
+ assert_equal value, @ordered_hash.values.last
+ assert_equal value, @ordered_hash[key]
+
+ assert_equal @keys.length + 1, @ordered_hash.timestamps.length
+ assert_equal key, @ordered_hash.timestamps.keys.last
+ assert_equal timestamp, @ordered_hash.timestamps.values.last
+ assert_equal timestamp, @ordered_hash.timestamps[key]
+ end
+
+ def test_delete
+ key, value, timestamp = 'white', 'ffffff', '999'
+ bad_key = 'black'
+
+ @ordered_hash.[]=(key, value, timestamp)
+ assert_equal @keys.length + 1, @ordered_hash.length
+ assert_equal @ordered_hash.keys.length, @ordered_hash.length
+
+ assert_equal value, @ordered_hash.delete(key)
+ assert_equal @keys.length, @ordered_hash.length
+ assert_equal @ordered_hash.keys.length, @ordered_hash.length
+
+ assert_nil @ordered_hash.delete(bad_key)
+
+ @ordered_hash.[]=(key, value, timestamp)
+ assert_equal @keys.length + 1, @ordered_hash.timestamps.length
+ assert_equal @ordered_hash.keys.length, @ordered_hash.timestamps.length
+
+ assert_equal value, @ordered_hash.delete(key)
+ assert_equal @keys.length, @ordered_hash.timestamps.length
+ assert_equal @ordered_hash.keys.length, @ordered_hash.timestamps.length
+
+ assert_nil @ordered_hash.delete(bad_key)
+ end
+
+ def test_to_a
+ assert_equal @keys.zip(@timestamps).sort, @ordered_hash.timestamps.sort.to_a
+ end
+
+ def test_has_key
+ assert_equal true, @ordered_hash.timestamps.has_key?('blue')
+ assert_equal true, @ordered_hash.timestamps.key?('blue')
+ assert_equal true, @ordered_hash.timestamps.include?('blue')
+ assert_equal true, @ordered_hash.timestamps.member?('blue')
+
+ assert_equal false, @ordered_hash.timestamps.has_key?('indigo')
+ assert_equal false, @ordered_hash.timestamps.key?('indigo')
+ assert_equal false, @ordered_hash.timestamps.include?('indigo')
+ assert_equal false, @ordered_hash.timestamps.member?('indigo')
+ end
+
+ def test_has_value
+ assert_equal true, @ordered_hash.timestamps.has_value?('12')
+ assert_equal true, @ordered_hash.timestamps.value?('12')
+ assert_equal false, @ordered_hash.timestamps.has_value?('99')
+ assert_equal false, @ordered_hash.timestamps.value?('99')
+ end
+
+ def test_each_key
+ keys = []
+ @ordered_hash.timestamps.each_key { |k| keys << k }
+ assert_equal @keys.sort, keys.sort
+ end
+
+ def test_each_value
+ values = []
+ @ordered_hash.timestamps.each_value { |v| values << v }
+ assert_equal @timestamps.sort, values.sort
+ end
+
+ def test_each
+ values = []
+ @ordered_hash.timestamps.each {|key, value| values << value}
+ assert_equal @timestamps.sort, values.sort
+ end
+
+ def test_delete_if
+ copy = @ordered_hash.dup
+ copy.delete('pink')
+ assert_equal copy, @ordered_hash.delete_if { |k, _| k == 'pink' }
+ assert !@ordered_hash.timestamps.keys.include?('pink')
+ end
+
+ def test_reject!
+ (copy = @ordered_hash.dup).delete('pink')
+ @ordered_hash.reject! { |k, _| k == 'pink' }
+ assert_equal copy, @ordered_hash
+ assert !@ordered_hash.keys.include?('pink')
+ end
+
+ def test_reject
+ copy = @ordered_hash.dup
+ new_ordered_hash = @ordered_hash.reject { |k, _| k == 'pink' }
+ assert_equal copy, @ordered_hash
+ assert !new_ordered_hash.timestamps.keys.include?('pink')
+ assert @ordered_hash.timestamps.keys.include?('pink')
+ end
+
+ def test_clear
+ @ordered_hash.clear
+ assert_equal [], @ordered_hash.timestamps.keys
+ end
+
+ def test_merge
+ other_hash = Cassandra::OrderedHash.new
+ other_hash['purple'] = '800080'
+ other_hash['violet'] = 'ee82ee'
+ merged = @ordered_hash.merge other_hash
+ assert_equal merged.timestamps.length, @ordered_hash.timestamps.length + other_hash.timestamps.length
+ assert_equal (@keys + ['purple', 'violet']).sort, merged.timestamps.keys.sort
+
+ @ordered_hash.merge! other_hash
+ assert_equal @ordered_hash.timestamps, merged.timestamps
+ assert_equal @ordered_hash.timestamps.keys.sort, merged.timestamps.keys.sort
+ end
+
+ def test_shift
+ pair = @ordered_hash.shift
+ assert_equal [@keys.first, @values.first], pair
+ assert !@ordered_hash.timestamps.keys.include?(pair.first)
+ end
+
+ def test_keys
+ original = @ordered_hash.keys.dup
+ @ordered_hash.keys.pop
+ assert_equal original.sort, @ordered_hash.timestamps.keys.sort
+ end
+
+ def test_inspect
+ assert @ordered_hash.timestamps.sort.inspect.include?(@timestamps_hash.sort.inspect)
+ end
+
+ def test_alternate_initialization_with_splat
+ alternate = Cassandra::OrderedHash[1,2,3,4]
+ assert_kind_of Cassandra::OrderedHash, alternate
+ assert_equal [1, 3], alternate.timestamps.keys
+ end
+
+ def test_replace_updates_keys
+ @other_ordered_hash = Cassandra::OrderedHash[:black, '000000', :white, '000000']
+ original = @ordered_hash.replace(@other_ordered_hash)
+ assert_equal original.timestamps, @ordered_hash.timestamps
+ assert_equal @other_ordered_hash.timestamps.keys, @ordered_hash.timestamps.keys
+ end
+end

0 comments on commit 63ddf14

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