Skip to content

Commit

Permalink
start with value caches
Browse files Browse the repository at this point in the history
  • Loading branch information
sgratzl committed Dec 15, 2018
1 parent 9c13abe commit 84215e6
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 7 deletions.
30 changes: 25 additions & 5 deletions src/provider/ScheduledTasks.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Column, {IDataRow, Ranking, IndicesArray, IGroup, IOrderedGroup, INumberColumn, IDateColumn, isCategoricalLikeColumn, isNumberColumn, isDateColumn, ICategoricalLikeColumn, UIntTypedArray} from '../model';
import {ARenderTasks, IRenderTaskExectutor, taskNow, MultiIndices, taskLater, TaskNow, TaskLater} from './tasks';
import {toIndexArray, getNumberOfBins, IAdvancedBoxPlotData, ICategoricalStatistics, IDateStatistics, IStatistics, ISortMessageRequest, ISortMessageResponse, WORKER_BLOB, IWorkerMessage} from '../internal';
import {toIndexArray, getNumberOfBins, IAdvancedBoxPlotData, ICategoricalStatistics, IDateStatistics, IStatistics, ISortMessageRequest, ISortMessageResponse, WORKER_BLOB, IWorkerMessage, normalizedStatsBuilder, ISetRefMessageRequest} from '../internal';
import {CompareLookup} from './sort';
import {ISequence} from '../internal/interable';
import {IRenderTask} from '../renderer/interfaces';
import TaskScheduler, {oneShotIterator, ABORTED} from '../internal/scheduler';
import TaskScheduler, {oneShotIterator, ABORTED, ANOTHER_ROUND} from '../internal/scheduler';
import {sortDirect} from './DirectRenderTasks';


Expand All @@ -17,9 +17,9 @@ const THREAD_CLEANUP_TIME = 2;
export class ScheduleRenderTasks extends ARenderTasks implements IRenderTaskExectutor {

private readonly cache = new Map<string, IRenderTask<any>>();
private readonly valueCacheData = new Map<string, Float32Array | UIntTypedArray>();
private readonly tasks = new TaskScheduler();
private readonly workerPool: Worker[] = [];
private readonly activeWorkers= new Set<Worker>();
private cleanUpWorkerTimer: number = -1;
private workerTaskCounter = 0;

Expand Down Expand Up @@ -222,6 +222,7 @@ export class ScheduleRenderTasks extends ARenderTasks implements IRenderTaskExec
}
}


groupCompare(ranking: Ranking, group: IGroup, rows: IndicesArray) {
// TODO value cache
return taskLater(this.tasks.push(`r${ranking.id}:${group.name}`, () => ranking.toGroupCompareValue(this.byOrder(rows), group)));
Expand Down Expand Up @@ -392,13 +393,18 @@ export class ScheduleRenderTasks extends ARenderTasks implements IRenderTaskExec
}

if (this.workerPool.length > 0) {
return this.workerPool.shift()!;
const w = this.workerPool.shift()!;
this.activeWorkers.add(w);
return w;
}
return new Worker(WORKER_BLOB);
const w = new Worker(WORKER_BLOB);
this.activeWorkers.add(w);
return w;
}

private checkInWorker(worker: Worker) {
this.workerPool.push(worker);
this.activeWorkers.delete(worker);

if (this.workerPool.length >= MAX_WORKER_THREADS) {
this.workerPool.splice(0, MAX_WORKER_THREADS).forEach((w) => w.terminate());
Expand Down Expand Up @@ -466,4 +472,18 @@ export class ScheduleRenderTasks extends ARenderTasks implements IRenderTaskExec
return v ? v[dataIndex] : undefined;
};
}

protected setValueCacheData(key: string, value: Float32Array | UIntTypedArray | null) {
super.setValueCacheData(key, value);
const msg: ISetRefMessageRequest = {
uid: this.workerTaskCounter++,
type: 'setRef',
ref: key,
data: value
};
for (const w of this.workerPool) {
w.postMessage(msg);
}
this.activeWorkers.forEach((w) => w.postMessage(msg));
}
}
41 changes: 39 additions & 2 deletions src/provider/tasks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {abortAble, abortAbleAll, IAbortAblePromise} from 'lineupengine';
import {IForEachAble, lazySeq, ISequence} from '../internal/interable';
import {boxplotBuilder, categoricalStatsBuilder, dateStatsBuilder, IAdvancedBoxPlotData, ICategoricalStatistics, IDateStatistics, IStatistics, normalizedStatsBuilder} from '../internal/math';
import {boxplotBuilder, categoricalStatsBuilder, dateStatsBuilder, IAdvancedBoxPlotData, ICategoricalStatistics, IDateStatistics, IStatistics, normalizedStatsBuilder, getNumberOfBins} from '../internal/math';
import {ANOTHER_ROUND} from '../internal/scheduler';
import {CategoricalColumn, DateColumn, ICategoricalLikeColumn, IDataRow, IDateColumn, IGroup, ImpositionCompositeColumn, IndicesArray, INumberColumn, NumberColumn, OrdinalColumn, Ranking, IOrderedGroup} from '../model';
import {CategoricalColumn, DateColumn, ICategoricalLikeColumn, IDataRow, IDateColumn, IGroup, ImpositionCompositeColumn, IndicesArray, INumberColumn, NumberColumn, OrdinalColumn, Ranking, IOrderedGroup, UIntTypedArray} from '../model';
import Column, {ICompareValue} from '../model/Column';
import {IRenderTask, IRenderTasks} from '../renderer/interfaces';
import {CompareLookup} from './sort';
Expand Down Expand Up @@ -100,6 +100,8 @@ export class MultiIndices {
* @internal
*/
export class ARenderTasks {
protected readonly valueCacheData = new Map<string, Float32Array | UIntTypedArray>();

protected readonly byIndex = (i: number) => this.data[i];

constructor(protected data: IDataRow[] = []) {
Expand All @@ -115,6 +117,33 @@ export class ARenderTasks {
return lazySeq(indices).map((i) => acc(this.data[i]));
}

private buildNumberCache(col: INumberColumn): Iterator<IStatistics | null> {
let i = 0;
const chunkSize = 100;
const valueCache = new Float32Array(this.data.length);
const builder = normalizedStatsBuilder(getNumberOfBins(this.data.length));
const data = this.data;

const next = () => {
let chunkCounter = chunkSize;
for (; i < data.length && chunkCounter > 0; ++i, --chunkCounter) {
builder.push(valueCache[i] = col.getNumber(data[i]));
i++;
}
if (i < data.length) {
// need another round
return ANOTHER_ROUND;
}
// done
this.setValueCacheData(col.id, valueCache);
return {
done: true,
value: builder.build()
};
};
return {next};
}

private builder<T, BR, B extends {push: (v: T) => void, build: () => BR}, R = BR>(builder: B, order: IndicesArray | null | MultiIndices, acc: (row: IDataRow) => T, build?: (r: BR) => R): Iterator<R | null> {
let i = 0;
let o = 0;
Expand Down Expand Up @@ -200,4 +229,12 @@ export class ARenderTasks {
return this.builderForEach(b, order, (row: IDataRow) => col.iterCategory(row), build);
}


protected setValueCacheData(key: string, value: Float32Array | UIntTypedArray | null) {
if (value == null) {
this.valueCacheData.delete(key);
} else {
this.valueCacheData.set(key, value);
}
}
}

0 comments on commit 84215e6

Please sign in to comment.