@thi.ng/column-store 0.6.0 → 0.7.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
@@ -149,6 +149,8 @@ export interface IColumn {
149
149
  */
150
150
  setRow(i: number, value: any): void;
151
151
  removeRow(i: number): void;
152
+ /** @internal */
153
+ ensureRows(): void;
152
154
  encode(value: any): any;
153
155
  decode(value: any): any;
154
156
  replaceValue(currValue: any, newValue: any): boolean;
@@ -16,6 +16,7 @@ export declare abstract class AColumn<T extends Row = Row> implements IColumn {
16
16
  abstract validate(value: any): boolean;
17
17
  abstract setRow(i: number, value: any): void;
18
18
  abstract removeRow(i: number): void;
19
+ abstract ensureRows(): void;
19
20
  abstract replaceValue(currValue: any, newValue: any): boolean;
20
21
  abstract valueKey(x: any): any;
21
22
  abstract getRow(i: number): any;
@@ -56,11 +56,11 @@ class AColumn {
56
56
  if (!bitmap) return;
57
57
  bitmap.clear();
58
58
  for (let i = 0, n = this.table.length; i < n; i++) {
59
- const value = this.getRow(i);
59
+ const value = this.getRowKey(i);
60
60
  if (value == null) continue;
61
61
  if (isArray) {
62
62
  for (let x of value) bitmap.setBit(x, i);
63
- } else bitmap.setBit(this.getRowKey(i), i);
63
+ } else bitmap.setBit(value, i);
64
64
  }
65
65
  }
66
66
  ensureValue(val) {
@@ -10,6 +10,7 @@ export declare class DictTupleColumn<T extends Row = Row> extends AColumn<T> {
10
10
  encode(value: any): (number | null)[];
11
11
  decode(value: any[]): any[];
12
12
  validate(value: any): boolean;
13
+ ensureRows(): void;
13
14
  setRow(i: number, value: any[]): void;
14
15
  getRow(i: number): any[] | null;
15
16
  getRowKey(i: number): number[] | null;
@@ -32,6 +32,20 @@ class DictTupleColumn extends AColumn {
32
32
  validate(value) {
33
33
  return __validateArrayValue(this.spec, value);
34
34
  }
35
+ ensureRows() {
36
+ const {
37
+ bitmap,
38
+ spec: { default: value },
39
+ table: { length: n },
40
+ values
41
+ } = this;
42
+ const $value = value != null ? this.dict.addAll(value) : null;
43
+ values.length = n;
44
+ values.fill($value, 0, n);
45
+ if (bitmap && $value) {
46
+ for (let x of $value) bitmap.ensure(x).fill(1, 0, n);
47
+ }
48
+ }
35
49
  setRow(i, value) {
36
50
  value = this.ensureValue(value);
37
51
  const { values, dict, bitmap } = this;
package/columns/dict.d.ts CHANGED
@@ -10,6 +10,7 @@ export declare class DictColumn<T extends Row = Row> extends AColumn<T> {
10
10
  encode(value: any): number | null;
11
11
  decode(value: any): any;
12
12
  validate(value: any): boolean;
13
+ ensureRows(): void;
13
14
  setRow(i: number, value: any): void;
14
15
  getRow(i: number): any;
15
16
  getRowKey(i: number): number | null;
package/columns/dict.js CHANGED
@@ -34,6 +34,18 @@ class DictColumn extends AColumn {
34
34
  validate(value) {
35
35
  return __validateValue(this.spec, value);
36
36
  }
37
+ ensureRows() {
38
+ const {
39
+ bitmap,
40
+ spec: { default: value },
41
+ table: { length: n },
42
+ values
43
+ } = this;
44
+ const $value = value != null ? this.dict.add(value) : null;
45
+ values.length = n;
46
+ values.fill($value, 0, n);
47
+ if (bitmap && $value != null) bitmap.ensure($value).fill(1, 0, n);
48
+ }
37
49
  setRow(i, value) {
38
50
  value = this.ensureValue(value);
39
51
  const { values, bitmap } = this;
@@ -4,6 +4,7 @@ export declare class PlainColumn<T extends Row = Row> extends AColumn<T> {
4
4
  values: any[];
5
5
  readonly isArray = false;
6
6
  load({ values }: SerializedColumn): void;
7
+ ensureRows(): void;
7
8
  validate(value: any): boolean;
8
9
  setRow(i: number, value: any): void;
9
10
  getRow(i: number): any;
package/columns/plain.js CHANGED
@@ -11,13 +11,25 @@ class PlainColumn extends AColumn {
11
11
  this.values = this.spec.flags & FLAG_RLE ? Array.from(decodeSimple(values)) : values;
12
12
  this.reindex();
13
13
  }
14
+ ensureRows() {
15
+ const {
16
+ bitmap,
17
+ spec: { default: value },
18
+ table: { length: n },
19
+ values
20
+ } = this;
21
+ values.length = n;
22
+ values.fill(value ?? null, 0, n);
23
+ if (bitmap && value != null) bitmap.ensure(value).fill(1, 0, n);
24
+ }
14
25
  validate(value) {
15
26
  return __validateValue(this.spec, value);
16
27
  }
17
28
  setRow(i, value) {
18
29
  const { values, bitmap } = this;
19
30
  const old = values[i];
20
- values[i] = this.ensureValue(value);
31
+ value = this.ensureValue(value);
32
+ values[i] = value;
21
33
  if (bitmap) {
22
34
  if (old != null) bitmap.clearBit(old, i);
23
35
  if (value != null) bitmap.setBit(value, i);
@@ -7,6 +7,7 @@ export declare class TupleColumn<T extends Row = Row> extends AColumn<T> {
7
7
  load(spec: SerializedColumn): void;
8
8
  encode(value: any): any[];
9
9
  validate(value: any): boolean;
10
+ ensureRows(): void;
10
11
  setRow(i: number, value: any[]): void;
11
12
  getRow(i: number): Nullable<number[]>;
12
13
  getRowKey(i: number): Nullable<number[]>;
package/columns/tuple.js CHANGED
@@ -16,6 +16,19 @@ class TupleColumn extends AColumn {
16
16
  validate(value) {
17
17
  return __validateArrayValue(this.spec, value);
18
18
  }
19
+ ensureRows() {
20
+ const {
21
+ bitmap,
22
+ spec: { default: value },
23
+ table: { length: n },
24
+ values
25
+ } = this;
26
+ values.length = n;
27
+ values.fill(value ?? null, 0, n);
28
+ if (bitmap && value) {
29
+ for (let x of value) bitmap.ensure(x).fill(1, 0, n);
30
+ }
31
+ }
19
32
  setRow(i, value) {
20
33
  value = this.ensureValue(value);
21
34
  const { values, bitmap } = this;
@@ -11,6 +11,7 @@ export declare class TypedArrayColumn<T extends Row = Row> extends AColumn<T> {
11
11
  constructor(id: ColumnID<T>, table: Table<T>);
12
12
  load({ values }: SerializedColumn): void;
13
13
  validate(value: any): boolean;
14
+ ensureRows(): void;
14
15
  setRow(i: number, value: any): void;
15
16
  getRow(i: number): number;
16
17
  getRowKey(i: number): number;
@@ -22,5 +23,6 @@ export declare class TypedArrayColumn<T extends Row = Row> extends AColumn<T> {
22
23
  toJSON(): {
23
24
  values: any[];
24
25
  };
26
+ protected ensureCapacity(capacity: number, copy?: boolean): void;
25
27
  }
26
28
  //# sourceMappingURL=typedarray.d.ts.map
@@ -28,15 +28,15 @@ class TypedArrayColumn extends AColumn {
28
28
  validate(value) {
29
29
  return isNumber(value) && value >= this.limit[0] && value <= this.limit[1] || value == null && this.spec.default != null;
30
30
  }
31
+ ensureRows() {
32
+ const n = this.table.length;
33
+ this.ensureCapacity(n, false);
34
+ this.values.fill(this.spec.default, 0, n);
35
+ this.bitmap?.ensure(this.spec.default).fill(1, 0, n);
36
+ }
31
37
  setRow(i, value) {
32
38
  value = this.ensureValue(value);
33
- let len = this.values.length;
34
- if (i >= len) {
35
- while (i >= len) len <<= 1;
36
- const tmp = typedArray(this.type, len);
37
- tmp.set(this.values);
38
- this.values = tmp;
39
- }
39
+ this.ensureCapacity(i);
40
40
  const { values, bitmap } = this;
41
41
  const old = values[i];
42
42
  values[i] = value;
@@ -98,6 +98,15 @@ class TypedArrayColumn extends AColumn {
98
98
  this.type
99
99
  );
100
100
  }
101
+ ensureCapacity(capacity, copy = true) {
102
+ let len = this.values.length;
103
+ if (capacity >= len) {
104
+ while (capacity >= len) len <<= 1;
105
+ const tmp = typedArray(this.type, len);
106
+ copy && tmp.set(this.values);
107
+ this.values = tmp;
108
+ }
109
+ }
101
110
  }
102
111
  export {
103
112
  TypedArrayColumn
@@ -12,8 +12,9 @@ export declare class VectorColumn<T extends Row = Row> extends AColumn<T> {
12
12
  constructor(id: ColumnID<T>, table: Table<T>);
13
13
  load({ values }: SerializedColumn): void;
14
14
  validate(value: any): boolean;
15
+ ensureRows(): void;
15
16
  setRow(i: number, value: any): void;
16
- getRow(i: number): Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | Uint32Array<ArrayBufferLike>;
17
+ getRow(i: number): Uint8Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | Uint32Array<ArrayBufferLike>;
17
18
  getRowKey(i: number): string;
18
19
  valueKey(value: any): string | string[];
19
20
  removeRow(i: number): void;
@@ -23,5 +24,6 @@ export declare class VectorColumn<T extends Row = Row> extends AColumn<T> {
23
24
  toJSON(): {
24
25
  values: any[];
25
26
  };
27
+ protected ensureCapacity(capacity: number, copy?: boolean): void;
26
28
  }
27
29
  //# sourceMappingURL=vector.d.ts.map
package/columns/vector.js CHANGED
@@ -31,22 +31,25 @@ class VectorColumn extends AColumn {
31
31
  validate(value) {
32
32
  return isArrayLike(value) && value.length == this.size || value == null && this.spec.default != null;
33
33
  }
34
+ ensureRows() {
35
+ const {
36
+ size,
37
+ spec: { default: value },
38
+ table: { length: n }
39
+ } = this;
40
+ this.ensureCapacity(n, false);
41
+ for (let i = 0; i < n; i++) this.values.set(value, i * size);
42
+ this.bitmap?.ensure(this.valueKey(value)).fill(1, 0, n);
43
+ }
34
44
  setRow(i, value) {
35
45
  value = this.ensureValue(value);
36
- const j = i * this.size;
37
- let len = this.values.length;
38
- if (j >= len) {
39
- while (j >= len) len <<= 1;
40
- const tmp = typedArray(this.type, len);
41
- tmp.set(this.values);
42
- this.values = tmp;
43
- }
46
+ this.ensureCapacity(i);
44
47
  const { values, bitmap } = this;
45
48
  if (bitmap) {
46
49
  bitmap.clearBit(this.getRowKey(i), i);
47
50
  bitmap.setBit(this.valueKey(value), i);
48
51
  }
49
- values.set(value, j);
52
+ values.set(value, i * this.size);
50
53
  }
51
54
  getRow(i) {
52
55
  const { size } = this;
@@ -121,6 +124,16 @@ class VectorColumn extends AColumn {
121
124
  this.type
122
125
  );
123
126
  }
127
+ ensureCapacity(capacity, copy = true) {
128
+ capacity *= this.size;
129
+ let len = this.values.length;
130
+ if (capacity >= len) {
131
+ while (capacity >= len) len <<= 1;
132
+ const tmp = typedArray(this.type, len);
133
+ copy && tmp.set(this.values);
134
+ this.values = tmp;
135
+ }
136
+ }
124
137
  }
125
138
  export {
126
139
  VectorColumn
@@ -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> | Uint32Array<ArrayBufferLike>;
14
+ export declare const __deserializeTyped: (type: Type, flags: number, values: number[]) => Uint8Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | Uint32Array<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.6.0",
3
+ "version": "0.7.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",
@@ -126,5 +126,5 @@
126
126
  "status": "alpha",
127
127
  "year": 2025
128
128
  },
129
- "gitHead": "f1d8da5644dd22f212fc313df2187380da968a7c\n"
129
+ "gitHead": "3bb968f9005a82c2890510903aab375d2cc99fae\n"
130
130
  }
package/table.d.ts CHANGED
@@ -18,7 +18,7 @@ export declare class Table<T extends Row> {
18
18
  query(terms?: QueryTerm<T>[]): Query<T>;
19
19
  addColumn(id: ColumnID<T>, spec: Partial<ColumnSpec> & {
20
20
  type: ColumnSpec["type"];
21
- }): void;
21
+ }): IColumn;
22
22
  removeColumn(id: ColumnID<T>): boolean;
23
23
  [Symbol.iterator](): Generator<Maybe<T>, void, unknown>;
24
24
  reindex(): void;
package/table.js CHANGED
@@ -43,11 +43,13 @@ class Table {
43
43
  };
44
44
  this.validateColumnSpec(id, $spec);
45
45
  this.schema[id] = $spec;
46
- this.columns[id] = COLUMN_TYPES[spec.type].impl(
46
+ const column = this.columns[id] = COLUMN_TYPES[$spec.type].impl(
47
47
  this,
48
48
  String(id),
49
49
  $spec
50
50
  );
51
+ if (this.length) column.ensureRows();
52
+ return column;
51
53
  }
52
54
  removeColumn(id) {
53
55
  if (this.columns[id]) return false;
@@ -132,6 +134,8 @@ class Table {
132
134
  if (max > 1 !== isArray(spec.default))
133
135
  __columnError(id, `wrong default value`);
134
136
  }
137
+ if (this.length && spec.default == null && (def.required || min > 0))
138
+ __columnError(id, `missing default value to fill existing rows`);
135
139
  }
136
140
  toJSON() {
137
141
  return {