lib/s3sync/sync.rb in s3sync-2.0.1 vs lib/s3sync/sync.rb in s3sync-2.0.2

- old
+ new

@@ -69,39 +69,44 @@ end class Node include Comparable + SMALL_FILE = 50 * 1024 # 50.kilobytes + attr_accessor :base attr_accessor :path attr_accessor :size + attr_accessor :small_comparator - def initialize base, path, size + def initialize base, path, size, small_comparator = nil @base = base @path = path @size = size + @small_comparator = small_comparator end def full S3Sync.safe_join [@base, @path] end def == other - full == other.full and @size == other.size + @size == other.size && compare_small_comparators(other) end - def <=> other - if self.size < other.size - -1 - elsif self.size > other.size - 1 - else - 0 - end - end - alias eql? == + + private + + # If files are small and both nodes have a comparator, we can call an extra + # provided block to verify equality. This allows + def compare_small_comparators(other) + return true if @size > SMALL_FILE || other.size > SMALL_FILE + return true if small_comparator.nil? || other.small_comparator.nil? + + small_comparator.call == other.small_comparator.call + end end class LocalDirectory attr_accessor :source @@ -134,11 +139,12 @@ # folders and I don't think we care about any other thing, right? next unless st.file? # We only need the relative path here file_name = file.gsub(/^#{@source}\/?/, '').squeeze('/') - node = Node.new(@source.squeeze('/'), file_name, st.size) + small_comparator = lambda { Digest::MD5.hexdigest File.read(file) } + node = Node.new(@source.squeeze('/'), file_name, st.size, small_comparator) nodes[node.path] = node end return nodes end @@ -151,11 +157,11 @@ hash1.each do |key, value| value2 = hash2.delete key if value2.nil? to_add_to_2 << value - elsif value2.size == value.size + elsif value2 == value same << value else to_add_to_2 << value end end @@ -295,10 +301,12 @@ dir = location.path dir += '/' if not dir.empty? and not dir.end_with?('/') nodes = {} @args.s3.buckets[location.bucket].objects.with_prefix(dir || "").to_a.collect do |obj| - node = Node.new(location.path, obj.key, obj.content_length) + # etag comes back with quotes (obj.etag.inspcet # => "\"abc...def\"" + small_comparator = lambda { obj.etag[/[a-z0-9]+/] } + node = Node.new(location.path, obj.key, obj.content_length, small_comparator) nodes[node.path] = node end return nodes end