Skip to content
Snippets Groups Projects
Commit 982b18bd authored by David Sehnal's avatar David Sehnal
Browse files

Binary column windows, make all column functions closures

parent 16e66b83
No related branches found
No related tags found
No related merge requests found
...@@ -8,12 +8,13 @@ import * as Column from '../../common/column' ...@@ -8,12 +8,13 @@ import * as Column from '../../common/column'
import * as Data from '../data-model' import * as Data from '../data-model'
import { EncodedColumn } from './encoding' import { EncodedColumn } from './encoding'
import decode from './decoder' import decode from './decoder'
import { isTypedArray, typedArrayWindow } from '../../common/binary/column'
import { parseInt as fastParseInt, parseFloat as fastParseFloat } from '../../common/text/number-parser' import { parseInt as fastParseInt, parseFloat as fastParseFloat } from '../../common/text/number-parser'
export default function Field(column: EncodedColumn): Data.Field { export default function Field(column: EncodedColumn): Data.Field {
const mask = column.mask ? decode(column.mask) as number[] : void 0; const mask = column.mask ? decode(column.mask) as number[] : void 0;
const data = decode(column.data); const data = decode(column.data);
const isNumeric = (data as any).buffer && (data as any).byteLength && (data as any).BYTES_PER_ELEMENT; const isNumeric = isTypedArray(data);
const str: Data.Field['str'] = isNumeric const str: Data.Field['str'] = isNumeric
? mask ? mask
...@@ -45,9 +46,13 @@ export default function Field(column: EncodedColumn): Data.Field { ...@@ -45,9 +46,13 @@ export default function Field(column: EncodedColumn): Data.Field {
float, float,
presence, presence,
areValuesEqual: (rowA, rowB) => data[rowA] === data[rowB], areValuesEqual: (rowA, rowB) => data[rowA] === data[rowB],
stringEquals(row, v) { return str(row) === v; }, stringEquals: (row, v) => str(row) === v,
toStringArray(params) { return Column.createAndFillArray(rowCount, str, params); }, toStringArray: params => Column.createAndFillArray(rowCount, str, params),
toIntArray(params) { return Column.createAndFillArray(rowCount, int, params); }, toIntArray: isNumeric
toFloatArray(params) { return Column.createAndFillArray(rowCount, float, params); } ? params => typedArrayWindow(data, params)
: params => Column.createAndFillArray(rowCount, int, params),
toFloatArray: isNumeric
? params => typedArrayWindow(data, params)
: params => Column.createAndFillArray(rowCount, float, params)
}; };
} }
\ No newline at end of file
...@@ -44,7 +44,7 @@ export default function CifTextField(tokens: Tokens, rowCount: number): Data.Fie ...@@ -44,7 +44,7 @@ export default function CifTextField(tokens: Tokens, rowCount: number): Data.Fie
float, float,
presence, presence,
areValuesEqual: TokenColumn.areValuesEqualProvider(tokens), areValuesEqual: TokenColumn.areValuesEqualProvider(tokens),
stringEquals(row, v) { stringEquals: (row, v) => {
const s = indices[2 * row]; const s = indices[2 * row];
const value = v || ''; const value = v || '';
if (!value && presence(row) !== Data.ValuePresence.Present) return true; if (!value && presence(row) !== Data.ValuePresence.Present) return true;
...@@ -55,8 +55,8 @@ export default function CifTextField(tokens: Tokens, rowCount: number): Data.Fie ...@@ -55,8 +55,8 @@ export default function CifTextField(tokens: Tokens, rowCount: number): Data.Fie
} }
return true; return true;
}, },
toStringArray(params) { return Column.createAndFillArray(rowCount, str, params); }, toStringArray: params => Column.createAndFillArray(rowCount, str, params),
toIntArray(params) { return Column.createAndFillArray(rowCount, int, params); }, toIntArray: params => Column.createAndFillArray(rowCount, int, params),
toFloatArray(params) { return Column.createAndFillArray(rowCount, float, params); } toFloatArray: params => Column.createAndFillArray(rowCount, float, params)
} }
} }
\ No newline at end of file
/**
* Copyright (c) 2017 molio contributors, licensed under MIT, See LICENSE file for more info.
*
* @author David Sehnal <david.sehnal@gmail.com>
*/
import { getArrayBounds, ToArrayParams } from '../column'
export function isTypedArray(data: any) {
return data.buffer && typeof data.byteLength === 'number' && data.BYTES_PER_ELEMENT;
}
export function typedArrayWindow(data: any, params?: ToArrayParams): ArrayLike<number> {
const { constructor, buffer, length, byteOffset, BYTES_PER_ELEMENT } = data;
const { start, end } = getArrayBounds(length, params);
if (start === 0 && end === length) return data;
return new constructor(buffer, byteOffset + BYTES_PER_ELEMENT * start, Math.min(length, end - start));
}
\ No newline at end of file
...@@ -48,13 +48,18 @@ export function UndefinedColumn<T extends ColumnType>(rowCount: number, type: T) ...@@ -48,13 +48,18 @@ export function UndefinedColumn<T extends ColumnType>(rowCount: number, type: T)
} }
} }
/** A helped function for Column.toArray */
export function getArrayBounds(rowCount: number, params?: ToArrayParams) {
const start = params && typeof params.start !== 'undefined' ? Math.max(Math.min(params.start, rowCount - 1), 0) : 0;
const end = params && typeof params.end !== 'undefined' ? Math.min(params.end, rowCount) : rowCount;
return { start, end };
}
/** A helped function for Column.toArray */ /** A helped function for Column.toArray */
export function createArray(rowCount: number, params?: ToArrayParams) { export function createArray(rowCount: number, params?: ToArrayParams) {
const { array, start, end } = params || ({} as ToArrayParams); const c = params && typeof params.array !== 'undefined' ? params.array : Array;
const c = typeof array !== 'undefined' ? array : Array; const { start, end } = getArrayBounds(rowCount, params);
const s = typeof start !== 'undefined' ? Math.max(Math.min(start, rowCount - 1), 0) : 0; return { array: new c(end - start) as any[], start, end };
const e = typeof end !== 'undefined' ? Math.min(end, rowCount) : rowCount;
return { array: new c(e - s) as any[], start: s, end: e };
} }
/** A helped function for Column.toArray */ /** A helped function for Column.toArray */
......
...@@ -45,11 +45,9 @@ export function FixedColumn<T extends ColumnType>(lines: Tokens, offset: number, ...@@ -45,11 +45,9 @@ export function FixedColumn<T extends ColumnType>(lines: Tokens, offset: number,
isDefined: true, isDefined: true,
rowCount, rowCount,
value, value,
isValueDefined(row) { return true; }, isValueDefined: row => true,
toArray(params) { return createAndFillArray(rowCount, value, params); }, toArray: params => createAndFillArray(rowCount, value, params),
stringEquals(row, v) { return value(row) === v; }, stringEquals: (row, v) => value(row) === v,
areValuesEqual(rowA, rowB) { areValuesEqual: (rowA, rowB) => value(rowA) === value(rowB)
return value(rowA) === value(rowB);
}
}; };
} }
\ No newline at end of file
...@@ -33,9 +33,9 @@ export function TokenColumn<T extends ColumnType>(tokens: Tokens, type: T): Colu ...@@ -33,9 +33,9 @@ export function TokenColumn<T extends ColumnType>(tokens: Tokens, type: T): Colu
isDefined: true, isDefined: true,
rowCount, rowCount,
value, value,
isValueDefined(row) { return true; }, isValueDefined: row => true,
toArray(params) { return createAndFillArray(rowCount, value, params); }, toArray: params => createAndFillArray(rowCount, value, params),
stringEquals(row, v) { stringEquals: (row, v) => {
const s = indices[2 * row]; const s = indices[2 * row];
const value = v || ''; const value = v || '';
const len = value.length; const len = value.length;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* @author David Sehnal <david.sehnal@gmail.com> * @author David Sehnal <david.sehnal@gmail.com>
*/ */
import * as BinaryColumn from '../common/binary/column'
import FixedColumn from '../common/text/column/fixed' import FixedColumn from '../common/text/column/fixed'
import TokenColumn from '../common/text/column/token' import TokenColumn from '../common/text/column/token'
import { ColumnType } from '../common/column' import { ColumnType } from '../common/column'
...@@ -60,3 +61,17 @@ describe('token text column', () => { ...@@ -60,3 +61,17 @@ describe('token text column', () => {
expect(col1.value(2)).toBe(1); expect(col1.value(2)).toBe(1);
}) })
}); });
describe('binary column', () => {
it('window works', () => {
const xs = new Float64Array([1, 2, 3, 4]);
const w1 = BinaryColumn.typedArrayWindow(xs, { start: 1 });
const w2 = BinaryColumn.typedArrayWindow(xs, { start: 2, end: 4 });
expect(w1.length).toBe(3);
for (let i = 0; i < w1.length; i++) expect(w1[i]).toBe(xs[i + 1]);
expect(w2.length).toBe(2);
for (let i = 0; i < w2.length; i++) expect(w2[i]).toBe(xs[i + 2]);
});
})
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment