Skip to content

Commit

Permalink
prepare sort worker
Browse files Browse the repository at this point in the history
  • Loading branch information
sgratzl committed Nov 17, 2018
1 parent 1263505 commit 424337a
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 10 deletions.
11 changes: 4 additions & 7 deletions src/provider/LocalDataProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Column, {
import Ranking from '../model/Ranking';
import ACommonDataProvider from './ACommonDataProvider';
import {IDataProviderOptions, IStatsBuilder} from './interfaces';
import {sortComplex, sort2indices} from './sort';
import {local, ISortWorker, sortComplex} from './sort';
import {range} from 'd3-array';
import ADataProvider from './ADataProvider';

Expand Down Expand Up @@ -50,6 +50,7 @@ export default class LocalDataProvider extends ACommonDataProvider {

private _dataRows: IDataRow[];
private filter: ((row: IDataRow) => boolean) | null = null;
private sortWorker: ISortWorker = local;

constructor(private _data: any[], columns: IColumnDesc[] = [], options: Partial<ILocalDataProviderOptions & IDataProviderOptions> = {}) {
super(columns, options);
Expand Down Expand Up @@ -188,15 +189,11 @@ export default class LocalDataProvider extends ACommonDataProvider {
return [];
}

const types = ranking.toCompareValueType();
const types = isSortedBy ?ranking.toCompareValueType() : undefined;

return Promise.all(Array.from(groups.values()).map((g) => {
const group = g.group;
return Promise.resolve(g.rows)
// sort -> worker
.then((rows) => !isSortedBy ? rows : sortComplex(rows, types))
// to indices -> worker
.then((rows) => sort2indices(rows, this._data.length))
return this.sortWorker.sort(this._data.length, g.rows, types)
// to group info
.then(({order, index2pos}) => {
const o: IOrderedGroup = Object.assign({order, index2pos}, group);
Expand Down
23 changes: 20 additions & 3 deletions src/provider/sort.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {ICompareValue, ECompareValueType} from '../model/Column';
import {FIRST_IS_NAN, FIRST_IS_MISSING} from '../model/missing';
import {chooseByLength} from '../model';
import {chooseByLength, IndicesArray} from '../model';


const missingFloat = FIRST_IS_NAN > 0 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
const missingInt = FIRST_IS_MISSING > 0 ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
Expand Down Expand Up @@ -86,10 +87,9 @@ export function sortComplex<T extends {sort: ICompareValue[]}>(arr: T[], compara
return 0;
});
}
return arr;
}

export function sort2indices(arr: {i: number}[], rawLength: number) {
function sort2indices(arr: {i: number}[], rawLength: number) {
//store the ranking index and create an argsort version, i.e. rank 0 -> index i
const order = chooseByLength(arr.length);
const index2pos = chooseByLength(rawLength);
Expand All @@ -101,3 +101,20 @@ export function sort2indices(arr: {i: number}[], rawLength: number) {
}
return {order, index2pos};
}

function sort(rawLength: number, arr: {i: number, sort: ICompareValue[]}[], comparators?: {asc: boolean, v: ECompareValueType}[]) {
const a = comparators ? sortComplex(arr, comparators) : arr;
const r = sort2indices(a, rawLength);

return Promise.resolve(r);
}

export interface ISortWorker {
sort(rawLength: number, arr: {i: number, sort: ICompareValue[]}[], comparators?: {asc: boolean, v: ECompareValueType}[]): Promise<{order: IndicesArray, index2pos: IndicesArray}>;
terminate(): void;
}

export const local: ISortWorker = {
sort,
terminate: () => undefined
};
33 changes: 33 additions & 0 deletions src/provider/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

export interface IPoorManWorkerScopeEventMap {
message: MessageEvent;
error: ErrorEvent;
}

export interface IPoorManWorkerScope {
onmessage: ((this: IPoorManWorkerScope, ev: MessageEvent) => any) | null;
onerror: ((this: IPoorManWorkerScope, ev: ErrorEvent) => any) | null;
close(): void;
postMessage(message: any, transfer?: Transferable[]): void;
addEventListener<K extends keyof IPoorManWorkerScopeEventMap>(type: K, listener: (this: IPoorManWorkerScope, ev: IPoorManWorkerScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof IPoorManWorkerScopeEventMap>(type: K, listener: (this: IPoorManWorkerScope, ev: IPoorManWorkerScopeEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
}

function workerMain(self: IPoorManWorkerScope) {
self.addEventListener('message', (evt) => {
self.postMessage(`Worker: ${evt.data} - Polo`);
});
}

function toFunctionBody(f: Function) {
const source = f.toString();
return source.slice(source.indexOf('{') + 1, source.lastIndexOf('}'));
}

export function createWorker(fs: Function[]) {
const sources: string[] = fs.map(toFunctionBody);

const blob = new Blob(sources, {type: 'application/javascript'});

return new Worker(URL.createObjectURL(blob));
}

0 comments on commit 424337a

Please sign in to comment.