diff --git a/diff.js b/diff.js index d7a8ca4..027a40d 100644 --- a/diff.js +++ b/diff.js @@ -100,74 +100,81 @@ var _diff_item_order = function(diff, A, B, options, filter){ } -// get common chuncs... -// XXX add chunk offsets to results... -var getCommonSections = -function(A, B, a, b, min_chunk, cmp, index){ - a = a || 0 - b = b || 0 - min_chunk = min_chunk || 2 +// get common chuncs (LCS)... +var getCommonSections = function(A, B, cmp, min_chunk){ cmp = cmp || function(a, b){ - return a === b || a == b } - index = index || [] + return a === b || a == b ? a : false } + + var index = index || [] + // XXX do we actually need this??? + min_chunk = min_chunk || 1 + + var _getCommonSections = function(a, b){ + // index... + var res = (index[a] || [])[b] + if(res != null){ + return res + } + + // collect common chunk... + var l = 0 + var chunk = { + A: a, + B: b, + chunk: [], + } + while(a+l < A.length && b+l < B.length){ + var e = cmp(A[a+l], B[b+l]) + if(!e){ + break + } + chunk.chunk.push(e) + l++ + } + // discard small chunks... + l = l < min_chunk ? 0 : l + + // get next chunks... + var L = A.length > a+l + min_chunk ? + _getCommonSections(l+a+1, l+b) + : [0] + var R = B.length > b+l + min_chunk ? + _getCommonSections(l+a, l+b+1) + : [0] + + // select the best chunk-set... + // NOTE: we maximize the number of elements in a chunk set then + // minimize the number of chunks per set... + var next = L[0] == R[0] ? + (L.length < R.length ? L : R) + : L[0] > R[0] ? + L + : R + var res = + // non-empty chunk and next... + next[0] > 0 && l > 0 ? + [l + next[0], chunk].concat(next.slice(1)) + // non-empty chunk and empty next... + : l > 0 ? + [l, chunk] + // empty chunk... + : next + + // index... + index[a] = index[a] || [] + index[a][b] = res - // index... - var res = (index[a] || [])[b] - if(res != null){ return res - } + } - // get common chunk... - var l = 0 - var chunk = [] - while(a+l < A.length - && b+l < B.length - && cmp(A[a+l], B[b+l])){ - chunk.push(A[a+l]) - l++ - } - // discard small chunks... - if(l < min_chunk){ - chunk = [] - l = 0 - } - - // get next chunks... - var L = A.length > a+l + min_chunk ? - getCommonSections( - A, B, - l+a+1, l+b, - min_chunk, cmp, index) - : [0] - var R = B.length > b+l + min_chunk ? - getCommonSections( - A, B, - l+a, l+b+1, - min_chunk, cmp, index) - : [0] - - // select the best chunk-set... - // NOTE: we maximize the number of elements in a chunk set then - // minimize the number of chunks per set... - var next = L[0] == R[0] ? - (L.length < R.length ? L : R) - : L[0] > R[0] ? - L - : R - var res = next[0] > 0 && l > 0 ? - [l + next[0], chunk].concat(next.slice(1)) - : l > 0 ? - [l, chunk] - : next - - // index... - index[a] = index[a] || [] - index[a][b] = res - - return res + return _getCommonSections(0, 0) } + + + +// XXX var getCommonSections2 = function(A, B, a, b, min_chunk, cmp){ a = a || 0 b = b || 0 @@ -200,6 +207,7 @@ var makeIndex = function(L){ }, new Map()) } +// XXX var getCommonSections3 = function(A, B){ var A_index = makeIndex(A) var B_index = makeIndex(B)