def compare_blocks(left_block_cursor, right_block_cursor)
left_cursor = right_cursor = nil
left_row_checksums = left_block_cursor.row_checksums
right_row_checksums = right_block_cursor.row_checksums
left_diff_rows = []
left_diff_checksums = []
right_diff_rows = []
right_diff_checksums = []
i = k = 0
while i < left_row_checksums.size or k < right_row_checksums.size
left_keys = i < left_row_checksums.size ? left_row_checksums[i][:row_keys] : nil
right_keys = k < right_row_checksums.size ? right_row_checksums[k][:row_keys] : nil
rank = rank_rows left_keys, right_keys
case rank
when -1
left_diff_rows << left_keys
left_diff_checksums << left_row_checksums[i][:checksum]
i += 1
when 1
right_diff_rows << right_keys
right_diff_checksums << right_row_checksums[k][:checksum]
k += 1
when 0
if left_row_checksums[i][:checksum] != right_row_checksums[k][:checksum]
left_diff_rows << left_keys
left_diff_checksums << left_row_checksums[i][:checksum]
right_diff_rows << right_keys
right_diff_checksums << right_row_checksums[k][:checksum]
end
i += 1
k += 1
end
end
left_row_cache = left_block_cursor.retrieve_row_cache left_diff_checksums
right_row_cache = right_block_cursor.retrieve_row_cache right_diff_checksums
left_uncached_rows = []
left_diff_rows.each_with_index do |row, i|
left_uncached_rows << row unless left_row_cache[left_diff_checksums[i]]
end
right_uncached_rows = []
right_diff_rows.each_with_index do |row, i|
right_uncached_rows << row unless right_row_cache[right_diff_checksums[i]]
end
unless left_uncached_rows.empty?
left_cursor = session.left.create_cursor \
ProxyRowCursor, left_table, :row_keys => left_uncached_rows
end
unless right_uncached_rows.empty?
right_cursor = session.right.create_cursor \
ProxyRowCursor, right_table, :row_keys => right_uncached_rows
end
i = k = 0
while i < left_diff_rows.size or k < right_diff_rows.size
rank = rank_rows left_diff_rows[i], right_diff_rows[k]
case rank
when -1
if left_row_cache.include? left_diff_checksums[i]
row = Marshal.load(left_row_cache[left_diff_checksums[i]])
else
row = left_cursor.next_row
end
yield :left, row
i += 1
when 1
if right_row_cache.include? right_diff_checksums[k]
row = Marshal.load(right_row_cache[right_diff_checksums[k]])
else
row = right_cursor.next_row
end
yield :right, row
k += 1
when 0
if left_row_cache.include? left_diff_checksums[i]
left_row = Marshal.load(left_row_cache[left_diff_checksums[i]])
else
left_row = left_cursor.next_row
end
if right_row_cache.include? right_diff_checksums[k]
right_row = Marshal.load(right_row_cache[right_diff_checksums[k]])
else
row = right_cursor.next_row
end
yield :conflict, [left_row, right_row]
i += 1
k += 1
end
end
ensure
session.left.destroy_cursor left_cursor if left_cursor
session.right.destroy_cursor right_cursor if right_cursor
end