@thi.ng/column-store 0.10.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.
@@ -15,7 +15,7 @@ export declare class VectorColumn<T extends Row = Row> extends AColumn<T> {
15
15
  validate(value: any): boolean;
16
16
  ensureRows(): void;
17
17
  setRow(i: number, value: any): void;
18
- getRow(i: number): Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike> | Uint32Array<ArrayBufferLike>;
18
+ getRow(i: number): Uint32Array<ArrayBufferLike> | Float32Array<ArrayBufferLike> | Float64Array<ArrayBufferLike> | Int8Array<ArrayBufferLike> | Int16Array<ArrayBufferLike> | Int32Array<ArrayBufferLike> | Uint8Array<ArrayBufferLike> | Uint8ClampedArray<ArrayBufferLike> | Uint16Array<ArrayBufferLike>;
19
19
  getRowKey(i: number): string;
20
20
  valueKey(value: any): string | string[];
21
21
  removeRow(i: number): void;
@@ -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[]) => 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.10.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": "f15a589f1695f67f2e90b8d221a89fc9960a2e83\n"
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) mask.set(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
- if (mask) {
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
- if (mask) {
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) return false;
207
- colBitmaps.push(b);
208
- }
209
- for (let b of colBitmaps) {
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
- if (mask) {
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
- return false;
239
+ if (isNeg) {
240
+ if (mask) mask.fill(0);
241
+ else mask = ctx.makeMask();
242
+ } else return false;
245
243
  }
246
244
  }
247
- if (mask) {
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 },