Skip to content

Commit f0cc359

Browse files
authored
Merge pull request #1 from gitkraken-jacobw/improved-memory
Back-port memory improvements
2 parents 502c2aa + 2be595a commit f0cc359

File tree

2 files changed

+50
-154
lines changed

2 files changed

+50
-154
lines changed

diff3.js

Lines changed: 2 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -24,83 +24,6 @@
2424

2525
var onp = require('./onp');
2626

27-
function longestCommonSubsequence(file1, file2) {
28-
var diff = new onp(file1, file2);
29-
diff.compose();
30-
var ses = diff.getses();
31-
32-
var root;
33-
var prev;
34-
var file1RevIdx = file1.length - 1,
35-
file2RevIdx = file2.length - 1;
36-
for (var i = ses.length - 1; i >= 0; --i) {
37-
if (ses[i].t === diff.SES_COMMON) {
38-
if (prev) {
39-
prev.chain = {
40-
file1index: file1RevIdx,
41-
file2index: file2RevIdx,
42-
chain: null
43-
};
44-
prev = prev.chain;
45-
} else {
46-
root = {
47-
file1index: file1RevIdx,
48-
file2index: file2RevIdx,
49-
chain: null
50-
};
51-
prev = root;
52-
}
53-
file1RevIdx--;
54-
file2RevIdx--;
55-
} else if (ses[i].t === diff.SES_DELETE) {
56-
file1RevIdx--;
57-
} else if (ses[i].t === diff.SES_ADD) {
58-
file2RevIdx--;
59-
}
60-
}
61-
62-
var tail = {
63-
file1index: -1,
64-
file2index: -1,
65-
chain: null
66-
};
67-
68-
if (!prev) {
69-
return tail;
70-
}
71-
72-
prev.chain = tail;
73-
74-
return root;
75-
}
76-
77-
function diffIndices(file1, file2) {
78-
// We apply the LCS to give a simple representation of the
79-
// offsets and lengths of mismatched chunks in the input
80-
// files. This is used by diff3_merge_indices below.
81-
82-
var result = [];
83-
var tail1 = file1.length;
84-
var tail2 = file2.length;
85-
86-
for (var candidate = longestCommonSubsequence(file1, file2); candidate !== null; candidate = candidate.chain) {
87-
var mismatchLength1 = tail1 - candidate.file1index - 1;
88-
var mismatchLength2 = tail2 - candidate.file2index - 1;
89-
tail1 = candidate.file1index;
90-
tail2 = candidate.file2index;
91-
92-
if (mismatchLength1 || mismatchLength2) {
93-
result.push({
94-
file1: [tail1 + 1, mismatchLength1],
95-
file2: [tail2 + 1, mismatchLength2]
96-
});
97-
}
98-
}
99-
100-
result.reverse();
101-
return result;
102-
}
103-
10427
function diff3MergeIndices(a, o, b) {
10528
// Given three files, A, O, and B, where both A and B are
10629
// independently derived from O, returns a fairly complicated
@@ -115,8 +38,8 @@ function diff3MergeIndices(a, o, b) {
11538
// (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
11639
var i;
11740

118-
var m1 = diffIndices(o, a);
119-
var m2 = diffIndices(o, b);
41+
var m1 = new onp(o, a).compose();
42+
var m2 = new onp(o, b).compose();
12043

12144
var hunks = [];
12245

onp.js

Lines changed: 48 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,9 @@ module.exports = function (a_, b_) {
3333
m = a.length,
3434
n = b.length,
3535
reverse = false,
36-
ed = null,
3736
offset = m + 1,
3837
path = [],
39-
pathposi = [],
40-
ses = [],
41-
lcs = "",
42-
SES_DELETE = -1,
43-
SES_COMMON = 0,
44-
SES_ADD = 1;
38+
pathposi = [];
4539

4640
var tmp1,
4741
tmp2;
@@ -59,92 +53,45 @@ module.exports = function (a_, b_) {
5953
}
6054
};
6155

62-
var P = function (x, y, k) {
56+
var P = function (startX, startY, endX, endY, r) {
6357
return {
64-
'x' : x,
65-
'y' : y,
66-
'k' : k,
67-
};
68-
};
69-
70-
var seselem = function (elem, t) {
71-
return {
72-
'elem' : elem,
73-
't' : t,
58+
startX,
59+
startY,
60+
endX,
61+
endY,
62+
r
7463
};
7564
};
7665

7766
var snake = function (k, p, pp) {
78-
var r, x, y;
67+
var r, x, y, startX, startY;
7968
if (p > pp) {
8069
r = path[k-1+offset];
8170
} else {
8271
r = path[k+1+offset];
8372
}
8473

85-
y = Math.max(p, pp);
86-
x = y - k;
74+
startY = y = Math.max(p, pp);
75+
startX = x = y - k;
8776
while (x < m && y < n && a[x] === b[y]) {
8877
++x;
8978
++y;
9079
}
9180

92-
path[k+offset] = pathposi.length;
93-
pathposi[pathposi.length] = new P(x, y, r);
94-
return y;
95-
};
96-
97-
var recordseq = function (epc) {
98-
var x_idx, y_idx, px_idx, py_idx, i;
99-
x_idx = y_idx = 1;
100-
px_idx = py_idx = 0;
101-
for (i=epc.length-1;i>=0;--i) {
102-
while(px_idx < epc[i].x || py_idx < epc[i].y) {
103-
if (epc[i].y - epc[i].x > py_idx - px_idx) {
104-
if (reverse) {
105-
ses[ses.length] = new seselem(b[py_idx], SES_DELETE);
106-
} else {
107-
ses[ses.length] = new seselem(b[py_idx], SES_ADD);
108-
}
109-
++y_idx;
110-
++py_idx;
111-
} else if (epc[i].y - epc[i].x < py_idx - px_idx) {
112-
if (reverse) {
113-
ses[ses.length] = new seselem(a[px_idx], SES_ADD);
114-
} else {
115-
ses[ses.length] = new seselem(a[px_idx], SES_DELETE);
116-
}
117-
++x_idx;
118-
++px_idx;
119-
} else {
120-
ses[ses.length] = new seselem(a[px_idx], SES_COMMON);
121-
lcs += a[px_idx];
122-
++x_idx;
123-
++y_idx;
124-
++px_idx;
125-
++py_idx;
126-
}
127-
}
81+
if (startX == x && startY == y) {
82+
path[k+offset] = r;
83+
} else {
84+
path[k+offset] = pathposi.length;
85+
pathposi[pathposi.length] = new P(startX, startY, x, y, r);
12886
}
87+
return y;
12988
};
13089

13190
init();
13291

13392
return {
134-
SES_DELETE : -1,
135-
SES_COMMON : 0,
136-
SES_ADD : 1,
137-
editdistance : function () {
138-
return ed;
139-
},
140-
getlcs : function () {
141-
return lcs;
142-
},
143-
getses : function () {
144-
return ses;
145-
},
14693
compose : function () {
147-
var delta, size, fp, p, r, epc, i, k;
94+
var delta, size, fp, p, r, i, k, lastStartX, lastStartY, result;
14895
delta = n - m;
14996
size = m + n + 3;
15097
fp = {};
@@ -167,13 +114,39 @@ module.exports = function (a_, b_) {
167114
ed = delta + 2 * p;
168115

169116
r = path[delta+offset];
170-
171-
epc = [];
117+
lastStartX = m;
118+
lastStartY = n;
119+
result = [];
172120
while (r !== -1) {
173-
epc[epc.length] = new P(pathposi[r].x, pathposi[r].y, null);
174-
r = pathposi[r].k;
121+
let elem = pathposi[r];
122+
if (m != elem.endX || n != elem.endY) {
123+
result.push({
124+
file1: [
125+
reverse ? elem.endY : elem.endX,
126+
reverse ? lastStartY - elem.endY : lastStartX - elem.endX
127+
],
128+
file2: [
129+
reverse ? elem.endX : elem.endY,
130+
reverse ? lastStartX - elem.endX : lastStartY - elem.endY
131+
]
132+
});
133+
}
134+
135+
lastStartX = elem.startX;
136+
lastStartY = elem.startY;
137+
138+
r = pathposi[r].r;
139+
}
140+
141+
if (lastStartX != 0 || lastStartY != 0) {
142+
result.push({
143+
file1: [0, reverse ? lastStartY : lastStartX],
144+
file2: [0, reverse ? lastStartX : lastStartY]
145+
})
175146
}
176-
recordseq(epc);
147+
148+
result.reverse();
149+
return result;
177150
}
178151
};
179152
};

0 commit comments

Comments
 (0)