提交 537deb52 编写于 作者: P Phil Price

Change document tracker to be opted out of per callee origin.

上级 aba193c3
......@@ -9,11 +9,12 @@ import { loadMessageBundle } from 'vscode-nls';
const localize = loadMessageBundle();
export default class MergeConflictCodeLensProvider implements vscode.CodeLensProvider, vscode.Disposable {
private codeLensRegistrationHandle: vscode.Disposable | null;
private config: interfaces.IExtensionConfiguration;
private tracker: interfaces.IDocumentMergeConflictTracker;
constructor(private context: vscode.ExtensionContext, private tracker: interfaces.IDocumentMergeConflictTracker) {
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
this.tracker = trackerService.createTracker('codelens');
}
begin(config: interfaces.IExtensionConfiguration) {
......
......@@ -29,8 +29,10 @@ enum NavigationDirection {
export default class CommandHandler implements vscode.Disposable {
private disposables: vscode.Disposable[] = [];
private tracker: interfaces.IDocumentMergeConflictTracker;
constructor(private context: vscode.ExtensionContext, private tracker: interfaces.IDocumentMergeConflictTracker) {
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
this.tracker = trackerService.createTracker('commands');
}
begin() {
......
......@@ -8,29 +8,70 @@ import { MergeConflictParser } from './mergeConflictParser';
import * as interfaces from './interfaces';
import { Delayer } from './delayer';
export default class DocumentMergeConflictTracker implements vscode.Disposable, interfaces.IDocumentMergeConflictTracker {
class ScanTask {
public origins: Set<string> = new Set<string>();
public delayTask: Delayer<interfaces.IDocumentMergeConflict[]>;
private cache: Map<string, Delayer<interfaces.IDocumentMergeConflict[]>> = new Map();
private delayExpireTime: number = 150;
constructor(delayTime: number, initialOrigin: string) {
this.origins.add(initialOrigin);
this.delayTask = new Delayer<interfaces.IDocumentMergeConflict[]>(delayTime);
}
public addOrigin(name: string): boolean {
if (this.origins.has(name)) {
return false;
}
return false;
}
public hasOrigin(name: string): boolean {
return this.origins.has(name);
}
}
class OriginDocumentMergeConflictTracker implements interfaces.IDocumentMergeConflictTracker {
constructor(private parent: DocumentMergeConflictTracker, private origin: string) {
}
getConflicts(document: vscode.TextDocument): PromiseLike<interfaces.IDocumentMergeConflict[]> {
return this.parent.getConflicts(document, this.origin);
}
isPending(document: vscode.TextDocument): boolean {
return this.parent.isPending(document, this.origin);
}
forget(document: vscode.TextDocument) {
this.parent.forget(document);
}
}
export default class DocumentMergeConflictTracker implements vscode.Disposable, interfaces.IDocumentMergeConflictTrackerService {
private cache: Map<string, ScanTask> = new Map();
private delayExpireTime: number = 300;
getConflicts(document: vscode.TextDocument, origin: string): PromiseLike<interfaces.IDocumentMergeConflict[]> {
// Attempt from cache
let key = this.getCacheKey(document);
if (!key) {
// Document doesnt have a uri, can't cache it, so return
return Promise.resolve(this.getConflictsOrEmpty(document));
return Promise.resolve(this.getConflictsOrEmpty(document, [origin]));
}
let cacheItem = this.cache.get(key);
if (!cacheItem) {
cacheItem = new Delayer<interfaces.IDocumentMergeConflict[]>(this.delayExpireTime);
cacheItem = new ScanTask(this.delayExpireTime, origin);
this.cache.set(key, cacheItem);
}
else {
cacheItem.addOrigin(origin);
}
return cacheItem.trigger(() => {
let conflicts = this.getConflictsOrEmpty(document);
return cacheItem.delayTask.trigger(() => {
let conflicts = this.getConflictsOrEmpty(document, Array.from(cacheItem!.origins));
if (this.cache) {
this.cache.delete(key!);
......@@ -40,6 +81,29 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
});
}
isPending(document: vscode.TextDocument, origin: string): boolean {
if (!document) {
return false;
}
let key = this.getCacheKey(document);
if (!key) {
return false;
}
var task = this.cache.get(key);
if (!task) {
return false;
}
return task.hasOrigin(origin);
}
createTracker(origin: string): interfaces.IDocumentMergeConflictTracker {
return new OriginDocumentMergeConflictTracker(this, origin);
}
forget(document: vscode.TextDocument) {
let key = this.getCacheKey(document);
......@@ -52,12 +116,12 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
this.cache.clear();
}
private getConflictsOrEmpty(document: vscode.TextDocument): interfaces.IDocumentMergeConflict[] {
private getConflictsOrEmpty(document: vscode.TextDocument, origins: string[]): interfaces.IDocumentMergeConflict[] {
let stepStart = process.hrtime();
const containsConflict = MergeConflictParser.containsConflict(document);
let stepEnd = process.hrtime(stepStart);
console.info('%s -> Check document execution time: %dms', document.uri.toString(), stepEnd[1] / 1000000);
console.info('[%s] %s -> Check document execution time: %dms', origins.join(', '), document.uri.toString(), stepEnd[1] / 1000000);
if (!containsConflict) {
return [];
......@@ -67,7 +131,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
const conflicts = MergeConflictParser.scanDocument(document);
stepEnd = process.hrtime(stepStart);
console.info('%s -> Find conflict regions execution time: %dms', document.uri.toString(), stepEnd[1] / 1000000);
console.info('[%s] %s -> Find conflict regions execution time: %dms', origins.join(', '), document.uri.toString(), stepEnd[1] / 1000000);
return conflicts;
}
......@@ -79,4 +143,5 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
return null;
}
}
\ No newline at end of file
}
......@@ -37,5 +37,11 @@ export interface IDocumentMergeConflictDescriptor {
export interface IDocumentMergeConflictTracker {
getConflicts(document: vscode.TextDocument): PromiseLike<IDocumentMergeConflict[]>;
isPending(document: vscode.TextDocument): boolean;
forget(document: vscode.TextDocument);
}
export interface IDocumentMergeConflictTrackerService {
createTracker(origin: string): IDocumentMergeConflictTracker;
forget(document: vscode.TextDocument);
}
......@@ -17,8 +17,10 @@ export default class MergeDectorator implements vscode.Disposable {
private currentColorRgb = `32,200,94`;
private incomingColorRgb = `24,134,255`;
private config: interfaces.IExtensionConfiguration;
private tracker: interfaces.IDocumentMergeConflictTracker;
constructor(private context: vscode.ExtensionContext, private tracker: interfaces.IDocumentMergeConflictTracker) {
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
this.tracker = trackerService.createTracker('decorator');
}
begin(config: interfaces.IExtensionConfiguration) {
......@@ -149,10 +151,14 @@ export default class MergeDectorator implements vscode.Disposable {
return;
}
// If we have a pending scan from the same origin, exit early.
if (this.tracker.isPending(editor.document)) {
return;
}
let conflicts = await this.tracker.getConflicts(editor.document);
if (conflicts.length === 0) {
// TODO: Remove decorations
this.removeDecorations(editor);
return;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册