@thi.ng/column-store 0.9.0 → 0.10.0

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 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,
@@ -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;
@@ -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)[];
@@ -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);
@@ -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();
@@ -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
@@ -6,6 +6,10 @@ import { AColumn } from "./acolumn.js";
6
6
  class TupleColumn extends AColumn {
7
7
  values = [];
8
8
  isArray = true;
9
+ clear() {
10
+ this.values = [];
11
+ this.bitmap?.clear();
12
+ }
9
13
  load(spec) {
10
14
  this.values = spec.values;
11
15
  this.reindex();
@@ -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;
@@ -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, 8);
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();
@@ -10,6 +10,7 @@ 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;
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, 8 * this.size);
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thi.ng/column-store",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
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": "1138bb64457a415733cf5c05d32c211ccfd6ee72\n"
132
+ "gitHead": "f15a589f1695f67f2e90b8d221a89fc9960a2e83\n"
133
133
  }
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<Maybe<T>, void, unknown>;
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
  }