Optimized parsers for speed & memory usage

Switches to lazy parsing of diff chunks
This commit is contained in:
Eric Amodio
2017-06-10 00:16:46 -04:00
parent eeff31cf27
commit e6316400f0
16 changed files with 343 additions and 340 deletions

View File

@@ -1,4 +1,5 @@
'use strict';
import { Iterables, Strings } from '../../system';
import { GitDiff, GitDiffChunk, GitDiffLine } from './../git';
const unifiedDiffRegex = /^@@ -([\d]+),([\d]+) [+]([\d]+),([\d]+) @@([\s\S]*?)(?=^@@)/gm;
@@ -19,44 +20,7 @@ export class GitDiffParser {
const currentStart = +match[3];
const chunk = match[5];
const lines = chunk.split('\n').slice(1);
const current: (GitDiffLine | undefined)[] = [];
const previous: (GitDiffLine | undefined)[] = [];
for (const l of lines) {
switch (l[0]) {
case '+':
current.push({
line: ` ${l.substring(1)}`,
state: 'added'
});
previous.push(undefined);
break;
case '-':
current.push(undefined);
previous.push({
line: ` ${l.substring(1)}`,
state: 'removed'
});
break;
default:
current.push({ line: l, state: 'unchanged' });
previous.push({ line: l, state: 'unchanged' });
break;
}
}
chunks.push({
chunk: debug ? chunk : undefined,
current: current,
currentStart: currentStart,
currentEnd: currentStart + +match[4],
previous: previous,
previousStart: previousStart,
previousEnd: previousStart + +match[2]
});
chunks.push(new GitDiffChunk(chunk, { start: currentStart, end: currentStart + +match[4] }, { start: previousStart, end: previousStart + +match[2] }));
} while (match != null);
if (!chunks.length) return undefined;
@@ -67,4 +31,37 @@ export class GitDiffParser {
} as GitDiff;
return diff;
}
static parseChunk(chunk: string): [(GitDiffLine | undefined)[], (GitDiffLine | undefined)[]] {
const lines = Iterables.skip(Strings.lines(chunk), 1);
const current: (GitDiffLine | undefined)[] = [];
const previous: (GitDiffLine | undefined)[] = [];
for (const l of lines) {
switch (l[0]) {
case '+':
current.push({
line: ` ${l.substring(1)}`,
state: 'added'
});
previous.push(undefined);
break;
case '-':
current.push(undefined);
previous.push({
line: ` ${l.substring(1)}`,
state: 'removed'
});
break;
default:
current.push({ line: l, state: 'unchanged' });
previous.push({ line: l, state: 'unchanged' });
break;
}
}
return [current, previous];
}
}