class Dyph::Support::Diff3

Constants

Diff2Command

Public Class Methods

execute_diff(left, base, right, diff2) click to toggle source
# File lib/dyph/support/diff3.rb, line 5
def self.execute_diff(left, base, right, diff2)
  Diff3.new(left, base, right, diff2).get_differences
end
new(left, base, right, diff2) click to toggle source
# File lib/dyph/support/diff3.rb, line 9
def initialize(left, base, right, diff2)
  @left   = left
  @right  = right
  @base   = base
  @diff2 = diff2
end

Public Instance Methods

get_differences() click to toggle source
# File lib/dyph/support/diff3.rb, line 16
def get_differences
  #[[action, base_lo, base_hi, side_lo, side_hi]...]
  left_diff  = @diff2.diff(@base, @left).map { |r| Diff2Command.new(*r) }
  right_diff = @diff2.diff(@base, @right).map { |r| Diff2Command.new(*r) }
  collapse_differences(DiffDoubleQueue.new(left_diff, right_diff))
end

Private Instance Methods

build_result_queue(diffs_queue, prev_base_hi, result_queue) click to toggle source
# File lib/dyph/support/diff3.rb, line 45
def build_result_queue(diffs_queue, prev_base_hi, result_queue)
  #current side can be :left or :right
  if queue_finished?(diffs_queue.peek, prev_base_hi)
    result_queue
  else
    top_diff = diffs_queue.dequeue
    result_queue.enqueue(diffs_queue.current_side, top_diff)

    if prev_base_hi < top_diff.base_hi
      #switch the current side and adjust the base_hi
      diffs_queue.switch_sides
      build_result_queue(diffs_queue, top_diff.base_hi, result_queue)
    else
      build_result_queue(diffs_queue, prev_base_hi, result_queue)
    end
  end
end
collapse_differences(diffs_queue, differences=[]) click to toggle source
# File lib/dyph/support/diff3.rb, line 27
def collapse_differences(diffs_queue, differences=[])
  if diffs_queue.finished?
    differences
  else
    result_queue   = DiffDoubleQueue.new
    init_side =  diffs_queue.choose_side
    top_diff   =  diffs_queue.dequeue

    result_queue.enqueue(init_side, top_diff)

    diffs_queue.switch_sides
    build_result_queue(diffs_queue, top_diff.base_hi, result_queue)

    differences << determine_differnce(result_queue, init_side, diffs_queue.switch_sides)
    collapse_differences(diffs_queue, differences)
  end
end
decide_action(diff_diffs_queue, left_subset, right_subset) click to toggle source
# File lib/dyph/support/diff3.rb, line 91
def decide_action(diff_diffs_queue, left_subset, right_subset)
  #adjust because the ranges are 1 indexed

  if diff_diffs_queue.empty?(:left)
    :choose_right
  elsif diff_diffs_queue.empty?(:right)
    :choose_left
  else
    if left_subset != right_subset
      :possible_conflict
    else
      :no_conflict_found
    end
  end
end
determine_differnce(diff_diffs_queue, init_side, final_side) click to toggle source
# File lib/dyph/support/diff3.rb, line 67
        def determine_differnce(diff_diffs_queue, init_side, final_side)
          base_lo = diff_diffs_queue.get(init_side).first.base_lo
          base_hi = diff_diffs_queue.get(final_side).last.base_hi
#          puts "Beta base_lo #{base_lo} base_hi #{base_hi}"
          left_lo,  left_hi    = diffable_endpoints(diff_diffs_queue.get(:left), base_lo, base_hi)
          right_lo, right_hi   = diffable_endpoints(diff_diffs_queue.get(:right), base_lo, base_hi)

          #the endpoints are offset one, neet to account for that in getting subsets
          left_subset = @left[left_lo-1 .. left_hi]
          right_subset = @right[right_lo-1 .. right_hi]
          change_type = decide_action(diff_diffs_queue, left_subset, right_subset)
          [change_type, left_lo, left_hi, right_lo, right_hi, base_lo, base_hi]
        end
diffable_endpoints(command, base_lo, base_hi) click to toggle source
# File lib/dyph/support/diff3.rb, line 81
def diffable_endpoints(command, base_lo, base_hi)
  if command.any?
    lo = command.first.side_lo - command.first.base_lo +  base_lo
    hi = command.last.side_hi  - command.last.base_hi  + base_hi
    [lo, hi]
  else
    [base_lo,  base_hi]
  end
end
queue_finished?(queue, prev_base_hi) click to toggle source
# File lib/dyph/support/diff3.rb, line 63
def queue_finished?(queue, prev_base_hi)
  queue.empty? || queue.first.base_lo > prev_base_hi + 1
end