rowpipe 2.0.0 → 2.1.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/README.md +238 -55
- package/dist/cli/commands/count.d.ts +12 -0
- package/dist/cli/commands/count.d.ts.map +1 -0
- package/dist/cli/commands/count.js +49 -0
- package/dist/cli/commands/count.js.map +1 -0
- package/dist/cli/commands/explain.d.ts +3 -0
- package/dist/cli/commands/explain.d.ts.map +1 -0
- package/dist/cli/commands/explain.js +11 -0
- package/dist/cli/commands/explain.js.map +1 -0
- package/dist/cli/commands/files.d.ts +2 -1
- package/dist/cli/commands/files.d.ts.map +1 -1
- package/dist/cli/commands/files.js +5 -2
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/group.d.ts +12 -0
- package/dist/cli/commands/group.d.ts.map +1 -0
- package/dist/cli/commands/group.js +51 -0
- package/dist/cli/commands/group.js.map +1 -0
- package/dist/cli/commands/head.d.ts +7 -0
- package/dist/cli/commands/head.d.ts.map +1 -0
- package/dist/cli/commands/head.js +6 -0
- package/dist/cli/commands/head.js.map +1 -0
- package/dist/cli/commands/limit.d.ts +11 -0
- package/dist/cli/commands/limit.d.ts.map +1 -0
- package/dist/cli/commands/limit.js +40 -0
- package/dist/cli/commands/limit.js.map +1 -0
- package/dist/cli/commands/offset.d.ts +11 -0
- package/dist/cli/commands/offset.d.ts.map +1 -0
- package/dist/cli/commands/offset.js +39 -0
- package/dist/cli/commands/offset.js.map +1 -0
- package/dist/cli/commands/pipeline.d.ts +43 -0
- package/dist/cli/commands/pipeline.d.ts.map +1 -0
- package/dist/cli/commands/pipeline.js +198 -0
- package/dist/cli/commands/pipeline.js.map +1 -0
- package/dist/cli/commands/sort.d.ts +17 -0
- package/dist/cli/commands/sort.d.ts.map +1 -0
- package/dist/cli/commands/sort.js +55 -0
- package/dist/cli/commands/sort.js.map +1 -0
- package/dist/cli/commands/tail.d.ts +13 -0
- package/dist/cli/commands/tail.d.ts.map +1 -0
- package/dist/cli/commands/tail.js +39 -0
- package/dist/cli/commands/tail.js.map +1 -0
- package/dist/cli/commands/top.d.ts +19 -0
- package/dist/cli/commands/top.d.ts.map +1 -0
- package/dist/cli/commands/top.js +51 -0
- package/dist/cli/commands/top.js.map +1 -0
- package/dist/cli/commands/unique.d.ts +15 -0
- package/dist/cli/commands/unique.d.ts.map +1 -0
- package/dist/cli/commands/unique.js +44 -0
- package/dist/cli/commands/unique.js.map +1 -0
- package/dist/cli/index.js +252 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/core/pipeline.d.ts +40 -0
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +65 -0
- package/dist/core/pipeline.js.map +1 -1
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/planner/executor.d.ts +8 -0
- package/dist/planner/executor.d.ts.map +1 -0
- package/dist/planner/executor.js +86 -0
- package/dist/planner/executor.js.map +1 -0
- package/dist/planner/explain.d.ts +6 -0
- package/dist/planner/explain.d.ts.map +1 -0
- package/dist/planner/explain.js +91 -0
- package/dist/planner/explain.js.map +1 -0
- package/dist/planner/index.d.ts +5 -0
- package/dist/planner/index.d.ts.map +1 -0
- package/dist/planner/index.js +5 -0
- package/dist/planner/index.js.map +1 -0
- package/dist/planner/optimizer.d.ts +9 -0
- package/dist/planner/optimizer.d.ts.map +1 -0
- package/dist/planner/optimizer.js +78 -0
- package/dist/planner/optimizer.js.map +1 -0
- package/dist/planner/types.d.ts +63 -0
- package/dist/planner/types.d.ts.map +1 -0
- package/dist/planner/types.js +2 -0
- package/dist/planner/types.js.map +1 -0
- package/dist/transforms/count.d.ts +21 -0
- package/dist/transforms/count.d.ts.map +1 -0
- package/dist/transforms/count.js +65 -0
- package/dist/transforms/count.js.map +1 -0
- package/dist/transforms/group.d.ts +25 -0
- package/dist/transforms/group.d.ts.map +1 -0
- package/dist/transforms/group.js +71 -0
- package/dist/transforms/group.js.map +1 -0
- package/dist/transforms/limit.d.ts +7 -0
- package/dist/transforms/limit.d.ts.map +1 -0
- package/dist/transforms/limit.js +40 -0
- package/dist/transforms/limit.js.map +1 -0
- package/dist/transforms/offset.d.ts +7 -0
- package/dist/transforms/offset.d.ts.map +1 -0
- package/dist/transforms/offset.js +38 -0
- package/dist/transforms/offset.js.map +1 -0
- package/dist/transforms/sort/comparator.d.ts +43 -0
- package/dist/transforms/sort/comparator.d.ts.map +1 -0
- package/dist/transforms/sort/comparator.js +131 -0
- package/dist/transforms/sort/comparator.js.map +1 -0
- package/dist/transforms/sort/external-sort.d.ts +8 -0
- package/dist/transforms/sort/external-sort.d.ts.map +1 -0
- package/dist/transforms/sort/external-sort.js +159 -0
- package/dist/transforms/sort/external-sort.js.map +1 -0
- package/dist/transforms/sort/index.d.ts +10 -0
- package/dist/transforms/sort/index.d.ts.map +1 -0
- package/dist/transforms/sort/index.js +11 -0
- package/dist/transforms/sort/index.js.map +1 -0
- package/dist/transforms/tail.d.ts +6 -0
- package/dist/transforms/tail.d.ts.map +1 -0
- package/dist/transforms/tail.js +27 -0
- package/dist/transforms/tail.js.map +1 -0
- package/dist/transforms/top.d.ts +17 -0
- package/dist/transforms/top.d.ts.map +1 -0
- package/dist/transforms/top.js +52 -0
- package/dist/transforms/top.js.map +1 -0
- package/dist/transforms/unique.d.ts +13 -0
- package/dist/transforms/unique.d.ts.map +1 -0
- package/dist/transforms/unique.js +91 -0
- package/dist/transforms/unique.js.map +1 -0
- package/dist/utils/heap.d.ts +25 -0
- package/dist/utils/heap.d.ts.map +1 -0
- package/dist/utils/heap.js +90 -0
- package/dist/utils/heap.js.map +1 -0
- package/dist/utils/keystore.d.ts +80 -0
- package/dist/utils/keystore.d.ts.map +1 -0
- package/dist/utils/keystore.js +217 -0
- package/dist/utils/keystore.js.map +1 -0
- package/dist/utils/ring-buffer.d.ts +15 -0
- package/dist/utils/ring-buffer.d.ts.map +1 -0
- package/dist/utils/ring-buffer.js +40 -0
- package/dist/utils/ring-buffer.js.map +1 -0
- package/package.json +3 -2
- package/skills/rowpipe/SKILL.md +9 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { TransformFunction } from "../core/types.js";
|
|
2
|
+
export interface UniqueOptions {
|
|
3
|
+
by?: string | string[];
|
|
4
|
+
keep?: "first" | "last";
|
|
5
|
+
memoryLimit?: number | string;
|
|
6
|
+
tempDir?: string;
|
|
7
|
+
batchSize?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Deduplicates rows by key columns (or whole row) with spillable disk backup for large cardinalities.
|
|
11
|
+
*/
|
|
12
|
+
export declare function uniqueRows(options?: UniqueOptions): TransformFunction;
|
|
13
|
+
//# sourceMappingURL=unique.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unique.d.ts","sourceRoot":"","sources":["../../src/transforms/unique.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA8B,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGtF,MAAM,WAAW,aAAa;IAC5B,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,aAAkB,GAAG,iBAAiB,CAoFzE"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { encodeCompositeKey } from "../diff/key.js";
|
|
2
|
+
import { SpillableKeyStore } from "../utils/keystore.js";
|
|
3
|
+
function getRowUniqueKey(row, byCols) {
|
|
4
|
+
if (byCols && byCols.length > 0) {
|
|
5
|
+
return encodeCompositeKey(row, byCols).encoded;
|
|
6
|
+
}
|
|
7
|
+
return JSON.stringify(row);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Deduplicates rows by key columns (or whole row) with spillable disk backup for large cardinalities.
|
|
11
|
+
*/
|
|
12
|
+
export function uniqueRows(options = {}) {
|
|
13
|
+
const keep = options.keep || "first";
|
|
14
|
+
const byCols = options.by
|
|
15
|
+
? (Array.isArray(options.by) ? options.by : options.by.split(",").map((s) => s.trim()).filter(Boolean))
|
|
16
|
+
: undefined;
|
|
17
|
+
const effectiveBatchSize = options.batchSize || 1000;
|
|
18
|
+
return (stream) => {
|
|
19
|
+
return (async function* () {
|
|
20
|
+
const keyStore = new SpillableKeyStore({
|
|
21
|
+
memoryLimit: options.memoryLimit,
|
|
22
|
+
tempDir: options.tempDir,
|
|
23
|
+
});
|
|
24
|
+
try {
|
|
25
|
+
if (keep === "first") {
|
|
26
|
+
// Streaming mode: Emit immediately on first encounter
|
|
27
|
+
let currentBatchRows = [];
|
|
28
|
+
let globalOffset = 0;
|
|
29
|
+
for await (const batch of stream) {
|
|
30
|
+
for (let i = 0; i < batch.rows.length; i++) {
|
|
31
|
+
const row = batch.rows[i];
|
|
32
|
+
const key = getRowUniqueKey(row, byCols);
|
|
33
|
+
const isNew = await keyStore.add(key);
|
|
34
|
+
if (isNew) {
|
|
35
|
+
currentBatchRows.push(row);
|
|
36
|
+
if (currentBatchRows.length >= effectiveBatchSize) {
|
|
37
|
+
yield {
|
|
38
|
+
rows: currentBatchRows,
|
|
39
|
+
offset: globalOffset,
|
|
40
|
+
};
|
|
41
|
+
globalOffset += currentBatchRows.length;
|
|
42
|
+
currentBatchRows = [];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (currentBatchRows.length > 0) {
|
|
48
|
+
yield {
|
|
49
|
+
rows: currentBatchRows,
|
|
50
|
+
offset: globalOffset,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// keep: "last" mode: Retain latest row per key
|
|
56
|
+
const latestRows = new Map();
|
|
57
|
+
let globalOffset = 0;
|
|
58
|
+
for await (const batch of stream) {
|
|
59
|
+
for (let i = 0; i < batch.rows.length; i++) {
|
|
60
|
+
const row = batch.rows[i];
|
|
61
|
+
const key = getRowUniqueKey(row, byCols);
|
|
62
|
+
latestRows.set(key, row);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let currentBatchRows = [];
|
|
66
|
+
for (const row of latestRows.values()) {
|
|
67
|
+
currentBatchRows.push(row);
|
|
68
|
+
if (currentBatchRows.length >= effectiveBatchSize) {
|
|
69
|
+
yield {
|
|
70
|
+
rows: currentBatchRows,
|
|
71
|
+
offset: globalOffset,
|
|
72
|
+
};
|
|
73
|
+
globalOffset += currentBatchRows.length;
|
|
74
|
+
currentBatchRows = [];
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (currentBatchRows.length > 0) {
|
|
78
|
+
yield {
|
|
79
|
+
rows: currentBatchRows,
|
|
80
|
+
offset: globalOffset,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
await keyStore.close();
|
|
87
|
+
}
|
|
88
|
+
})();
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=unique.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unique.js","sourceRoot":"","sources":["../../src/transforms/unique.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Binary Heap implementation supporting MinHeap, MaxHeap, and Priority Queue.
|
|
3
|
+
*/
|
|
4
|
+
export type Comparator<T> = (a: T, b: T) => number;
|
|
5
|
+
export declare class Heap<T> {
|
|
6
|
+
private data;
|
|
7
|
+
private comparator;
|
|
8
|
+
constructor(comparator: Comparator<T>);
|
|
9
|
+
get size(): number;
|
|
10
|
+
isEmpty(): boolean;
|
|
11
|
+
peek(): T | undefined;
|
|
12
|
+
push(value: T): void;
|
|
13
|
+
pop(): T | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* Replaces the root element with a new element and re-balances the heap.
|
|
16
|
+
*/
|
|
17
|
+
replace(value: T): T | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Drains all elements from the heap in sorted order.
|
|
20
|
+
*/
|
|
21
|
+
drain(): T[];
|
|
22
|
+
private bubbleUp;
|
|
23
|
+
private bubbleDown;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=heap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heap.d.ts","sourceRoot":"","sources":["../../src/utils/heap.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC;AAEnD,qBAAa,IAAI,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,UAAU,CAAgB;gBAEtB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;IAIrC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,OAAO,IAAI,OAAO;IAIlB,IAAI,IAAI,CAAC,GAAG,SAAS;IAIrB,IAAI,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI;IAKpB,GAAG,IAAI,CAAC,GAAG,SAAS;IAWpB;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IAOhC;;OAEG;IACH,KAAK,IAAI,CAAC,EAAE;IAQZ,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,UAAU;CA+BnB"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
export class Heap {
|
|
2
|
+
data = [];
|
|
3
|
+
comparator;
|
|
4
|
+
constructor(comparator) {
|
|
5
|
+
this.comparator = comparator;
|
|
6
|
+
}
|
|
7
|
+
get size() {
|
|
8
|
+
return this.data.length;
|
|
9
|
+
}
|
|
10
|
+
isEmpty() {
|
|
11
|
+
return this.data.length === 0;
|
|
12
|
+
}
|
|
13
|
+
peek() {
|
|
14
|
+
return this.data[0];
|
|
15
|
+
}
|
|
16
|
+
push(value) {
|
|
17
|
+
this.data.push(value);
|
|
18
|
+
this.bubbleUp(this.data.length - 1);
|
|
19
|
+
}
|
|
20
|
+
pop() {
|
|
21
|
+
if (this.data.length === 0)
|
|
22
|
+
return undefined;
|
|
23
|
+
const top = this.data[0];
|
|
24
|
+
const bottom = this.data.pop();
|
|
25
|
+
if (this.data.length > 0) {
|
|
26
|
+
this.data[0] = bottom;
|
|
27
|
+
this.bubbleDown(0);
|
|
28
|
+
}
|
|
29
|
+
return top;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Replaces the root element with a new element and re-balances the heap.
|
|
33
|
+
*/
|
|
34
|
+
replace(value) {
|
|
35
|
+
const top = this.data[0];
|
|
36
|
+
this.data[0] = value;
|
|
37
|
+
this.bubbleDown(0);
|
|
38
|
+
return top;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Drains all elements from the heap in sorted order.
|
|
42
|
+
*/
|
|
43
|
+
drain() {
|
|
44
|
+
const result = [];
|
|
45
|
+
while (!this.isEmpty()) {
|
|
46
|
+
result.push(this.pop());
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
bubbleUp(index) {
|
|
51
|
+
while (index > 0) {
|
|
52
|
+
const parentIdx = (index - 1) >>> 1;
|
|
53
|
+
if (this.comparator(this.data[index], this.data[parentIdx]) < 0) {
|
|
54
|
+
const temp = this.data[index];
|
|
55
|
+
this.data[index] = this.data[parentIdx];
|
|
56
|
+
this.data[parentIdx] = temp;
|
|
57
|
+
index = parentIdx;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
bubbleDown(index) {
|
|
65
|
+
const length = this.data.length;
|
|
66
|
+
while (true) {
|
|
67
|
+
const leftIdx = (index << 1) + 1;
|
|
68
|
+
const rightIdx = leftIdx + 1;
|
|
69
|
+
let smallest = index;
|
|
70
|
+
if (leftIdx < length &&
|
|
71
|
+
this.comparator(this.data[leftIdx], this.data[smallest]) < 0) {
|
|
72
|
+
smallest = leftIdx;
|
|
73
|
+
}
|
|
74
|
+
if (rightIdx < length &&
|
|
75
|
+
this.comparator(this.data[rightIdx], this.data[smallest]) < 0) {
|
|
76
|
+
smallest = rightIdx;
|
|
77
|
+
}
|
|
78
|
+
if (smallest !== index) {
|
|
79
|
+
const temp = this.data[index];
|
|
80
|
+
this.data[index] = this.data[smallest];
|
|
81
|
+
this.data[smallest] = temp;
|
|
82
|
+
index = smallest;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=heap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heap.js","sourceRoot":"","sources":["../../src/utils/heap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export interface KeyStore {
|
|
2
|
+
has(key: string): Promise<boolean>;
|
|
3
|
+
add(key: string): Promise<boolean>;
|
|
4
|
+
delete(key: string): Promise<boolean>;
|
|
5
|
+
count(): number;
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
getSpillStats?(): {
|
|
8
|
+
isSpilled: boolean;
|
|
9
|
+
spilledBytes: number;
|
|
10
|
+
entryCount: number;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export declare class MemoryKeyStore implements KeyStore {
|
|
14
|
+
private set;
|
|
15
|
+
private estimatedBytes;
|
|
16
|
+
has(key: string): Promise<boolean>;
|
|
17
|
+
add(key: string): Promise<boolean>;
|
|
18
|
+
delete(key: string): Promise<boolean>;
|
|
19
|
+
count(): number;
|
|
20
|
+
getEstimatedBytes(): number;
|
|
21
|
+
keys(): AsyncIterable<string>;
|
|
22
|
+
close(): Promise<void>;
|
|
23
|
+
getSpillStats(): {
|
|
24
|
+
isSpilled: boolean;
|
|
25
|
+
spilledBytes: number;
|
|
26
|
+
entryCount: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Disk-backed KeyStore using 256 hash partitions.
|
|
31
|
+
*/
|
|
32
|
+
export declare class DiskKeyStore implements KeyStore {
|
|
33
|
+
private tempDir;
|
|
34
|
+
private partitionSets;
|
|
35
|
+
private totalCount;
|
|
36
|
+
private spilledBytes;
|
|
37
|
+
private isClosed;
|
|
38
|
+
constructor(customTempDir?: string);
|
|
39
|
+
private ensureDir;
|
|
40
|
+
private getPartition;
|
|
41
|
+
private getPartitionFilePath;
|
|
42
|
+
private loadPartition;
|
|
43
|
+
private flushPartition;
|
|
44
|
+
has(key: string): Promise<boolean>;
|
|
45
|
+
add(key: string): Promise<boolean>;
|
|
46
|
+
delete(key: string): Promise<boolean>;
|
|
47
|
+
count(): number;
|
|
48
|
+
getSpillStats(): {
|
|
49
|
+
isSpilled: boolean;
|
|
50
|
+
spilledBytes: number;
|
|
51
|
+
entryCount: number;
|
|
52
|
+
};
|
|
53
|
+
close(): Promise<void>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Hybrid Spillable KeyStore.
|
|
57
|
+
*/
|
|
58
|
+
export declare class SpillableKeyStore implements KeyStore {
|
|
59
|
+
private memoryStore;
|
|
60
|
+
private diskStore?;
|
|
61
|
+
private memoryLimitBytes;
|
|
62
|
+
private tempDir?;
|
|
63
|
+
private isSpilled;
|
|
64
|
+
constructor(options?: {
|
|
65
|
+
memoryLimit?: number | string;
|
|
66
|
+
tempDir?: string;
|
|
67
|
+
});
|
|
68
|
+
private spillToDisk;
|
|
69
|
+
has(key: string): Promise<boolean>;
|
|
70
|
+
add(key: string): Promise<boolean>;
|
|
71
|
+
delete(key: string): Promise<boolean>;
|
|
72
|
+
count(): number;
|
|
73
|
+
getSpillStats(): {
|
|
74
|
+
isSpilled: boolean;
|
|
75
|
+
spilledBytes: number;
|
|
76
|
+
entryCount: number;
|
|
77
|
+
};
|
|
78
|
+
close(): Promise<void>;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=keystore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keystore.d.ts","sourceRoot":"","sources":["../../src/utils/keystore.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtC,KAAK,IAAI,MAAM,CAAC;IAChB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,aAAa,CAAC,IAAI;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACpF;AAED,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,cAAc,CAAK;IAErB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IASlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ3C,KAAK,IAAI,MAAM;IAIf,iBAAiB,IAAI,MAAM;IAIpB,IAAI,IAAI,aAAa,CAAC,MAAM,CAAC;IAM9B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,aAAa;;;;;CAGd;AAED;;GAEG;AACH,qBAAa,YAAa,YAAW,QAAQ;IAC3C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,QAAQ,CAAS;gBAEb,aAAa,CAAC,EAAE,MAAM;YAQpB,SAAS;IAIvB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,oBAAoB;YAId,aAAa;YAgCb,cAAc;IAUtB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAU3C,KAAK,IAAI,MAAM;IAIf,aAAa;;;;;IAIP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B;AAED;;GAEG;AACH,qBAAa,iBAAkB,YAAW,QAAQ;IAChD,OAAO,CAAC,WAAW,CAAwB;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAe;IACjC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;gBAEd,OAAO,GAAE;QAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO;YAK/D,WAAW;IAUnB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO3C,KAAK,IAAI,MAAM;IAOf,aAAa;;;;;IAOP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAM7B"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { promises as fsPromises } from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { parseMemoryLimit } from "../diff/storage/spillable-index.js";
|
|
5
|
+
export class MemoryKeyStore {
|
|
6
|
+
set = new Set();
|
|
7
|
+
estimatedBytes = 0;
|
|
8
|
+
async has(key) {
|
|
9
|
+
return this.set.has(key);
|
|
10
|
+
}
|
|
11
|
+
async add(key) {
|
|
12
|
+
if (this.set.has(key)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
this.set.add(key);
|
|
16
|
+
this.estimatedBytes += key.length * 2 + 16;
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
async delete(key) {
|
|
20
|
+
if (this.set.delete(key)) {
|
|
21
|
+
this.estimatedBytes = Math.max(0, this.estimatedBytes - (key.length * 2 + 16));
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
count() {
|
|
27
|
+
return this.set.size;
|
|
28
|
+
}
|
|
29
|
+
getEstimatedBytes() {
|
|
30
|
+
return this.estimatedBytes;
|
|
31
|
+
}
|
|
32
|
+
async *keys() {
|
|
33
|
+
for (const key of this.set) {
|
|
34
|
+
yield key;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async close() {
|
|
38
|
+
this.set.clear();
|
|
39
|
+
this.estimatedBytes = 0;
|
|
40
|
+
}
|
|
41
|
+
getSpillStats() {
|
|
42
|
+
return { isSpilled: false, spilledBytes: 0, entryCount: this.set.size };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Disk-backed KeyStore using 256 hash partitions.
|
|
47
|
+
*/
|
|
48
|
+
export class DiskKeyStore {
|
|
49
|
+
tempDir;
|
|
50
|
+
partitionSets = new Map();
|
|
51
|
+
totalCount = 0;
|
|
52
|
+
spilledBytes = 0;
|
|
53
|
+
isClosed = false;
|
|
54
|
+
constructor(customTempDir) {
|
|
55
|
+
const baseDir = customTempDir || os.tmpdir();
|
|
56
|
+
this.tempDir = path.join(baseDir, `rowpipe-keystore-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
|
|
57
|
+
}
|
|
58
|
+
async ensureDir() {
|
|
59
|
+
await fsPromises.mkdir(this.tempDir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
getPartition(key) {
|
|
62
|
+
let hash = 0;
|
|
63
|
+
for (let i = 0; i < key.length; i++) {
|
|
64
|
+
hash = (hash * 31 + key.charCodeAt(i)) >>> 0;
|
|
65
|
+
}
|
|
66
|
+
return hash % 256;
|
|
67
|
+
}
|
|
68
|
+
getPartitionFilePath(partition) {
|
|
69
|
+
return path.join(this.tempDir, `part_${partition}.txt`);
|
|
70
|
+
}
|
|
71
|
+
async loadPartition(partition) {
|
|
72
|
+
if (this.partitionSets.has(partition)) {
|
|
73
|
+
return this.partitionSets.get(partition);
|
|
74
|
+
}
|
|
75
|
+
const set = new Set();
|
|
76
|
+
const filePath = this.getPartitionFilePath(partition);
|
|
77
|
+
try {
|
|
78
|
+
const content = await fsPromises.readFile(filePath, "utf-8");
|
|
79
|
+
const lines = content.split("\n");
|
|
80
|
+
for (const line of lines) {
|
|
81
|
+
if (line.length > 0) {
|
|
82
|
+
set.add(line);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// File does not exist yet
|
|
88
|
+
}
|
|
89
|
+
// Keep active partitions bounded in memory
|
|
90
|
+
if (this.partitionSets.size >= 16) {
|
|
91
|
+
const firstKey = this.partitionSets.keys().next().value;
|
|
92
|
+
if (firstKey !== undefined) {
|
|
93
|
+
await this.flushPartition(firstKey);
|
|
94
|
+
this.partitionSets.delete(firstKey);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
this.partitionSets.set(partition, set);
|
|
98
|
+
return set;
|
|
99
|
+
}
|
|
100
|
+
async flushPartition(partition) {
|
|
101
|
+
const set = this.partitionSets.get(partition);
|
|
102
|
+
if (!set)
|
|
103
|
+
return;
|
|
104
|
+
await this.ensureDir();
|
|
105
|
+
const filePath = this.getPartitionFilePath(partition);
|
|
106
|
+
const content = Array.from(set).join("\n") + "\n";
|
|
107
|
+
await fsPromises.writeFile(filePath, content, "utf-8");
|
|
108
|
+
this.spilledBytes += Buffer.byteLength(content, "utf-8");
|
|
109
|
+
}
|
|
110
|
+
async has(key) {
|
|
111
|
+
const part = this.getPartition(key);
|
|
112
|
+
const set = await this.loadPartition(part);
|
|
113
|
+
return set.has(key);
|
|
114
|
+
}
|
|
115
|
+
async add(key) {
|
|
116
|
+
const part = this.getPartition(key);
|
|
117
|
+
const set = await this.loadPartition(part);
|
|
118
|
+
if (set.has(key)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
set.add(key);
|
|
122
|
+
this.totalCount++;
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
async delete(key) {
|
|
126
|
+
const part = this.getPartition(key);
|
|
127
|
+
const set = await this.loadPartition(part);
|
|
128
|
+
if (set.delete(key)) {
|
|
129
|
+
this.totalCount--;
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
count() {
|
|
135
|
+
return this.totalCount;
|
|
136
|
+
}
|
|
137
|
+
getSpillStats() {
|
|
138
|
+
return { isSpilled: true, spilledBytes: this.spilledBytes, entryCount: this.totalCount };
|
|
139
|
+
}
|
|
140
|
+
async close() {
|
|
141
|
+
if (this.isClosed)
|
|
142
|
+
return;
|
|
143
|
+
this.isClosed = true;
|
|
144
|
+
this.partitionSets.clear();
|
|
145
|
+
try {
|
|
146
|
+
await fsPromises.rm(this.tempDir, { recursive: true, force: true });
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Ignore cleanup error
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Hybrid Spillable KeyStore.
|
|
155
|
+
*/
|
|
156
|
+
export class SpillableKeyStore {
|
|
157
|
+
memoryStore = new MemoryKeyStore();
|
|
158
|
+
diskStore;
|
|
159
|
+
memoryLimitBytes;
|
|
160
|
+
tempDir;
|
|
161
|
+
isSpilled = false;
|
|
162
|
+
constructor(options = {}) {
|
|
163
|
+
this.memoryLimitBytes = parseMemoryLimit(options.memoryLimit, 256 * 1024 * 1024);
|
|
164
|
+
this.tempDir = options.tempDir;
|
|
165
|
+
}
|
|
166
|
+
async spillToDisk() {
|
|
167
|
+
if (this.isSpilled)
|
|
168
|
+
return;
|
|
169
|
+
this.diskStore = new DiskKeyStore(this.tempDir);
|
|
170
|
+
for await (const key of this.memoryStore.keys()) {
|
|
171
|
+
await this.diskStore.add(key);
|
|
172
|
+
}
|
|
173
|
+
await this.memoryStore.close();
|
|
174
|
+
this.isSpilled = true;
|
|
175
|
+
}
|
|
176
|
+
async has(key) {
|
|
177
|
+
if (this.isSpilled && this.diskStore) {
|
|
178
|
+
return this.diskStore.has(key);
|
|
179
|
+
}
|
|
180
|
+
return this.memoryStore.has(key);
|
|
181
|
+
}
|
|
182
|
+
async add(key) {
|
|
183
|
+
if (this.isSpilled && this.diskStore) {
|
|
184
|
+
return this.diskStore.add(key);
|
|
185
|
+
}
|
|
186
|
+
const added = await this.memoryStore.add(key);
|
|
187
|
+
if (this.memoryStore.getEstimatedBytes() >= this.memoryLimitBytes) {
|
|
188
|
+
await this.spillToDisk();
|
|
189
|
+
}
|
|
190
|
+
return added;
|
|
191
|
+
}
|
|
192
|
+
async delete(key) {
|
|
193
|
+
if (this.isSpilled && this.diskStore) {
|
|
194
|
+
return this.diskStore.delete(key);
|
|
195
|
+
}
|
|
196
|
+
return this.memoryStore.delete(key);
|
|
197
|
+
}
|
|
198
|
+
count() {
|
|
199
|
+
if (this.isSpilled && this.diskStore) {
|
|
200
|
+
return this.diskStore.count();
|
|
201
|
+
}
|
|
202
|
+
return this.memoryStore.count();
|
|
203
|
+
}
|
|
204
|
+
getSpillStats() {
|
|
205
|
+
if (this.isSpilled && this.diskStore) {
|
|
206
|
+
return this.diskStore.getSpillStats();
|
|
207
|
+
}
|
|
208
|
+
return this.memoryStore.getSpillStats();
|
|
209
|
+
}
|
|
210
|
+
async close() {
|
|
211
|
+
await this.memoryStore.close();
|
|
212
|
+
if (this.diskStore) {
|
|
213
|
+
await this.diskStore.close();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
//# sourceMappingURL=keystore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keystore.js","sourceRoot":"","sources":["../../src/utils/keystore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-capacity circular buffer with O(1) push and bounded O(N) memory complexity.
|
|
3
|
+
*/
|
|
4
|
+
export declare class RingBuffer<T> {
|
|
5
|
+
private buffer;
|
|
6
|
+
private capacity;
|
|
7
|
+
private head;
|
|
8
|
+
private length;
|
|
9
|
+
constructor(capacity: number);
|
|
10
|
+
get size(): number;
|
|
11
|
+
push(item: T): void;
|
|
12
|
+
toArray(): T[];
|
|
13
|
+
clear(): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=ring-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/utils/ring-buffer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,UAAU,CAAC,CAAC;IACvB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAEP,QAAQ,EAAE,MAAM;IAK5B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAUnB,OAAO,IAAI,CAAC,EAAE;IASd,KAAK,IAAI,IAAI;CAKd"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed-capacity circular buffer with O(1) push and bounded O(N) memory complexity.
|
|
3
|
+
*/
|
|
4
|
+
export class RingBuffer {
|
|
5
|
+
buffer;
|
|
6
|
+
capacity;
|
|
7
|
+
head = 0;
|
|
8
|
+
length = 0;
|
|
9
|
+
constructor(capacity) {
|
|
10
|
+
this.capacity = Math.max(1, capacity);
|
|
11
|
+
this.buffer = new Array(this.capacity);
|
|
12
|
+
}
|
|
13
|
+
get size() {
|
|
14
|
+
return this.length;
|
|
15
|
+
}
|
|
16
|
+
push(item) {
|
|
17
|
+
const index = (this.head + this.length) % this.capacity;
|
|
18
|
+
this.buffer[index] = item;
|
|
19
|
+
if (this.length < this.capacity) {
|
|
20
|
+
this.length++;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
this.head = (this.head + 1) % this.capacity;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
toArray() {
|
|
27
|
+
const result = new Array(this.length);
|
|
28
|
+
for (let i = 0; i < this.length; i++) {
|
|
29
|
+
const index = (this.head + i) % this.capacity;
|
|
30
|
+
result[i] = this.buffer[index];
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
clear() {
|
|
35
|
+
this.head = 0;
|
|
36
|
+
this.length = 0;
|
|
37
|
+
this.buffer.fill(undefined);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ring-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ring-buffer.js","sourceRoot":"","sources":["../../src/utils/ring-buffer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,UAAU;IACb,MAAM,CAAuB;IAC7B,QAAQ,CAAS;IACjB,IAAI,GAAG,CAAC,CAAC;IACT,MAAM,GAAG,CAAC,CAAC;IAEnB,YAAY,QAAgB;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,IAAO;QACV,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,OAAO;QACL,MAAM,MAAM,GAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACrC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC9C,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAM,CAAC;QACtC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rowpipe",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Stream-first tabular data toolkit for CSV, TSV, JSON, JSONL, XLSX, Apache Parquet, and Markdown",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"test:watch": "vitest",
|
|
21
21
|
"bench": "tsx benchmarks/memory-bench.ts",
|
|
22
22
|
"benchmark:diff": "tsx benchmarks/diff-bench.ts",
|
|
23
|
-
"benchmark:files": "tsx benchmarks/files-bench.ts"
|
|
23
|
+
"benchmark:files": "tsx benchmarks/files-bench.ts",
|
|
24
|
+
"benchmark:ops": "tsx benchmarks/operations-bench.ts"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"csv",
|
package/skills/rowpipe/SKILL.md
CHANGED
|
@@ -20,6 +20,15 @@ Rowpipe is a high-performance, stream-first command-line toolkit and Node.js lib
|
|
|
20
20
|
| **Map** | `rowpipe map <file> "<col1=expr1>" "<col2=expr2>"` | Derive and compute columns per row with arithmetic/JSON dot-notation |
|
|
21
21
|
| **Filter** | `rowpipe filter <file> "<expression>"` | Filter rows using safe expression engine and pipe syntax (`\|`) |
|
|
22
22
|
| **Reduce** | `rowpipe reduce <file> "<agg1=func(col)>" [--by <cols>]` | Global & group-by streaming aggregations (`sum`, `avg`, `min`, `max`, `count`, `countDistinct`, `stddev`) |
|
|
23
|
+
| **Limit / Head** | `rowpipe limit <file> <n>` / `rowpipe head <file> [-n <n>]` | Emit first N rows with early upstream stream cancellation |
|
|
24
|
+
| **Offset** | `rowpipe offset <file> <n>` | Skip first N rows without scanning remainder |
|
|
25
|
+
| **Tail** | `rowpipe tail <file> [-n <n>]` | Emit last N rows using bounded $O(N)$ circular ring buffer |
|
|
26
|
+
| **Sort** | `rowpipe sort <file> --by <cols> [--memory-limit <m>]` | Multi-column typed external merge sort with disk run spilling and $K$-way min-heap |
|
|
27
|
+
| **Top** | `rowpipe top <file> --by <cols> [-n <n>]` | Extract Top-K largest/smallest records using bounded $O(K)$ heap |
|
|
28
|
+
| **Unique** | `rowpipe unique <file> [--by <cols>] [--keep first\|last]` | Deduplicate rows by key columns or entire rows with spillable hash key store |
|
|
29
|
+
| **Count** | `rowpipe count <file> [--by <cols>] [--distinct <col>]` | Ultra-fast row total, distinct count (HyperLogLog), or group-count |
|
|
30
|
+
| **Group** | `rowpipe group <file> --by <cols> [--count] [--sum <c>]` | Group tabular streams with hash accumulation and multi-column aggregations |
|
|
31
|
+
| **Explain** | `rowpipe explain <file> [pipeline flags]` | Visualize planned execution pipeline and rule-based optimizations |
|
|
23
32
|
| **Select** | `rowpipe select <file> <col1,col2,...>` | Project subset of columns in order |
|
|
24
33
|
| **Rename** | `rowpipe rename <file> <old1=new1> <old2=new2>` | Rename columns in stream |
|
|
25
34
|
| **Cast** | `rowpipe cast <file> <col1:type> [--on-error null]` | Stream cast types (`integer`, `number`, `boolean`, `date`) |
|