@tanstack/db-ivm 0.0.0 → 0.1.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/LICENSE +21 -0
- package/dist/cjs/d2.cjs +111 -0
- package/dist/cjs/d2.cjs.map +1 -0
- package/dist/cjs/d2.d.cts +45 -0
- package/dist/cjs/graph.cjs +90 -0
- package/dist/cjs/graph.cjs.map +1 -0
- package/dist/cjs/graph.d.cts +57 -0
- package/dist/cjs/index.cjs +72 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/index.d.cts +4 -0
- package/dist/cjs/indexes.cjs +104 -0
- package/dist/cjs/indexes.cjs.map +1 -0
- package/dist/cjs/indexes.d.cts +20 -0
- package/dist/cjs/multiset.cjs +173 -0
- package/dist/cjs/multiset.cjs.map +1 -0
- package/dist/cjs/multiset.d.cts +36 -0
- package/dist/cjs/operators/concat.cjs +37 -0
- package/dist/cjs/operators/concat.cjs.map +1 -0
- package/dist/cjs/operators/concat.d.cts +13 -0
- package/dist/cjs/operators/consolidate.cjs +40 -0
- package/dist/cjs/operators/consolidate.cjs.map +1 -0
- package/dist/cjs/operators/consolidate.d.cts +12 -0
- package/dist/cjs/operators/count.cjs +36 -0
- package/dist/cjs/operators/count.cjs.map +1 -0
- package/dist/cjs/operators/count.d.cts +13 -0
- package/dist/cjs/operators/debug.cjs +50 -0
- package/dist/cjs/operators/debug.cjs.map +1 -0
- package/dist/cjs/operators/debug.d.cts +16 -0
- package/dist/cjs/operators/distinct.cjs +78 -0
- package/dist/cjs/operators/distinct.cjs.map +1 -0
- package/dist/cjs/operators/distinct.d.cts +14 -0
- package/dist/cjs/operators/filter.cjs +43 -0
- package/dist/cjs/operators/filter.cjs.map +1 -0
- package/dist/cjs/operators/filter.d.cts +16 -0
- package/dist/cjs/operators/filterBy.cjs +19 -0
- package/dist/cjs/operators/filterBy.cjs.map +1 -0
- package/dist/cjs/operators/filterBy.d.cts +10 -0
- package/dist/cjs/operators/groupBy.cjs +225 -0
- package/dist/cjs/operators/groupBy.cjs.map +1 -0
- package/dist/cjs/operators/groupBy.d.cts +68 -0
- package/dist/cjs/operators/index.d.cts +18 -0
- package/dist/cjs/operators/join.cjs +145 -0
- package/dist/cjs/operators/join.cjs.map +1 -0
- package/dist/cjs/operators/join.d.cts +48 -0
- package/dist/cjs/operators/keying.cjs +16 -0
- package/dist/cjs/operators/keying.cjs.map +1 -0
- package/dist/cjs/operators/keying.d.cts +19 -0
- package/dist/cjs/operators/map.cjs +43 -0
- package/dist/cjs/operators/map.cjs.map +1 -0
- package/dist/cjs/operators/map.d.cts +16 -0
- package/dist/cjs/operators/negate.cjs +28 -0
- package/dist/cjs/operators/negate.cjs.map +1 -0
- package/dist/cjs/operators/negate.d.cts +13 -0
- package/dist/cjs/operators/orderBy.cjs +102 -0
- package/dist/cjs/operators/orderBy.cjs.map +1 -0
- package/dist/cjs/operators/orderBy.d.cts +38 -0
- package/dist/cjs/operators/orderByBTree.d.cts +3 -0
- package/dist/cjs/operators/output.cjs +46 -0
- package/dist/cjs/operators/output.cjs.map +1 -0
- package/dist/cjs/operators/output.d.cts +16 -0
- package/dist/cjs/operators/pipe.cjs +9 -0
- package/dist/cjs/operators/pipe.cjs.map +1 -0
- package/dist/cjs/operators/pipe.d.cts +21 -0
- package/dist/cjs/operators/reduce.cjs +99 -0
- package/dist/cjs/operators/reduce.cjs.map +1 -0
- package/dist/cjs/operators/reduce.d.cts +14 -0
- package/dist/cjs/operators/topK.cjs +39 -0
- package/dist/cjs/operators/topK.cjs.map +1 -0
- package/dist/cjs/operators/topK.d.cts +32 -0
- package/dist/cjs/operators/topKWithFractionalIndex.cjs +218 -0
- package/dist/cjs/operators/topKWithFractionalIndex.cjs.map +1 -0
- package/dist/cjs/operators/topKWithFractionalIndex.d.cts +58 -0
- package/dist/cjs/operators/topKWithFractionalIndexBTree.d.cts +27 -0
- package/dist/cjs/types.d.cts +30 -0
- package/dist/cjs/utils.cjs +125 -0
- package/dist/cjs/utils.cjs.map +1 -0
- package/dist/cjs/utils.d.cts +40 -0
- package/dist/esm/d2.d.ts +45 -0
- package/dist/esm/d2.js +111 -0
- package/dist/esm/d2.js.map +1 -0
- package/dist/esm/graph.d.ts +57 -0
- package/dist/esm/graph.js +90 -0
- package/dist/esm/graph.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +72 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/indexes.d.ts +20 -0
- package/dist/esm/indexes.js +104 -0
- package/dist/esm/indexes.js.map +1 -0
- package/dist/esm/multiset.d.ts +36 -0
- package/dist/esm/multiset.js +173 -0
- package/dist/esm/multiset.js.map +1 -0
- package/dist/esm/operators/concat.d.ts +13 -0
- package/dist/esm/operators/concat.js +37 -0
- package/dist/esm/operators/concat.js.map +1 -0
- package/dist/esm/operators/consolidate.d.ts +12 -0
- package/dist/esm/operators/consolidate.js +40 -0
- package/dist/esm/operators/consolidate.js.map +1 -0
- package/dist/esm/operators/count.d.ts +13 -0
- package/dist/esm/operators/count.js +36 -0
- package/dist/esm/operators/count.js.map +1 -0
- package/dist/esm/operators/debug.d.ts +16 -0
- package/dist/esm/operators/debug.js +50 -0
- package/dist/esm/operators/debug.js.map +1 -0
- package/dist/esm/operators/distinct.d.ts +14 -0
- package/dist/esm/operators/distinct.js +78 -0
- package/dist/esm/operators/distinct.js.map +1 -0
- package/dist/esm/operators/filter.d.ts +16 -0
- package/dist/esm/operators/filter.js +43 -0
- package/dist/esm/operators/filter.js.map +1 -0
- package/dist/esm/operators/filterBy.d.ts +10 -0
- package/dist/esm/operators/filterBy.js +19 -0
- package/dist/esm/operators/filterBy.js.map +1 -0
- package/dist/esm/operators/groupBy.d.ts +68 -0
- package/dist/esm/operators/groupBy.js +225 -0
- package/dist/esm/operators/groupBy.js.map +1 -0
- package/dist/esm/operators/index.d.ts +18 -0
- package/dist/esm/operators/join.d.ts +48 -0
- package/dist/esm/operators/join.js +145 -0
- package/dist/esm/operators/join.js.map +1 -0
- package/dist/esm/operators/keying.d.ts +19 -0
- package/dist/esm/operators/keying.js +16 -0
- package/dist/esm/operators/keying.js.map +1 -0
- package/dist/esm/operators/map.d.ts +16 -0
- package/dist/esm/operators/map.js +43 -0
- package/dist/esm/operators/map.js.map +1 -0
- package/dist/esm/operators/negate.d.ts +13 -0
- package/dist/esm/operators/negate.js +28 -0
- package/dist/esm/operators/negate.js.map +1 -0
- package/dist/esm/operators/orderBy.d.ts +38 -0
- package/dist/esm/operators/orderBy.js +102 -0
- package/dist/esm/operators/orderBy.js.map +1 -0
- package/dist/esm/operators/orderByBTree.d.ts +3 -0
- package/dist/esm/operators/output.d.ts +16 -0
- package/dist/esm/operators/output.js +46 -0
- package/dist/esm/operators/output.js.map +1 -0
- package/dist/esm/operators/pipe.d.ts +21 -0
- package/dist/esm/operators/pipe.js +9 -0
- package/dist/esm/operators/pipe.js.map +1 -0
- package/dist/esm/operators/reduce.d.ts +14 -0
- package/dist/esm/operators/reduce.js +99 -0
- package/dist/esm/operators/reduce.js.map +1 -0
- package/dist/esm/operators/topK.d.ts +32 -0
- package/dist/esm/operators/topK.js +39 -0
- package/dist/esm/operators/topK.js.map +1 -0
- package/dist/esm/operators/topKWithFractionalIndex.d.ts +58 -0
- package/dist/esm/operators/topKWithFractionalIndex.js +218 -0
- package/dist/esm/operators/topKWithFractionalIndex.js.map +1 -0
- package/dist/esm/operators/topKWithFractionalIndexBTree.d.ts +27 -0
- package/dist/esm/types.d.ts +30 -0
- package/dist/esm/utils.d.ts +40 -0
- package/dist/esm/utils.js +125 -0
- package/dist/esm/utils.js.map +1 -0
- package/package.json +6 -7
- package/src/operators/orderBy.ts +11 -29
- package/src/operators/topKWithFractionalIndex.ts +69 -57
- package/src/operators/topKWithFractionalIndexBTree.ts +14 -19
package/src/operators/orderBy.ts
CHANGED
|
@@ -138,6 +138,9 @@ export function orderByWithFractionalIndexBase<
|
|
|
138
138
|
) => Ve,
|
|
139
139
|
options?: OrderByOptions<Ve>
|
|
140
140
|
) {
|
|
141
|
+
type KeyType = T extends KeyValue<infer K, unknown> ? K : never
|
|
142
|
+
type ValueType = T extends KeyValue<unknown, infer V> ? V : never
|
|
143
|
+
|
|
141
144
|
const limit = options?.limit ?? Infinity
|
|
142
145
|
const offset = options?.offset ?? 0
|
|
143
146
|
const comparator =
|
|
@@ -151,37 +154,16 @@ export function orderByWithFractionalIndexBase<
|
|
|
151
154
|
|
|
152
155
|
return (
|
|
153
156
|
stream: IStreamBuilder<T>
|
|
154
|
-
): IStreamBuilder<
|
|
155
|
-
KeyValue<
|
|
156
|
-
T extends KeyValue<infer K, unknown> ? K : never,
|
|
157
|
-
[T extends KeyValue<unknown, infer V> ? V : never, string]
|
|
158
|
-
>
|
|
159
|
-
> => {
|
|
160
|
-
type KeyType = T extends KeyValue<infer K, unknown> ? K : never
|
|
161
|
-
type ValueType = T extends KeyValue<unknown, infer V> ? V : never
|
|
162
|
-
|
|
157
|
+
): IStreamBuilder<[KeyType, [ValueType, string]]> => {
|
|
163
158
|
return stream.pipe(
|
|
164
|
-
|
|
165
|
-
(
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
value as T extends KeyValue<unknown, infer V> ? V : never
|
|
172
|
-
),
|
|
173
|
-
],
|
|
174
|
-
] as KeyValue<null, [KeyType, Ve]>
|
|
159
|
+
topKFunction(
|
|
160
|
+
(a: ValueType, b: ValueType) =>
|
|
161
|
+
comparator(valueExtractor(a), valueExtractor(b)),
|
|
162
|
+
{
|
|
163
|
+
limit,
|
|
164
|
+
offset,
|
|
165
|
+
}
|
|
175
166
|
),
|
|
176
|
-
topKFunction((a, b) => comparator(a[1], b[1]), {
|
|
177
|
-
limit,
|
|
178
|
-
offset,
|
|
179
|
-
}),
|
|
180
|
-
map(([_, [[key], index]]) => [key, index] as KeyValue<KeyType, string>),
|
|
181
|
-
innerJoin(stream),
|
|
182
|
-
map(([key, [index, value]]) => {
|
|
183
|
-
return [key, [value, index]] as KeyValue<KeyType, [ValueType, string]>
|
|
184
|
-
}),
|
|
185
167
|
consolidate()
|
|
186
168
|
)
|
|
187
169
|
}
|
|
@@ -2,10 +2,9 @@ import { generateKeyBetween } from "fractional-indexing"
|
|
|
2
2
|
import { DifferenceStreamWriter, UnaryOperator } from "../graph.js"
|
|
3
3
|
import { StreamBuilder } from "../d2.js"
|
|
4
4
|
import { MultiSet } from "../multiset.js"
|
|
5
|
-
import { Index } from "../indexes.js"
|
|
6
5
|
import { binarySearch, globalObjectIdGenerator } from "../utils.js"
|
|
7
6
|
import type { DifferenceStreamReader } from "../graph.js"
|
|
8
|
-
import type { IStreamBuilder,
|
|
7
|
+
import type { IStreamBuilder, PipedOperator } from "../types.js"
|
|
9
8
|
|
|
10
9
|
export interface TopKWithFractionalIndexOptions {
|
|
11
10
|
limit?: number
|
|
@@ -158,31 +157,34 @@ class TopKArray<V> implements TopK<V> {
|
|
|
158
157
|
* This operator maintains fractional indices for sorted elements
|
|
159
158
|
* and only updates indices when elements move position
|
|
160
159
|
*/
|
|
161
|
-
export class TopKWithFractionalIndexOperator<K,
|
|
162
|
-
[K,
|
|
163
|
-
[K, IndexedValue<
|
|
160
|
+
export class TopKWithFractionalIndexOperator<K, T> extends UnaryOperator<
|
|
161
|
+
[K, T],
|
|
162
|
+
[K, IndexedValue<T>]
|
|
164
163
|
> {
|
|
165
|
-
#index
|
|
164
|
+
#index: Map<K, number> = new Map() // maps keys to their multiplicity
|
|
166
165
|
|
|
167
166
|
/**
|
|
168
167
|
* topK data structure that supports insertions and deletions
|
|
169
168
|
* and returns changes to the topK.
|
|
170
169
|
*/
|
|
171
|
-
#topK: TopK<TaggedValue<
|
|
170
|
+
#topK: TopK<TaggedValue<K, T>>
|
|
172
171
|
|
|
173
172
|
constructor(
|
|
174
173
|
id: number,
|
|
175
|
-
inputA: DifferenceStreamReader<[K,
|
|
176
|
-
output: DifferenceStreamWriter<[K,
|
|
177
|
-
comparator: (a:
|
|
174
|
+
inputA: DifferenceStreamReader<[K, T]>,
|
|
175
|
+
output: DifferenceStreamWriter<[K, IndexedValue<T>]>,
|
|
176
|
+
comparator: (a: T, b: T) => number,
|
|
178
177
|
options: TopKWithFractionalIndexOptions
|
|
179
178
|
) {
|
|
180
179
|
super(id, inputA, output)
|
|
181
180
|
const limit = options.limit ?? Infinity
|
|
182
181
|
const offset = options.offset ?? 0
|
|
183
|
-
const compareTaggedValues = (
|
|
182
|
+
const compareTaggedValues = (
|
|
183
|
+
a: TaggedValue<K, T>,
|
|
184
|
+
b: TaggedValue<K, T>
|
|
185
|
+
) => {
|
|
184
186
|
// First compare on the value
|
|
185
|
-
const valueComparison = comparator(
|
|
187
|
+
const valueComparison = comparator(getVal(a), getVal(b))
|
|
186
188
|
if (valueComparison !== 0) {
|
|
187
189
|
return valueComparison
|
|
188
190
|
}
|
|
@@ -197,13 +199,13 @@ export class TopKWithFractionalIndexOperator<K, V1> extends UnaryOperator<
|
|
|
197
199
|
protected createTopK(
|
|
198
200
|
offset: number,
|
|
199
201
|
limit: number,
|
|
200
|
-
comparator: (a: TaggedValue<
|
|
201
|
-
): TopK<TaggedValue<
|
|
202
|
+
comparator: (a: TaggedValue<K, T>, b: TaggedValue<K, T>) => number
|
|
203
|
+
): TopK<TaggedValue<K, T>> {
|
|
202
204
|
return new TopKArray(offset, limit, comparator)
|
|
203
205
|
}
|
|
204
206
|
|
|
205
207
|
run(): void {
|
|
206
|
-
const result: Array<[[K,
|
|
208
|
+
const result: Array<[[K, IndexedValue<T>], number]> = []
|
|
207
209
|
for (const message of this.inputMessages()) {
|
|
208
210
|
for (const [item, multiplicity] of message.getInner()) {
|
|
209
211
|
const [key, value] = item
|
|
@@ -218,27 +220,25 @@ export class TopKWithFractionalIndexOperator<K, V1> extends UnaryOperator<
|
|
|
218
220
|
|
|
219
221
|
processElement(
|
|
220
222
|
key: K,
|
|
221
|
-
value:
|
|
223
|
+
value: T,
|
|
222
224
|
multiplicity: number,
|
|
223
|
-
result: Array<[[K,
|
|
225
|
+
result: Array<[[K, IndexedValue<T>], number]>
|
|
224
226
|
): void {
|
|
225
|
-
const oldMultiplicity = this
|
|
226
|
-
this.#index.addValue(key, [value, multiplicity])
|
|
227
|
-
const newMultiplicity = this.#index.getMultiplicity(key, value)
|
|
227
|
+
const { oldMultiplicity, newMultiplicity } = this.addKey(key, multiplicity)
|
|
228
228
|
|
|
229
|
-
let res: TopKChanges<TaggedValue<
|
|
229
|
+
let res: TopKChanges<TaggedValue<K, T>> = {
|
|
230
230
|
moveIn: null,
|
|
231
231
|
moveOut: null,
|
|
232
232
|
}
|
|
233
233
|
if (oldMultiplicity <= 0 && newMultiplicity > 0) {
|
|
234
234
|
// The value was invisible but should now be visible
|
|
235
235
|
// Need to insert it into the array of sorted values
|
|
236
|
-
const taggedValue = tagValue(value)
|
|
236
|
+
const taggedValue = tagValue(key, value)
|
|
237
237
|
res = this.#topK.insert(taggedValue)
|
|
238
238
|
} else if (oldMultiplicity > 0 && newMultiplicity <= 0) {
|
|
239
239
|
// The value was visible but should now be invisible
|
|
240
240
|
// Need to remove it from the array of sorted values
|
|
241
|
-
const taggedValue = tagValue(value)
|
|
241
|
+
const taggedValue = tagValue(key, value)
|
|
242
242
|
res = this.#topK.delete(taggedValue)
|
|
243
243
|
} else {
|
|
244
244
|
// The value was invisible and it remains invisible
|
|
@@ -247,26 +247,45 @@ export class TopKWithFractionalIndexOperator<K, V1> extends UnaryOperator<
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
if (res.moveIn) {
|
|
250
|
-
const
|
|
251
|
-
|
|
250
|
+
const index = getIndex(res.moveIn)
|
|
251
|
+
const taggedValue = getValue(res.moveIn)
|
|
252
|
+
const k = getKey(taggedValue)
|
|
253
|
+
const val = getVal(taggedValue)
|
|
254
|
+
result.push([[k, [val, index]], 1])
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
if (res.moveOut) {
|
|
255
|
-
const
|
|
256
|
-
|
|
258
|
+
const index = getIndex(res.moveOut)
|
|
259
|
+
const taggedValue = getValue(res.moveOut)
|
|
260
|
+
const k = getKey(taggedValue)
|
|
261
|
+
const val = getVal(taggedValue)
|
|
262
|
+
result.push([[k, [val, index]], -1])
|
|
257
263
|
}
|
|
258
264
|
|
|
259
265
|
return
|
|
260
266
|
}
|
|
267
|
+
|
|
268
|
+
private getMultiplicity(key: K): number {
|
|
269
|
+
return this.#index.get(key) ?? 0
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
private addKey(
|
|
273
|
+
key: K,
|
|
274
|
+
multiplicity: number
|
|
275
|
+
): { oldMultiplicity: number; newMultiplicity: number } {
|
|
276
|
+
const oldMultiplicity = this.getMultiplicity(key)
|
|
277
|
+
const newMultiplicity = oldMultiplicity + multiplicity
|
|
278
|
+
if (newMultiplicity === 0) {
|
|
279
|
+
this.#index.delete(key)
|
|
280
|
+
} else {
|
|
281
|
+
this.#index.set(key, newMultiplicity)
|
|
282
|
+
}
|
|
283
|
+
return { oldMultiplicity, newMultiplicity }
|
|
284
|
+
}
|
|
261
285
|
}
|
|
262
286
|
|
|
263
287
|
/**
|
|
264
288
|
* Limits the number of results based on a comparator, with optional offset.
|
|
265
|
-
* This works on a keyed stream, where the key is the first element of the tuple.
|
|
266
|
-
* The ordering is within a key group, i.e. elements are sorted within a key group
|
|
267
|
-
* and the limit + offset is applied to that sorted group.
|
|
268
|
-
* To order the entire stream, key by the same value for all elements such as null.
|
|
269
|
-
*
|
|
270
289
|
* Uses fractional indexing to minimize the number of changes when elements move positions.
|
|
271
290
|
* Each element is assigned a fractional index that is lexicographically sortable.
|
|
272
291
|
* When elements move, only the indices of the moved elements are updated, not all elements.
|
|
@@ -275,26 +294,22 @@ export class TopKWithFractionalIndexOperator<K, V1> extends UnaryOperator<
|
|
|
275
294
|
* @param options - An optional object containing limit and offset properties
|
|
276
295
|
* @returns A piped operator that orders the elements and limits the number of results
|
|
277
296
|
*/
|
|
278
|
-
export function topKWithFractionalIndex<
|
|
279
|
-
|
|
280
|
-
V1Type extends T extends KeyValue<KType, infer V> ? V : never,
|
|
281
|
-
T,
|
|
282
|
-
>(
|
|
283
|
-
comparator: (a: V1Type, b: V1Type) => number,
|
|
297
|
+
export function topKWithFractionalIndex<KType, T>(
|
|
298
|
+
comparator: (a: T, b: T) => number,
|
|
284
299
|
options?: TopKWithFractionalIndexOptions
|
|
285
|
-
): PipedOperator<
|
|
300
|
+
): PipedOperator<[KType, T], [KType, IndexedValue<T>]> {
|
|
286
301
|
const opts = options || {}
|
|
287
302
|
|
|
288
303
|
return (
|
|
289
|
-
stream: IStreamBuilder<T>
|
|
290
|
-
): IStreamBuilder<
|
|
291
|
-
const output = new StreamBuilder<
|
|
304
|
+
stream: IStreamBuilder<[KType, T]>
|
|
305
|
+
): IStreamBuilder<[KType, IndexedValue<T>]> => {
|
|
306
|
+
const output = new StreamBuilder<[KType, IndexedValue<T>]>(
|
|
292
307
|
stream.graph,
|
|
293
|
-
new DifferenceStreamWriter<
|
|
308
|
+
new DifferenceStreamWriter<[KType, IndexedValue<T>]>()
|
|
294
309
|
)
|
|
295
|
-
const operator = new TopKWithFractionalIndexOperator<KType,
|
|
310
|
+
const operator = new TopKWithFractionalIndexOperator<KType, T>(
|
|
296
311
|
stream.graph.getNextOperatorId(),
|
|
297
|
-
stream.connectReader()
|
|
312
|
+
stream.connectReader(),
|
|
298
313
|
output.writer,
|
|
299
314
|
comparator,
|
|
300
315
|
opts
|
|
@@ -324,24 +339,21 @@ export function getIndex<V>(indexedVal: IndexedValue<V>): FractionalIndex {
|
|
|
324
339
|
return indexedVal[1]
|
|
325
340
|
}
|
|
326
341
|
|
|
327
|
-
function mapValue<V, W>(
|
|
328
|
-
indexedVal: IndexedValue<V>,
|
|
329
|
-
f: (value: V) => W
|
|
330
|
-
): IndexedValue<W> {
|
|
331
|
-
return [f(getValue(indexedVal)), getIndex(indexedVal)]
|
|
332
|
-
}
|
|
333
|
-
|
|
334
342
|
export type Tag = number
|
|
335
|
-
export type TaggedValue<V> = [V, Tag]
|
|
343
|
+
export type TaggedValue<K, V> = [K, V, Tag]
|
|
336
344
|
|
|
337
|
-
function tagValue<V>(value: V): TaggedValue<V> {
|
|
338
|
-
return [value, globalObjectIdGenerator.getId(
|
|
345
|
+
function tagValue<K, V>(key: K, value: V): TaggedValue<K, V> {
|
|
346
|
+
return [key, value, globalObjectIdGenerator.getId(key)]
|
|
339
347
|
}
|
|
340
348
|
|
|
341
|
-
function
|
|
349
|
+
function getKey<K, V>(tieBreakerTaggedValue: TaggedValue<K, V>): K {
|
|
342
350
|
return tieBreakerTaggedValue[0]
|
|
343
351
|
}
|
|
344
352
|
|
|
345
|
-
function
|
|
353
|
+
function getVal<K, V>(tieBreakerTaggedValue: TaggedValue<K, V>): V {
|
|
346
354
|
return tieBreakerTaggedValue[1]
|
|
347
355
|
}
|
|
356
|
+
|
|
357
|
+
function getTag<K, V>(tieBreakerTaggedValue: TaggedValue<K, V>): Tag {
|
|
358
|
+
return tieBreakerTaggedValue[2]
|
|
359
|
+
}
|
|
@@ -7,8 +7,7 @@ import {
|
|
|
7
7
|
getValue,
|
|
8
8
|
indexedValue,
|
|
9
9
|
} from "./topKWithFractionalIndex.js"
|
|
10
|
-
import type { IStreamBuilder,
|
|
11
|
-
import type { DifferenceStreamReader } from "../graph.js"
|
|
10
|
+
import type { IStreamBuilder, PipedOperator } from "../types.js"
|
|
12
11
|
import type {
|
|
13
12
|
IndexedValue,
|
|
14
13
|
TaggedValue,
|
|
@@ -238,13 +237,13 @@ class TopKTree<V> implements TopK<V> {
|
|
|
238
237
|
*/
|
|
239
238
|
export class TopKWithFractionalIndexBTreeOperator<
|
|
240
239
|
K,
|
|
241
|
-
|
|
242
|
-
> extends TopKWithFractionalIndexOperator<K,
|
|
240
|
+
T,
|
|
241
|
+
> extends TopKWithFractionalIndexOperator<K, T> {
|
|
243
242
|
protected override createTopK(
|
|
244
243
|
offset: number,
|
|
245
244
|
limit: number,
|
|
246
|
-
comparator: (a: TaggedValue<
|
|
247
|
-
): TopK<TaggedValue<
|
|
245
|
+
comparator: (a: TaggedValue<K, T>, b: TaggedValue<K, T>) => number
|
|
246
|
+
): TopK<TaggedValue<K, T>> {
|
|
248
247
|
if (BTree === undefined) {
|
|
249
248
|
throw new Error(
|
|
250
249
|
`B+ tree not loaded. You need to call loadBTree() before using TopKWithFractionalIndexBTreeOperator.`
|
|
@@ -269,14 +268,10 @@ export class TopKWithFractionalIndexBTreeOperator<
|
|
|
269
268
|
* @param options - An optional object containing limit and offset properties
|
|
270
269
|
* @returns A piped operator that orders the elements and limits the number of results
|
|
271
270
|
*/
|
|
272
|
-
export function topKWithFractionalIndexBTree<
|
|
273
|
-
|
|
274
|
-
V1Type extends T extends KeyValue<KType, infer V> ? V : never,
|
|
275
|
-
T,
|
|
276
|
-
>(
|
|
277
|
-
comparator: (a: V1Type, b: V1Type) => number,
|
|
271
|
+
export function topKWithFractionalIndexBTree<KType, T>(
|
|
272
|
+
comparator: (a: T, b: T) => number,
|
|
278
273
|
options?: TopKWithFractionalIndexOptions
|
|
279
|
-
): PipedOperator<
|
|
274
|
+
): PipedOperator<[KType, T], [KType, IndexedValue<T>]> {
|
|
280
275
|
const opts = options || {}
|
|
281
276
|
|
|
282
277
|
if (BTree === undefined) {
|
|
@@ -286,15 +281,15 @@ export function topKWithFractionalIndexBTree<
|
|
|
286
281
|
}
|
|
287
282
|
|
|
288
283
|
return (
|
|
289
|
-
stream: IStreamBuilder<T>
|
|
290
|
-
): IStreamBuilder<
|
|
291
|
-
const output = new StreamBuilder<
|
|
284
|
+
stream: IStreamBuilder<[KType, T]>
|
|
285
|
+
): IStreamBuilder<[KType, IndexedValue<T>]> => {
|
|
286
|
+
const output = new StreamBuilder<[KType, IndexedValue<T>]>(
|
|
292
287
|
stream.graph,
|
|
293
|
-
new DifferenceStreamWriter<
|
|
288
|
+
new DifferenceStreamWriter<[KType, IndexedValue<T>]>()
|
|
294
289
|
)
|
|
295
|
-
const operator = new
|
|
290
|
+
const operator = new TopKWithFractionalIndexBTreeOperator<KType, T>(
|
|
296
291
|
stream.graph.getNextOperatorId(),
|
|
297
|
-
stream.connectReader()
|
|
292
|
+
stream.connectReader(),
|
|
298
293
|
output.writer,
|
|
299
294
|
comparator,
|
|
300
295
|
opts
|