@milaboratories/pf-driver 1.4.12 → 1.4.14

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.
@@ -1,12 +1,10 @@
1
1
  import {
2
- assertNever,
3
2
  bigintReplacer,
4
3
  PFrameDriverError,
5
4
  type PFrameHandle,
5
+ type PTableDef,
6
6
  type PTableHandle,
7
- type JoinEntry,
8
7
  type JsonSerializable,
9
- type PColumnValue,
10
8
  type PObjectId,
11
9
  } from "@milaboratories/pl-model-common";
12
10
  import type { PFrameInternal } from "@milaboratories/pl-model-middle-layer";
@@ -14,8 +12,7 @@ import { RefCountPoolBase, type PoolEntry } from "@milaboratories/helpers";
14
12
  import { logPFrames } from "./logging";
15
13
  import type { PFramePool } from "./pframe_pool";
16
14
  import {
17
- FullPTableDefV1,
18
- FullPTableDefV2,
15
+ buildFullPTableDefFromLegacy,
19
16
  stableKeyFromFullPTableDef,
20
17
  type FullPTableDef,
21
18
  } from "./ptable_shared";
@@ -77,78 +74,19 @@ export class PTablePool<TreeEntry extends JsonSerializable> extends RefCountPool
77
74
  );
78
75
  }
79
76
 
80
- switch (params.type) {
81
- case "v1":
82
- return this.createNewResourceV1(params, key);
83
- case "v2":
84
- return this.createNewResourceV2(params, key);
85
- default:
86
- // @ts-expect-error `params.type` is a string, but we want to make sure all cases are handled
87
- throw new PFrameDriverError(`Unsupported FullPTableDef type: ${params.type}`);
88
- }
89
- }
90
-
91
- protected createNewResourceV1(params: FullPTableDefV1, key: PTableHandle): PTableHolder {
92
- const { def, pFrameHandle } = params;
93
- const { pFramePromise, disposeSignal } = this.pFrames.getByKey(pFrameHandle);
77
+ const { pFrameHandle } = params;
78
+ const { pFrameDataPromise: pFramePromise, disposeSignal } = this.pFrames.getByKey(pFrameHandle);
94
79
 
95
80
  const defDisposeSignal = this.pTableDefs.tryGetByKey(key)?.disposeSignal;
96
81
  const combinedSignal = AbortSignal.any([disposeSignal, defDisposeSignal].filter((s) => !!s));
97
82
 
98
- // 3. Sort
99
- if (def.sorting.length > 0) {
100
- const predecessor = this.acquire({
101
- ...params,
102
- def: {
103
- ...def,
104
- sorting: [],
105
- },
106
- });
107
- const {
108
- resource: { pTablePromise },
109
- } = predecessor;
110
- const sortedTable = pTablePromise.then((pTable) => pTable.sort(key, def.sorting));
111
- return new PTableHolder(pFrameHandle, combinedSignal, sortedTable, predecessor);
112
- }
113
-
114
- // 2. Filter (except the case with artificial columns where cartesian creates too many rows)
115
- if (!hasArtificialColumns(def.src) && def.filters.length > 0) {
116
- const predecessor = this.acquire({
117
- ...params,
118
- def: {
119
- ...def,
120
- filters: [],
121
- },
122
- });
123
- const {
124
- resource: { pTablePromise },
125
- } = predecessor;
126
- const filteredTable = pTablePromise.then((pTable) => pTable.filter(key, def.filters));
127
- return new PTableHolder(pFrameHandle, combinedSignal, filteredTable, predecessor);
128
- }
129
-
130
- // 1. Join
83
+ const { tableSpec, dataQuery } = params;
131
84
  const table = pFramePromise.then((pFrame) =>
132
- pFrame.createTable(key, {
133
- src: joinEntryToInternal(def.src),
134
- // `def.filters` would be non-empty only when join has artificial columns
135
- filters: [...def.partitionFilters, ...def.filters],
136
- }),
85
+ pFrame.createTableV2(key, { tableSpec, dataQuery }),
137
86
  );
138
87
  return new PTableHolder(pFrameHandle, combinedSignal, table);
139
88
  }
140
89
 
141
- protected createNewResourceV2(params: FullPTableDefV2, key: PTableHandle): PTableHolder {
142
- const { pFrameHandle } = params;
143
- const { pFramePromise, disposeSignal } = this.pFrames.getByKey(pFrameHandle);
144
-
145
- const defDisposeSignal = this.pTableDefs.tryGetByKey(key)?.disposeSignal;
146
- const combinedSignal = AbortSignal.any([disposeSignal, defDisposeSignal].filter((s) => !!s));
147
-
148
- const table = pFramePromise.then((pFrame) => pFrame.createTableV2(key, params.def));
149
- return new PTableHolder(pFrameHandle, combinedSignal, table);
150
- }
151
-
152
90
  public getByKey(key: PTableHandle): PTableHolder {
153
91
  const resource = super.tryGetByKey(key);
154
92
  if (!resource) {
@@ -158,78 +96,19 @@ export class PTablePool<TreeEntry extends JsonSerializable> extends RefCountPool
158
96
  }
159
97
  return resource;
160
98
  }
161
- }
162
-
163
- function hasArtificialColumns<T>(entry: JoinEntry<T>): boolean {
164
- switch (entry.type) {
165
- case "column":
166
- case "slicedColumn":
167
- case "inlineColumn":
168
- return false;
169
- case "artificialColumn":
170
- return true;
171
- case "full":
172
- case "inner":
173
- return entry.entries.some(hasArtificialColumns);
174
- case "outer":
175
- return hasArtificialColumns(entry.primary) || entry.secondary.some(hasArtificialColumns);
176
- default:
177
- assertNever(entry);
178
- }
179
- }
180
99
 
181
- function joinEntryToInternal(entry: JoinEntry<PObjectId>): PFrameInternal.JoinEntryV4 {
182
- const type = entry.type;
183
- switch (type) {
184
- case "column":
185
- return {
186
- type: "column",
187
- columnId: entry.column,
188
- };
189
- case "slicedColumn":
190
- return {
191
- type: "slicedColumn",
192
- columnId: entry.column,
193
- newId: entry.newId,
194
- axisFilters: entry.axisFilters,
195
- };
196
- case "artificialColumn":
197
- return {
198
- type: "artificialColumn",
199
- columnId: entry.column,
200
- newId: entry.newId,
201
- axesIndices: entry.axesIndices,
202
- };
203
- case "inlineColumn":
204
- return {
205
- type: "inlineColumn",
206
- newId: entry.column.id,
207
- spec: entry.column.spec,
208
- dataInfo: {
209
- type: "Json",
210
- keyLength: entry.column.spec.axesSpec.length,
211
- data: entry.column.data.reduce(
212
- (acc, row) => {
213
- acc[JSON.stringify(row.key)] = row.val;
214
- return acc;
215
- },
216
- {} as Record<string, PColumnValue>,
217
- ),
218
- },
219
- };
220
- case "inner":
221
- case "full":
222
- return {
223
- type: entry.type,
224
- entries: entry.entries.map((col) => joinEntryToInternal(col)),
225
- };
226
- case "outer":
227
- return {
228
- type: "outer",
229
- primary: joinEntryToInternal(entry.primary),
230
- secondary: entry.secondary.map((col) => joinEntryToInternal(col)),
231
- };
232
- default:
233
- throw new PFrameDriverError(`unsupported PFrame join entry type: ${type satisfies never}`);
100
+ /**
101
+ * Acquire a PTable from a legacy `PTableDef` + column specs map.
102
+ * Lowers the input via WASM-spec and stores the resulting
103
+ * `{ tableSpec, dataQuery }` shape. Returns the lowered def
104
+ * alongside the pool entry.
105
+ */
106
+ public acquireFromLegacy(opts: {
107
+ pFrameHandle: PFrameHandle;
108
+ def: PTableDef<PObjectId>;
109
+ pFrameSpec: PFrameInternal.PFrameWasmV3;
110
+ }): { def: FullPTableDef; entry: PoolEntry<PTableHandle, PTableHolder> } {
111
+ const def = buildFullPTableDefFromLegacy(opts);
112
+ return { def, entry: this.acquire(def) };
234
113
  }
235
114
  }
@@ -1,30 +1,59 @@
1
1
  import type {
2
- PObjectId,
2
+ DataQuery,
3
3
  PFrameHandle,
4
+ PObjectId,
5
+ PTableColumnSpec,
4
6
  PTableDef,
5
7
  PTableHandle,
6
- DataQuery,
7
- PTableColumnSpec,
8
8
  } from "@milaboratories/pl-model-common";
9
- import { hashJson } from "@milaboratories/pl-model-middle-layer";
10
-
11
- export type FullPTableDefV1 = {
12
- type: "v1";
13
- pFrameHandle: PFrameHandle;
14
- def: PTableDef<PObjectId>;
15
- };
9
+ import { hashJson, PFrameInternal } from "@milaboratories/pl-model-middle-layer";
16
10
 
17
- export type FullPTableDefV2 = {
18
- type: "v2";
11
+ /**
12
+ * PTable definition stored in the def / table pools. Always
13
+ * carries a pre-lowered data query plus the corresponding output
14
+ * `tableSpec`. Legacy `PTableDef<PObjectId>` inputs are lowered to
15
+ * this shape via WASM-spec at acquire time.
16
+ */
17
+ export type FullPTableDef = {
19
18
  pFrameHandle: PFrameHandle;
20
- def: {
21
- tableSpec: PTableColumnSpec[];
22
- dataQuery: DataQuery;
23
- };
19
+ tableSpec: PTableColumnSpec[];
20
+ dataQuery: DataQuery;
24
21
  };
25
22
 
26
- export type FullPTableDef = FullPTableDefV1 | FullPTableDefV2;
27
-
28
23
  export function stableKeyFromFullPTableDef(data: FullPTableDef): PTableHandle {
29
24
  return hashJson(data) as string as PTableHandle;
30
25
  }
26
+
27
+ /**
28
+ * Lower a legacy `PTableDef<PObjectId>` to the data layer. Returns
29
+ * the output `tableSpec` and the lowered `dataQuery`. Routes through
30
+ * `rewriteLegacyQuery` + `evaluateQuery` on the caller-supplied
31
+ * WASM-spec frame.
32
+ */
33
+ export function lowerLegacyPTableDef(
34
+ pFrameSpec: PFrameInternal.PFrameWasmV3,
35
+ legacyDef: PTableDef<PObjectId>,
36
+ ): { tableSpec: PTableColumnSpec[]; dataQuery: DataQuery } {
37
+ const legacy: PFrameInternal.LegacyQuery = {
38
+ src: legacyDef.src,
39
+ filters: [...legacyDef.partitionFilters, ...legacyDef.filters],
40
+ sorting: legacyDef.sorting,
41
+ };
42
+ return pFrameSpec.evaluateQuery(pFrameSpec.rewriteLegacyQuery(legacy));
43
+ }
44
+
45
+ /**
46
+ * Build a `FullPTableDef` from a legacy `PTableDef` plus the
47
+ * PFrame's WASM-spec frame. Used by pool `acquireFromLegacy` methods
48
+ * to keep lowering off the call site.
49
+ */
50
+ export function buildFullPTableDefFromLegacy(opts: {
51
+ pFrameHandle: PFrameHandle;
52
+ def: PTableDef<PObjectId>;
53
+ pFrameSpec: PFrameInternal.PFrameWasmV3;
54
+ }): FullPTableDef {
55
+ return {
56
+ pFrameHandle: opts.pFrameHandle,
57
+ ...lowerLegacyPTableDef(opts.pFrameSpec, opts.def),
58
+ };
59
+ }