@thi.ng/column-store 0.9.0 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.d.ts +8 -2
- package/api.js +2 -0
- package/columns/acolumn.d.ts +1 -0
- package/columns/dict-tuple.d.ts +1 -0
- package/columns/dict-tuple.js +5 -0
- package/columns/dict.d.ts +1 -0
- package/columns/dict.js +5 -0
- package/columns/plain.d.ts +1 -0
- package/columns/plain.js +4 -0
- package/columns/tuple.d.ts +1 -0
- package/columns/tuple.js +4 -0
- package/columns/typedarray.d.ts +1 -0
- package/columns/typedarray.js +6 -1
- package/columns/vector.d.ts +2 -1
- package/columns/vector.js +6 -1
- package/internal/serialize.d.ts +1 -1
- package/package.json +2 -2
- package/query.d.ts +1 -1
- package/query.js +31 -27
- package/table.d.ts +7 -3
- package/table.js +22 -0
package/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FloatType, Fn3, IntType, Maybe, Predicate, UintType } from "@thi.ng/api";
|
|
1
|
+
import type { FloatType, Fn3, IClear, IntType, Maybe, Predicate, UintType } from "@thi.ng/api";
|
|
2
2
|
import type { BitmapIndex } from "./bitmap.js";
|
|
3
3
|
import type { QueryCtx } from "./query.js";
|
|
4
4
|
import type { Table } from "./table.js";
|
|
@@ -84,7 +84,7 @@ export declare const FLAG_UNIQUE: number;
|
|
|
84
84
|
export declare const FLAG_RLE: number;
|
|
85
85
|
/** @internal */
|
|
86
86
|
export declare const LIMITS: Record<NumericType, [number, number]>;
|
|
87
|
-
export interface IColumn extends Iterable<any
|
|
87
|
+
export interface IColumn extends Iterable<any>, IClear {
|
|
88
88
|
bitmap?: BitmapIndex;
|
|
89
89
|
readonly isArray: boolean;
|
|
90
90
|
load(spec: SerializedColumn): void;
|
|
@@ -192,4 +192,10 @@ export interface QueryTermOpSpec {
|
|
|
192
192
|
*/
|
|
193
193
|
fn: QueryTermOp;
|
|
194
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* Initial capacity for typedarray and vector columns
|
|
197
|
+
*
|
|
198
|
+
* @internal
|
|
199
|
+
*/
|
|
200
|
+
export declare const INITIAL_CAPACITY = 8;
|
|
195
201
|
//# sourceMappingURL=api.d.ts.map
|
package/api.js
CHANGED
|
@@ -17,11 +17,13 @@ const LIMITS = {
|
|
|
17
17
|
f32: [-Infinity, Infinity],
|
|
18
18
|
f64: [-Infinity, Infinity]
|
|
19
19
|
};
|
|
20
|
+
const INITIAL_CAPACITY = 8;
|
|
20
21
|
export {
|
|
21
22
|
FLAG_BITMAP,
|
|
22
23
|
FLAG_DICT,
|
|
23
24
|
FLAG_RLE,
|
|
24
25
|
FLAG_UNIQUE,
|
|
26
|
+
INITIAL_CAPACITY,
|
|
25
27
|
LIMITS,
|
|
26
28
|
ONE_PLUS,
|
|
27
29
|
OPTIONAL,
|
package/columns/acolumn.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare abstract class AColumn<T extends Row = Row> implements IColumn {
|
|
|
13
13
|
constructor(id: ColumnID<T>, table: Table<T>);
|
|
14
14
|
[Symbol.iterator](): Generator<any, void, unknown>;
|
|
15
15
|
reindex(): void;
|
|
16
|
+
abstract clear(): void;
|
|
16
17
|
abstract load(spec: SerializedColumn): void;
|
|
17
18
|
abstract validate(value: any): boolean;
|
|
18
19
|
abstract setRow(i: number, value: any): void;
|
package/columns/dict-tuple.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class DictTupleColumn<T extends Row = Row> extends AColumn<T> {
|
|
|
5
5
|
values: (number[] | null)[];
|
|
6
6
|
dict: BidirIndex<any>;
|
|
7
7
|
readonly isArray = true;
|
|
8
|
+
clear(): void;
|
|
8
9
|
load({ dict, values }: SerializedColumn): void;
|
|
9
10
|
reindex(): void;
|
|
10
11
|
encode(value: any): (number | null)[];
|
package/columns/dict-tuple.js
CHANGED
|
@@ -9,6 +9,11 @@ class DictTupleColumn extends AColumn {
|
|
|
9
9
|
values = [];
|
|
10
10
|
dict = new BidirIndex();
|
|
11
11
|
isArray = true;
|
|
12
|
+
clear() {
|
|
13
|
+
this.values = [];
|
|
14
|
+
this.dict.clear();
|
|
15
|
+
this.bitmap?.clear();
|
|
16
|
+
}
|
|
12
17
|
load({ dict, values }) {
|
|
13
18
|
this.values = values;
|
|
14
19
|
super.loadDict(dict);
|
package/columns/dict.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class DictColumn<T extends Row = Row> extends AColumn<T> {
|
|
|
5
5
|
values: (number | null)[];
|
|
6
6
|
dict: BidirIndex<any>;
|
|
7
7
|
readonly isArray = false;
|
|
8
|
+
clear(): void;
|
|
8
9
|
load({ dict, values }: SerializedColumn): void;
|
|
9
10
|
reindex(): void;
|
|
10
11
|
encode(value: any): number | null;
|
package/columns/dict.js
CHANGED
|
@@ -11,6 +11,11 @@ class DictColumn extends AColumn {
|
|
|
11
11
|
values = [];
|
|
12
12
|
dict = new BidirIndex();
|
|
13
13
|
isArray = false;
|
|
14
|
+
clear() {
|
|
15
|
+
this.values = [];
|
|
16
|
+
this.dict.clear();
|
|
17
|
+
this.bitmap?.clear();
|
|
18
|
+
}
|
|
14
19
|
load({ dict, values }) {
|
|
15
20
|
this.values = this.spec.flags & FLAG_RLE ? this.spec.cardinality[0] === 0 && this.spec.default == null ? decodeSimple(values) : Array.from(decodeBinary(values)) : values;
|
|
16
21
|
super.loadDict(dict);
|
package/columns/plain.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { AColumn } from "./acolumn.js";
|
|
|
3
3
|
export declare class PlainColumn<T extends Row = Row> extends AColumn<T> {
|
|
4
4
|
values: any[];
|
|
5
5
|
readonly isArray = false;
|
|
6
|
+
clear(): void;
|
|
6
7
|
load({ values }: SerializedColumn): void;
|
|
7
8
|
ensureRows(): void;
|
|
8
9
|
validate(value: any): boolean;
|
package/columns/plain.js
CHANGED
|
@@ -7,6 +7,10 @@ import { AColumn } from "./acolumn.js";
|
|
|
7
7
|
class PlainColumn extends AColumn {
|
|
8
8
|
values = [];
|
|
9
9
|
isArray = false;
|
|
10
|
+
clear() {
|
|
11
|
+
this.values = [];
|
|
12
|
+
this.bitmap?.clear();
|
|
13
|
+
}
|
|
10
14
|
load({ values }) {
|
|
11
15
|
this.values = this.spec.flags & FLAG_RLE ? Array.from(decodeSimple(values)) : values;
|
|
12
16
|
this.reindex();
|
package/columns/tuple.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { AColumn } from "./acolumn.js";
|
|
|
4
4
|
export declare class TupleColumn<T extends Row = Row> extends AColumn<T> {
|
|
5
5
|
values: Nullable<number[]>[];
|
|
6
6
|
readonly isArray = true;
|
|
7
|
+
clear(): void;
|
|
7
8
|
load(spec: SerializedColumn): void;
|
|
8
9
|
encode(value: any): any[];
|
|
9
10
|
validate(value: any): boolean;
|
package/columns/tuple.js
CHANGED
package/columns/typedarray.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare class TypedArrayColumn<T extends Row = Row> extends AColumn<T> {
|
|
|
9
9
|
protected tmp: TypedArray;
|
|
10
10
|
readonly isArray = false;
|
|
11
11
|
constructor(id: ColumnID<T>, table: Table<T>);
|
|
12
|
+
clear(): void;
|
|
12
13
|
load({ values }: SerializedColumn): void;
|
|
13
14
|
validate(value: any): boolean;
|
|
14
15
|
ensureRows(): void;
|
package/columns/typedarray.js
CHANGED
|
@@ -2,6 +2,7 @@ import { typedArray } from "@thi.ng/api/typedarray";
|
|
|
2
2
|
import { isArray } from "@thi.ng/checks/is-array";
|
|
3
3
|
import { isNumber } from "@thi.ng/checks/is-number";
|
|
4
4
|
import {
|
|
5
|
+
INITIAL_CAPACITY,
|
|
5
6
|
LIMITS
|
|
6
7
|
} from "../api.js";
|
|
7
8
|
import { __indexOfSingle, __lastIndexOfSingle } from "../internal/indexof.js";
|
|
@@ -18,9 +19,13 @@ class TypedArrayColumn extends AColumn {
|
|
|
18
19
|
super(id, table);
|
|
19
20
|
this.type = table.schema[id].type;
|
|
20
21
|
this.limit = LIMITS[this.type];
|
|
21
|
-
this.values = typedArray(this.type,
|
|
22
|
+
this.values = typedArray(this.type, INITIAL_CAPACITY);
|
|
22
23
|
this.tmp = typedArray(this.type, 1);
|
|
23
24
|
}
|
|
25
|
+
clear() {
|
|
26
|
+
this.values = typedArray(this.type, INITIAL_CAPACITY);
|
|
27
|
+
this.bitmap?.clear();
|
|
28
|
+
}
|
|
24
29
|
load({ values }) {
|
|
25
30
|
this.values = __deserializeTyped(this.type, this.spec.flags, values);
|
|
26
31
|
this.reindex();
|
package/columns/vector.d.ts
CHANGED
|
@@ -10,11 +10,12 @@ export declare class VectorColumn<T extends Row = Row> extends AColumn<T> {
|
|
|
10
10
|
protected tmp: TypedArray;
|
|
11
11
|
readonly isArray = false;
|
|
12
12
|
constructor(id: ColumnID<T>, table: Table<T>);
|
|
13
|
+
clear(): void;
|
|
13
14
|
load({ values }: SerializedColumn): void;
|
|
14
15
|
validate(value: any): boolean;
|
|
15
16
|
ensureRows(): void;
|
|
16
17
|
setRow(i: number, value: any): void;
|
|
17
|
-
getRow(i: number): Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike
|
|
18
|
+
getRow(i: number): Uint32Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike>;
|
|
18
19
|
getRowKey(i: number): string;
|
|
19
20
|
valueKey(value: any): string | string[];
|
|
20
21
|
removeRow(i: number): void;
|
package/columns/vector.js
CHANGED
|
@@ -4,6 +4,7 @@ import { isArrayLike } from "@thi.ng/checks/is-arraylike";
|
|
|
4
4
|
import { isNumber } from "@thi.ng/checks/is-number";
|
|
5
5
|
import { unsupportedOp } from "@thi.ng/errors/unsupported";
|
|
6
6
|
import {
|
|
7
|
+
INITIAL_CAPACITY,
|
|
7
8
|
LIMITS
|
|
8
9
|
} from "../api.js";
|
|
9
10
|
import { __clampRange } from "../internal/indexof.js";
|
|
@@ -21,9 +22,13 @@ class VectorColumn extends AColumn {
|
|
|
21
22
|
this.type = this.spec.type.split("v")[0];
|
|
22
23
|
this.size = this.spec.cardinality[1];
|
|
23
24
|
this.limit = LIMITS[this.type];
|
|
24
|
-
this.values = typedArray(this.type,
|
|
25
|
+
this.values = typedArray(this.type, INITIAL_CAPACITY * this.size);
|
|
25
26
|
this.tmp = typedArray(this.type, this.size);
|
|
26
27
|
}
|
|
28
|
+
clear() {
|
|
29
|
+
this.values = typedArray(this.type, INITIAL_CAPACITY * this.size);
|
|
30
|
+
this.bitmap?.clear();
|
|
31
|
+
}
|
|
27
32
|
load({ values }) {
|
|
28
33
|
this.values = __deserializeTyped(this.type, this.spec.flags, values);
|
|
29
34
|
this.reindex();
|
package/internal/serialize.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export declare const __serializeTyped: ($values: NumericArray, spec: ColumnSpec,
|
|
|
11
11
|
values: any[];
|
|
12
12
|
};
|
|
13
13
|
/** @internal */
|
|
14
|
-
export declare const __deserializeTyped: (type: Type, flags: number, values: number[]) => Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike
|
|
14
|
+
export declare const __deserializeTyped: (type: Type, flags: number, values: number[]) => Uint32Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike>;
|
|
15
15
|
//# sourceMappingURL=serialize.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/column-store",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "In-memory column store database with customizable column types, extensible query engine, bitfield indexing for query acceleration, JSON serialization with optional RLE compression",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -129,5 +129,5 @@
|
|
|
129
129
|
"status": "alpha",
|
|
130
130
|
"year": 2025
|
|
131
131
|
},
|
|
132
|
-
"gitHead": "
|
|
132
|
+
"gitHead": "f2700429ff95ad80d2b4487f6bde4d7e220204c3\n"
|
|
133
133
|
}
|
package/query.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export declare class QueryCtx<T extends Row> {
|
|
|
33
33
|
*/
|
|
34
34
|
[Symbol.iterator](): Generator<number, void, unknown>;
|
|
35
35
|
clear(): void;
|
|
36
|
-
makeMask(seed?: Uint32Array): Uint32Array<ArrayBuffer>;
|
|
36
|
+
makeMask(seed?: number | Uint32Array): Uint32Array<ArrayBuffer>;
|
|
37
37
|
/**
|
|
38
38
|
* Combines the `mask` with the context's mask (combined using bitwise AND).
|
|
39
39
|
* If the context mask is still undefined, assigns `mask` as the initial
|
package/query.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isArray } from "@thi.ng/checks/is-array";
|
|
2
|
+
import { isNumber } from "@thi.ng/checks/is-number";
|
|
2
3
|
import { illegalArgs } from "@thi.ng/errors/illegal-arguments";
|
|
3
4
|
import { unsupportedOp } from "@thi.ng/errors/unsupported";
|
|
4
5
|
import { Bitfield } from "./bitmap.js";
|
|
@@ -111,7 +112,9 @@ class QueryCtx {
|
|
|
111
112
|
}
|
|
112
113
|
makeMask(seed) {
|
|
113
114
|
const mask = new Uint32Array(this.size);
|
|
114
|
-
if (seed)
|
|
115
|
+
if (seed) {
|
|
116
|
+
isNumber(seed) ? mask.fill(seed) : mask.set(seed);
|
|
117
|
+
}
|
|
115
118
|
return mask;
|
|
116
119
|
}
|
|
117
120
|
/**
|
|
@@ -166,11 +169,7 @@ const execBitOr = (ctx, term, column) => {
|
|
|
166
169
|
const b = bitmap.index.get(key)?.buffer;
|
|
167
170
|
if (b) mask = ctx.makeMask(b);
|
|
168
171
|
}
|
|
169
|
-
|
|
170
|
-
term.type === "nor" ? ctx.mergeInvMask(mask) : ctx.mergeMask(mask);
|
|
171
|
-
return true;
|
|
172
|
-
}
|
|
173
|
-
return false;
|
|
172
|
+
return __finalizeMask(ctx, mask, term.type === "nor");
|
|
174
173
|
};
|
|
175
174
|
const execOr = (ctx, term, column) => {
|
|
176
175
|
const key = column.valueKey(term.value);
|
|
@@ -184,11 +183,7 @@ const execOr = (ctx, term, column) => {
|
|
|
184
183
|
}
|
|
185
184
|
}
|
|
186
185
|
}
|
|
187
|
-
|
|
188
|
-
term.type === "nor" ? ctx.mergeInvMask(mask) : ctx.mergeMask(mask);
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
return false;
|
|
186
|
+
return __finalizeMask(ctx, mask, term.type === "nor");
|
|
192
187
|
};
|
|
193
188
|
const delegateOr = (ctx, term, column) => (term.value != null && column.bitmap ? execBitOr : execOr)(
|
|
194
189
|
ctx,
|
|
@@ -198,15 +193,18 @@ const delegateOr = (ctx, term, column) => (term.value != null && column.bitmap ?
|
|
|
198
193
|
const execBitAnd = (ctx, term, column) => {
|
|
199
194
|
const bitmap = column.bitmap;
|
|
200
195
|
const key = column.valueKey(term.value);
|
|
196
|
+
const isNeg = term.type === "nand";
|
|
201
197
|
let mask;
|
|
202
198
|
if (isArray(key)) {
|
|
203
|
-
const colBitmaps = [];
|
|
204
199
|
for (let k of key) {
|
|
205
200
|
const b = bitmap.index.get(k)?.buffer;
|
|
206
|
-
if (!b)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
201
|
+
if (!b) {
|
|
202
|
+
if (isNeg) {
|
|
203
|
+
if (mask) mask.fill(0);
|
|
204
|
+
else mask = ctx.makeMask();
|
|
205
|
+
continue;
|
|
206
|
+
} else return false;
|
|
207
|
+
}
|
|
210
208
|
if (mask) {
|
|
211
209
|
const n = b.length;
|
|
212
210
|
for (let i = 0; i < n; i++) mask[i] &= b[i];
|
|
@@ -217,16 +215,13 @@ const execBitAnd = (ctx, term, column) => {
|
|
|
217
215
|
const b = bitmap.index.get(key)?.buffer;
|
|
218
216
|
if (b) mask = ctx.makeMask(b);
|
|
219
217
|
}
|
|
220
|
-
|
|
221
|
-
term.type === "nand" ? ctx.mergeInvMask(mask) : ctx.mergeMask(mask);
|
|
222
|
-
return true;
|
|
223
|
-
}
|
|
224
|
-
return false;
|
|
218
|
+
return __finalizeMask(ctx, mask, isNeg);
|
|
225
219
|
};
|
|
226
220
|
const execAnd = (ctx, term, column) => {
|
|
227
221
|
const n = ctx.table.length;
|
|
228
222
|
const key = column.valueKey(term.value) ?? null;
|
|
229
223
|
const pred = column.isArray ? (row, v) => row.includes(v) : (row, v) => row === v;
|
|
224
|
+
const isNeg = term.type === "nand";
|
|
230
225
|
let mask;
|
|
231
226
|
for (let k of isArray(key) ? key : [key]) {
|
|
232
227
|
let m;
|
|
@@ -241,20 +236,29 @@ const execAnd = (ctx, term, column) => {
|
|
|
241
236
|
for (let i = 0; i < n; i++) mask[i] &= m[i];
|
|
242
237
|
} else mask = m;
|
|
243
238
|
} else {
|
|
244
|
-
|
|
239
|
+
if (isNeg) {
|
|
240
|
+
if (mask) mask.fill(0);
|
|
241
|
+
else mask = ctx.makeMask();
|
|
242
|
+
} else return false;
|
|
245
243
|
}
|
|
246
244
|
}
|
|
247
|
-
|
|
248
|
-
term.type === "nand" ? ctx.mergeInvMask(mask) : ctx.mergeMask(mask);
|
|
249
|
-
return true;
|
|
250
|
-
}
|
|
251
|
-
return false;
|
|
245
|
+
return __finalizeMask(ctx, mask, isNeg);
|
|
252
246
|
};
|
|
253
247
|
const delegateAnd = (ctx, term, column) => (term.value != null && column.bitmap ? execBitAnd : execAnd)(
|
|
254
248
|
ctx,
|
|
255
249
|
term,
|
|
256
250
|
column
|
|
257
251
|
);
|
|
252
|
+
const __finalizeMask = (ctx, mask, isNeg) => {
|
|
253
|
+
if (mask) {
|
|
254
|
+
isNeg ? ctx.mergeInvMask(mask) : ctx.mergeMask(mask);
|
|
255
|
+
return true;
|
|
256
|
+
} else if (isNeg) {
|
|
257
|
+
if (!ctx.bitmap) ctx.bitmap = ctx.makeMask(-1);
|
|
258
|
+
return true;
|
|
259
|
+
}
|
|
260
|
+
return false;
|
|
261
|
+
};
|
|
258
262
|
const QUERY_OPS = {
|
|
259
263
|
or: { fn: delegateOr },
|
|
260
264
|
nor: { fn: delegateOr },
|
package/table.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Maybe } from "@thi.ng/api";
|
|
1
|
+
import type { IClear, ICopy, IEmpty, Maybe } from "@thi.ng/api";
|
|
2
2
|
import { type ColumnID, type ColumnSchema, type ColumnSpec, type ColumnTypeSpec, type IColumn, type QueryTerm, type Row, type RowWithMeta, type SerializedTable } from "./api.js";
|
|
3
3
|
import { Query } from "./query.js";
|
|
4
4
|
/**
|
|
@@ -6,7 +6,7 @@ import { Query } from "./query.js";
|
|
|
6
6
|
*/
|
|
7
7
|
export interface TableOpts {
|
|
8
8
|
}
|
|
9
|
-
export declare class Table<T extends Row> {
|
|
9
|
+
export declare class Table<T extends Row> implements IClear, ICopy<Table<T>>, IEmpty<Table<T>> {
|
|
10
10
|
opts: TableOpts;
|
|
11
11
|
schema: ColumnSchema<T>;
|
|
12
12
|
columns: Record<ColumnID<T>, IColumn>;
|
|
@@ -15,12 +15,15 @@ export declare class Table<T extends Row> {
|
|
|
15
15
|
constructor(schema: Record<ColumnID<T>, Partial<ColumnSpec> & {
|
|
16
16
|
type: ColumnSpec["type"];
|
|
17
17
|
}>, opts?: Partial<TableOpts>);
|
|
18
|
+
clear(): void;
|
|
19
|
+
copy(): Table<T>;
|
|
20
|
+
empty(): Table<T>;
|
|
18
21
|
query(terms?: QueryTerm<T>[]): Query<T>;
|
|
19
22
|
addColumn(id: ColumnID<T>, spec: Partial<ColumnSpec> & {
|
|
20
23
|
type: ColumnSpec["type"];
|
|
21
24
|
}): IColumn;
|
|
22
25
|
removeColumn(id: ColumnID<T>): boolean;
|
|
23
|
-
[Symbol.iterator](): Generator<
|
|
26
|
+
[Symbol.iterator](): Generator<T, void, unknown>;
|
|
24
27
|
reindex(): void;
|
|
25
28
|
addRow(row: Partial<T>): void;
|
|
26
29
|
addRows(rows: Iterable<Partial<T>>): void;
|
|
@@ -32,6 +35,7 @@ export declare class Table<T extends Row> {
|
|
|
32
35
|
getPartialRow<K extends ColumnID<T>>(i: number, columns: K[], safe?: boolean): Maybe<Pick<T, K>>;
|
|
33
36
|
getPartialRow<K extends ColumnID<T>>(i: number, columns: K[], safe?: boolean, includeID?: false): Maybe<Pick<T, K>>;
|
|
34
37
|
getPartialRow<K extends ColumnID<T>>(i: number, columns: K[], safe?: boolean, includeID?: true): Maybe<RowWithMeta<Pick<T, K>>>;
|
|
38
|
+
slice(start?: number, end?: number): Table<T>;
|
|
35
39
|
indexOf(id: ColumnID<T>, value: any, start?: number, end?: number): number;
|
|
36
40
|
lastIndexOf(id: ColumnID<T>, value: any, start?: number, end?: number): number;
|
|
37
41
|
validateRow(row: Partial<T>): void;
|
package/table.js
CHANGED
|
@@ -13,6 +13,7 @@ import { TupleColumn } from "./columns/tuple.js";
|
|
|
13
13
|
import { TypedArrayColumn } from "./columns/typedarray.js";
|
|
14
14
|
import { VectorColumn } from "./columns/vector.js";
|
|
15
15
|
import { __columnError } from "./internal/checks.js";
|
|
16
|
+
import { __clamp } from "./internal/indexof.js";
|
|
16
17
|
import { Query } from "./query.js";
|
|
17
18
|
class Table {
|
|
18
19
|
opts;
|
|
@@ -31,6 +32,19 @@ class Table {
|
|
|
31
32
|
this.opts = { ...opts };
|
|
32
33
|
for (let id in schema) this.addColumn(id, schema[id]);
|
|
33
34
|
}
|
|
35
|
+
clear() {
|
|
36
|
+
const { columns } = this;
|
|
37
|
+
for (let id in columns) columns[id].clear();
|
|
38
|
+
this.length = 0;
|
|
39
|
+
}
|
|
40
|
+
copy() {
|
|
41
|
+
const copy = new Table(this.schema, this.opts);
|
|
42
|
+
copy.addRows(this);
|
|
43
|
+
return copy;
|
|
44
|
+
}
|
|
45
|
+
empty() {
|
|
46
|
+
return new Table(this.schema, this.opts);
|
|
47
|
+
}
|
|
34
48
|
query(terms) {
|
|
35
49
|
return new Query(this, terms);
|
|
36
50
|
}
|
|
@@ -104,6 +118,14 @@ class Table {
|
|
|
104
118
|
}
|
|
105
119
|
return row;
|
|
106
120
|
}
|
|
121
|
+
slice(start = 0, end) {
|
|
122
|
+
const max = this.length;
|
|
123
|
+
start = __clamp(start, 0, max);
|
|
124
|
+
end = __clamp(end ?? max, start, max);
|
|
125
|
+
const copy = this.empty();
|
|
126
|
+
for (let i = start; i < end; i++) copy.addRow(this.getRow(i, true));
|
|
127
|
+
return copy;
|
|
128
|
+
}
|
|
107
129
|
indexOf(id, value, start, end) {
|
|
108
130
|
return this.columns[id]?.indexOf(value, start, end) ?? -1;
|
|
109
131
|
}
|