qvdjs 2.0.5 → 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 +10 -6
- package/dist/index.cjs +1134 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1133 -362
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -80,6 +80,7 @@ holds.
|
|
|
80
80
|
| Rows from a file too large to hold | `QvdDataFrame.iterate(path, {chunkSize})` | Everything, but holds two chunks — a 96 MB heap against 512 MB |
|
|
81
81
|
| A few columns of a large file | `QvdColumnTable.fromQvd(path)` | Everything, but stops before building rows — 141 MiB against 385 MiB |
|
|
82
82
|
| Only the schema: names, row count, types | `QvdDataFrame.readMetadata(path)` | The header alone. Constant cost, whatever the file's size |
|
|
83
|
+
| To know whether a read will fit first | `QvdDataFrame.checkRead(path, options)` | The header alone. Answers rather than reads; a read it approves is not refused for memory |
|
|
83
84
|
|
|
84
85
|
```javascript
|
|
85
86
|
import {QvdDataFrame, QvdColumnTable} from 'qvdjs';
|
|
@@ -87,6 +88,9 @@ import {QvdDataFrame, QvdColumnTable} from 'qvdjs';
|
|
|
87
88
|
// What is in this file? Costs the same whether it is 20 KB or 20 GB.
|
|
88
89
|
const {columns, rowCount} = await QvdDataFrame.readMetadata('sales.qvd');
|
|
89
90
|
|
|
91
|
+
// Will reading it fit? Also the header alone, and every suggestion it gives has been checked.
|
|
92
|
+
const {fits, suggestions} = await QvdDataFrame.checkRead('sales.qvd');
|
|
93
|
+
|
|
90
94
|
// Sum one column without ever building a row.
|
|
91
95
|
const table = await QvdColumnTable.fromQvd('sales.qvd');
|
|
92
96
|
let total = 0;
|
|
@@ -191,12 +195,13 @@ console.log(df.loadStats);
|
|
|
191
195
|
// { symbolTableBytes, totalRows, rowsLoaded, offset, symbolFiltering, symbolsKept }
|
|
192
196
|
```
|
|
193
197
|
|
|
194
|
-
**
|
|
195
|
-
|
|
198
|
+
**The limit is memory, not file size.** A read holds the symbols of the fields it reads and what it
|
|
199
|
+
builds — the rows, or the columns — and reads the records a slice at a time rather than holding the file.
|
|
200
|
+
So a QVD of any size can be read whole when its result fits, and `iterate()` over one holds those symbols
|
|
201
|
+
and two chunks of rows. A read with `fields` never reads the other fields' symbols at all.
|
|
196
202
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
`Reached heap limit` that no `try`/`catch` can intercept:
|
|
203
|
+
A read too large to fit throws a **catchable** `QvdValidationError` carrying a row count that would have
|
|
204
|
+
fitted, instead of a fatal `Reached heap limit` that no `try`/`catch` can intercept:
|
|
200
205
|
|
|
201
206
|
```javascript
|
|
202
207
|
try {
|
|
@@ -281,7 +286,6 @@ Honest boundaries rather than an issue list — these are the ones that change w
|
|
|
281
286
|
|
|
282
287
|
| Limitation | What it means in practice |
|
|
283
288
|
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
284
|
-
| **Full loads stop at 2 GiB** | Use a windowed read or `iterate()` above that. Failure is a raw Node `RangeError`, not a `QvdError`. |
|
|
285
289
|
| **The symbol table is always parsed in full** | `{offset, limit}`, `iterate()` and `QvdColumnTable` all avoid materialising rows, but none is constant-memory in the size of a high-cardinality file. |
|
|
286
290
|
| **A killed process can leave a temporary file** | A write builds `<name>.qvdjs-<hex>.tmp` beside the QVD and removes it however the write ends — unless the process is killed outright, or the removal is itself refused, in which case the error names the file in `context.temporaryFile`. The QVD is untouched either way, and such a file can be deleted. `{atomic: false}` writes none when it rewrites a QVD that exists, and damages the QVD instead; a QVD that does not exist yet is renamed into place in either mode. |
|
|
287
291
|
| **The writer takes numbers, strings, dual values and `null`** | Anything else - a `Date`, a boolean, an array, a `QvdSymbol` - is refused with a `QvdValidationError` naming the field and the row. Convert first: a `Date` to `new QvdDual(dateToQlikSerial(date), text)`, the serial and the text Qlik shows, which is how Qlik stores a date; a boolean to `-1` and `0`, as a Qlik comparison stores it. |
|