qvdjs 2.2.0 → 2.2.2
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/dist/index.cjs +112 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +112 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2253,9 +2253,10 @@ function recommendedChunkFor(budget, symbolTableSize, windowRows, totalRows, col
|
|
|
2253
2253
|
}
|
|
2254
2254
|
return low;
|
|
2255
2255
|
}
|
|
2256
|
-
function validateMemoryAvailability(symbolTableSize, maxRows, totalRows, filePath, safetyFactor = 0.8, columnCount = 0, materialisesRows = true, live = null, bytesHeld = null, readBytes = null, wholeSymbols = false) {
|
|
2256
|
+
function validateMemoryAvailability(symbolTableSize, maxRows, totalRows, filePath, safetyFactor = 0.8, columnCount = 0, materialisesRows = true, live = null, bytesHeld = null, readBytes = null, wholeSymbols = false, retainedBytes = 0) {
|
|
2257
2257
|
const answer = checkMemory({
|
|
2258
2258
|
wholeSymbols,
|
|
2259
|
+
retainedBytes,
|
|
2259
2260
|
symbolTableSize,
|
|
2260
2261
|
maxRows,
|
|
2261
2262
|
totalRows,
|
|
@@ -2288,7 +2289,8 @@ function checkMemory({
|
|
|
2288
2289
|
bytesHeld = null,
|
|
2289
2290
|
readBytes = null,
|
|
2290
2291
|
measured = null,
|
|
2291
|
-
wholeSymbols = false
|
|
2292
|
+
wholeSymbols = false,
|
|
2293
|
+
retainedBytes = 0
|
|
2292
2294
|
}) {
|
|
2293
2295
|
if (typeof safetyFactor !== "number" || safetyFactor < 0 || safetyFactor > 1) {
|
|
2294
2296
|
throw new QvdValidationError("safetyFactor must be a number between 0.0 and 1.0", {
|
|
@@ -2312,7 +2314,12 @@ function checkMemory({
|
|
|
2312
2314
|
rowsLive,
|
|
2313
2315
|
wholeSymbols
|
|
2314
2316
|
);
|
|
2315
|
-
const {
|
|
2317
|
+
const {
|
|
2318
|
+
held,
|
|
2319
|
+
afterRelease: heldAfterRelease = null,
|
|
2320
|
+
forRows: heldForRows,
|
|
2321
|
+
forChunk: heldForChunk
|
|
2322
|
+
} = bytesHeld ?? noBytesHeld;
|
|
2316
2323
|
const externalMemory = estimateExternalMemory(liveRows, columnCount) + held;
|
|
2317
2324
|
const bounded = budget.candidates.map((candidate) => {
|
|
2318
2325
|
const heapOnly = candidate.source === "V8 heap limit";
|
|
@@ -2348,6 +2355,25 @@ function checkMemory({
|
|
|
2348
2355
|
const availableMemory = binding ? binding.bytes : budget.bytes;
|
|
2349
2356
|
const estimatedMemory = binding ? binding.needs : heapMemory;
|
|
2350
2357
|
const maxAllowedMemory = binding ? binding.allowed : budget.bytes * safetyFactor;
|
|
2358
|
+
const retainedIsTheReason = (() => {
|
|
2359
|
+
if (binding === null || retainedBytes <= 0) {
|
|
2360
|
+
return false;
|
|
2361
|
+
}
|
|
2362
|
+
const heapAfter = estimateMemoryUsage(
|
|
2363
|
+
Math.max(0, symbolTableSize - retainedBytes),
|
|
2364
|
+
maxRows,
|
|
2365
|
+
totalRows,
|
|
2366
|
+
columnCount,
|
|
2367
|
+
materialisesRows,
|
|
2368
|
+
rowsLive,
|
|
2369
|
+
wholeSymbols
|
|
2370
|
+
);
|
|
2371
|
+
const externalAfter = estimateExternalMemory(liveRows, columnCount) + (heldAfterRelease ?? held);
|
|
2372
|
+
return budget.candidates.every((candidate) => {
|
|
2373
|
+
const heapOnly = candidate.source === "V8 heap limit";
|
|
2374
|
+
return (heapOnly ? heapAfter : heapAfter + externalAfter) <= candidate.bytes * safetyFactor;
|
|
2375
|
+
});
|
|
2376
|
+
})();
|
|
2351
2377
|
if (binding) {
|
|
2352
2378
|
const includeExternal = !binding.heapOnly;
|
|
2353
2379
|
const rowsHeldBudget = /* @__PURE__ */ __name((rows) => maxAllowedMemory - (includeExternal ? heldForRows(rows) : 0), "rowsHeldBudget");
|
|
@@ -2394,13 +2420,17 @@ function checkMemory({
|
|
|
2394
2420
|
const knob = chunked ? "chunkSize" : "limit";
|
|
2395
2421
|
const recommendedValue = chunked ? recommendedChunk : recommendedMaxRows;
|
|
2396
2422
|
const nothingFits = recommendedValue === 0;
|
|
2423
|
+
const held2 = retainedIsTheReason;
|
|
2424
|
+
const fixedCost = held2 ? "the columns this file is holding exceed" : "the symbol table alone exceeds";
|
|
2425
|
+
const release = held2 ? `Close the file and open it again to release them, or raise ` : `Raise `;
|
|
2426
|
+
const releaseFirst = held2 ? `Close the file and open it again to release the columns it is holding, which is the direct remedy. ` : "";
|
|
2397
2427
|
let advice;
|
|
2398
2428
|
if (nothingFits) {
|
|
2399
|
-
advice = `No row count fits this budget -
|
|
2429
|
+
advice = `No row count fits this budget - ${fixedCost} it, so ${knob} cannot help. ` + (containerBound ? `${release}the container's memory limit.` : `${release}the heap with --max-old-space-size, or raise memorySafetyFactor.`);
|
|
2400
2430
|
} else if (containerBound) {
|
|
2401
|
-
advice = `The binding limit is the container's, so raising --max-old-space-size would let V8 grow past it and be killed by the OOM killer instead. Set it below the container limit, raise the limit, or hold fewer rows with ${knob} (recommended: ${formatCount(recommendedValue)} rows or less).`;
|
|
2431
|
+
advice = releaseFirst + `The binding limit is the container's, so raising --max-old-space-size would let V8 grow past it and be killed by the OOM killer instead. Set it below the container limit, raise the limit, or hold fewer rows with ${knob} (recommended: ${formatCount(recommendedValue)} rows or less).`;
|
|
2402
2432
|
} else {
|
|
2403
|
-
advice = `Try holding fewer rows using the ${knob} parameter (recommended: ${formatCount(recommendedValue)} rows or less), or raise the heap with --max-old-space-size.`;
|
|
2433
|
+
advice = releaseFirst + `Try holding fewer rows using the ${knob} parameter (recommended: ${formatCount(recommendedValue)} rows or less), or raise the heap with --max-old-space-size.`;
|
|
2404
2434
|
}
|
|
2405
2435
|
const suggestions = [];
|
|
2406
2436
|
if (!nothingFits) {
|
|
@@ -2424,10 +2454,16 @@ function checkMemory({
|
|
|
2424
2454
|
exact: symbolTableSize === 0,
|
|
2425
2455
|
suggestions,
|
|
2426
2456
|
refusal: {
|
|
2427
|
-
message: `Insufficient memory to load file safely. Symbol table: ${sizeMB}MB, Estimated memory needed: ${estimatedMB}MB, Available: ${availableMB}MB (limited by ${limitingFactor}, which bounds ${limitingScope}; considered: ${budgetBreakdown}; observed but not used: ${observedBreakdown}). ` + advice,
|
|
2457
|
+
message: `Insufficient memory to load file safely. ${retainedIsTheReason ? "Columns held" : "Symbol table"}: ${sizeMB}MB, Estimated memory needed: ${estimatedMB}MB, Available: ${availableMB}MB (limited by ${limitingFactor}, which bounds ${limitingScope}; considered: ${budgetBreakdown}; observed but not used: ${observedBreakdown}). ` + advice,
|
|
2428
2458
|
context: {
|
|
2429
2459
|
symbolTableSize,
|
|
2430
2460
|
symbolTableSizeMB: sizeMB,
|
|
2461
|
+
// Whether that figure is the file's symbol table or what an open file is still holding. A
|
|
2462
|
+
// paging read is charged for every column any of its pages decoded and kept, so a caller
|
|
2463
|
+
// branching on the refusal needs to know which of the two it is looking at - the remedies
|
|
2464
|
+
// differ, and for this one releasing is a remedy where raising the limit is only a workaround.
|
|
2465
|
+
holdsDecodedColumns: retainedIsTheReason,
|
|
2466
|
+
retainedSymbolBytes: retainedBytes,
|
|
2431
2467
|
estimatedMemoryMB: estimatedMB,
|
|
2432
2468
|
availableMemoryMB: availableMB,
|
|
2433
2469
|
heapLimitMB,
|
|
@@ -2595,19 +2631,39 @@ function validateHeaderStructure(headerObj, filePath, stage) {
|
|
|
2595
2631
|
});
|
|
2596
2632
|
return fieldList;
|
|
2597
2633
|
}
|
|
2598
|
-
function validateSymbolTableSizeEarly(symbolTableLength, filePath) {
|
|
2634
|
+
function validateSymbolTableSizeEarly(symbolTableLength, filePath, retainedBytes = 0) {
|
|
2599
2635
|
const heapLimit = getHeapLimit();
|
|
2600
2636
|
const MAX_SYMBOL_TABLE_SIZE = heapLimit * 0.125;
|
|
2601
2637
|
if (symbolTableLength > MAX_SYMBOL_TABLE_SIZE) {
|
|
2602
2638
|
const sizeMB = Math.round(symbolTableLength / 1024 / 1024);
|
|
2603
2639
|
const maxMB = Math.round(MAX_SYMBOL_TABLE_SIZE / 1024 / 1024);
|
|
2604
2640
|
const heapMB = Math.round(heapLimit / 1024 / 1024);
|
|
2641
|
+
if (retainedBytes > 0 && symbolTableLength - retainedBytes <= MAX_SYMBOL_TABLE_SIZE) {
|
|
2642
|
+
throw new QvdValidationError(
|
|
2643
|
+
`Columns held too large (${sizeMB}MB exceeds ${maxMB}MB limit). This open file is holding the columns its pages have decoded, and they have grown past the ceiling rather than the file's own symbol table being large. Limit scales with heap size (current: ${heapMB}MB, limit: 12.5% = ${maxMB}MB). Consider: (1) closing the file and opening it again, which releases what the pages decoded, (2) paging over fewer columns with fields, or (3) increasing heap size with --max-old-space-size.`,
|
|
2644
|
+
{
|
|
2645
|
+
file: filePath,
|
|
2646
|
+
symbolTableSize: symbolTableLength,
|
|
2647
|
+
symbolTableSizeMB: sizeMB,
|
|
2648
|
+
holdsDecodedColumns: true,
|
|
2649
|
+
retainedSymbolBytes: retainedBytes,
|
|
2650
|
+
maxAllowed: MAX_SYMBOL_TABLE_SIZE,
|
|
2651
|
+
maxAllowedMB: maxMB,
|
|
2652
|
+
heapLimitMB: heapMB,
|
|
2653
|
+
reason: "memory"
|
|
2654
|
+
}
|
|
2655
|
+
);
|
|
2656
|
+
}
|
|
2605
2657
|
throw new QvdValidationError(
|
|
2606
2658
|
`Symbol table too large (${sizeMB}MB exceeds ${maxMB}MB limit for lazy loading). This QVD file contains extremely high-cardinality fields. Limit scales with heap size (current: ${heapMB}MB, limit: 12.5% = ${maxMB}MB). Consider: (1) loading the full file without a row window - maxRows, limit or offset - since the symbol table is read in full either way, (2) increasing heap size with --max-old-space-size, or (3) aggregating high-cardinality fields.`,
|
|
2607
2659
|
{
|
|
2608
2660
|
file: filePath,
|
|
2609
2661
|
symbolTableSize: symbolTableLength,
|
|
2610
2662
|
symbolTableSizeMB: sizeMB,
|
|
2663
|
+
// Present and false, not absent. A caller told it can branch on this has to find it on both
|
|
2664
|
+
// refusals, or the branch reads `undefined` for the commoner of the two.
|
|
2665
|
+
holdsDecodedColumns: false,
|
|
2666
|
+
retainedSymbolBytes: retainedBytes,
|
|
2611
2667
|
maxAllowed: MAX_SYMBOL_TABLE_SIZE,
|
|
2612
2668
|
maxAllowedMB: maxMB,
|
|
2613
2669
|
heapLimitMB: heapMB,
|
|
@@ -4013,6 +4069,10 @@ var init_QvdFileReader = __esm({
|
|
|
4013
4069
|
const columnCount = selected.length;
|
|
4014
4070
|
const symbolBytes = symbolBytesOf(this._fieldsHeldAfter(selected, headerFields), symbolTableLength);
|
|
4015
4071
|
const readSymbolBytes = symbolBytesOf(this._fieldsReadBy(selected), symbolTableLength);
|
|
4072
|
+
const retainedBytes = symbolBytesOf(
|
|
4073
|
+
this._fieldsHeldAfter(selected, headerFields).slice(selected.length),
|
|
4074
|
+
symbolTableLength
|
|
4075
|
+
);
|
|
4016
4076
|
const resolved = headerNumbersUsable ? resolveWindow(window, totalRows) : { offset: 0, limit: 0 };
|
|
4017
4077
|
const windowRows = resolved.limit;
|
|
4018
4078
|
if (headerNumbersUsable && this._headerMatchesFile) {
|
|
@@ -4030,7 +4090,8 @@ var init_QvdFileReader = __esm({
|
|
|
4030
4090
|
windowRows,
|
|
4031
4091
|
recordSize,
|
|
4032
4092
|
liveRows,
|
|
4033
|
-
this._analysisAhead(window, resolved, totalRows, symbolTableLength)
|
|
4093
|
+
this._analysisAhead(window, resolved, totalRows, symbolTableLength),
|
|
4094
|
+
symbolBytes - retainedBytes
|
|
4034
4095
|
),
|
|
4035
4096
|
// What it reads, which is not what it holds - the records go through one buffer and are not
|
|
4036
4097
|
// kept. Carried so that a refusal's `check` says everything the pre-flight would have said.
|
|
@@ -4042,7 +4103,8 @@ var init_QvdFileReader = __esm({
|
|
|
4042
4103
|
// A paging read keeps whole columns, so the estimate must not discount its symbols as a window's
|
|
4043
4104
|
// sample of them - see `estimateMemoryUsage`. Under-charging is the direction that ends in a
|
|
4044
4105
|
// heap-limit abort rather than an error.
|
|
4045
|
-
this._symbolCache !== null
|
|
4106
|
+
this._symbolCache !== null,
|
|
4107
|
+
retainedBytes
|
|
4046
4108
|
);
|
|
4047
4109
|
}
|
|
4048
4110
|
if (window.offset === 0 && window.limit === null) {
|
|
@@ -4050,7 +4112,7 @@ var init_QvdFileReader = __esm({
|
|
|
4050
4112
|
return;
|
|
4051
4113
|
}
|
|
4052
4114
|
const rowsToLoad = windowRows;
|
|
4053
|
-
validateSymbolTableSizeEarly(symbolBytes, this._path);
|
|
4115
|
+
validateSymbolTableSizeEarly(symbolBytes, this._path, retainedBytes);
|
|
4054
4116
|
validateRecordSize(recordSize, this._path, "readData");
|
|
4055
4117
|
validateRecordCount(totalRows, this._path, "readData");
|
|
4056
4118
|
const fileBytesRequired = indexTableOffset + (resolved.offset + rowsToLoad) * recordSize;
|
|
@@ -4162,9 +4224,14 @@ var init_QvdFileReader = __esm({
|
|
|
4162
4224
|
* would hold.
|
|
4163
4225
|
* @private
|
|
4164
4226
|
*/
|
|
4165
|
-
_bytesHeld(symbolBytes, windowRows, recordSize, liveRows, analysisAhead) {
|
|
4227
|
+
_bytesHeld(symbolBytes, windowRows, recordSize, liveRows, analysisAhead, freshSymbolBytes = null) {
|
|
4166
4228
|
return {
|
|
4167
4229
|
held: this._bytesHeldBy(symbolBytes, this._recordsAtOnce(windowRows, liveRows, analysisAhead), recordSize),
|
|
4230
|
+
// What it would hold having closed the file and opened it again: every selected column read fresh,
|
|
4231
|
+
// because nothing is cached any more. Higher than `held`, not lower - a cached column this read
|
|
4232
|
+
// selects costs nothing to read now and would cost its area then. Without it the counterfactual
|
|
4233
|
+
// that decides whether releasing helps was answered against the warm figure and said yes too often.
|
|
4234
|
+
afterRelease: freshSymbolBytes === null ? null : this._bytesHeldBy(freshSymbolBytes, this._recordsAtOnce(windowRows, liveRows, analysisAhead), recordSize),
|
|
4168
4235
|
// A window of so many rows reads so many records at a time, and the pass that reads it ahead of the
|
|
4169
4236
|
// decode reads the same rows, so the buffer is sized from the rows either way.
|
|
4170
4237
|
forRows: /* @__PURE__ */ __name((rows) => this._bytesHeldBy(symbolBytes, rows, recordSize), "forRows"),
|
|
@@ -4790,7 +4857,8 @@ var init_QvdFileReader = __esm({
|
|
|
4790
4857
|
const symbolTableSize = this._symbolTableLength();
|
|
4791
4858
|
const plan = this._symbolAreaPlan();
|
|
4792
4859
|
const readSymbolBytes = plan.ranges.reduce((sum, range) => sum + (range.end - range.start), 0);
|
|
4793
|
-
const
|
|
4860
|
+
const retainedBytes = symbolBytesOf(this._fieldsHeldAfter(fields, allFields).slice(fields.length), symbolTableSize);
|
|
4861
|
+
const symbolBytes = readSymbolBytes + retainedBytes;
|
|
4794
4862
|
const totalRows = headerInteger(this._header["QvdTableHeader"]["NoOfRecords"]);
|
|
4795
4863
|
const recordSize = headerInteger(this._header["QvdTableHeader"]["RecordByteSize"]);
|
|
4796
4864
|
validateSymbolTableSize(symbolBytes, this._path, totalRows);
|
|
@@ -4804,11 +4872,12 @@ var init_QvdFileReader = __esm({
|
|
|
4804
4872
|
fields.length,
|
|
4805
4873
|
this._materialisesRows,
|
|
4806
4874
|
liveRows,
|
|
4807
|
-
this._bytesHeld(readSymbolBytes, rowsToLoad, recordSize, liveRows, false),
|
|
4875
|
+
this._bytesHeld(readSymbolBytes, rowsToLoad, recordSize, liveRows, false, symbolBytes - retainedBytes),
|
|
4808
4876
|
// `symbolsToKeep` is non-null exactly when the symbol-usage pass has run, and a pass that has
|
|
4809
4877
|
// run has read the window's records once already - so the read's total is two passes over them.
|
|
4810
4878
|
readSymbolBytes + readPasses(symbolsToKeep !== null) * rowsToLoad * recordSize,
|
|
4811
|
-
this._symbolCache !== null
|
|
4879
|
+
this._symbolCache !== null,
|
|
4880
|
+
retainedBytes
|
|
4812
4881
|
);
|
|
4813
4882
|
}
|
|
4814
4883
|
warnLargeSymbolTable(
|
|
@@ -5060,12 +5129,14 @@ var init_QvdFileReader = __esm({
|
|
|
5060
5129
|
* viewer scrolls to - and the header is already in hand. `parseHeaderOnly` has to have run.
|
|
5061
5130
|
*
|
|
5062
5131
|
* @param {QvdRowWindow} window The rows the read would cover, normalised.
|
|
5063
|
-
* @param {{chunkSize?: number|null, fields?: Array<string>|null, materialisesRows?: boolean
|
|
5064
|
-
* `chunkSize` for an `iterate()`; `fields` and `materialisesRows` to ask
|
|
5065
|
-
* one this reader was built for, which is what a `QvdFile` does per call
|
|
5132
|
+
* @param {{chunkSize?: number|null, fields?: Array<string>|null, materialisesRows?: boolean,
|
|
5133
|
+
* paging?: boolean}} [options] `chunkSize` for an `iterate()`; `fields` and `materialisesRows` to ask
|
|
5134
|
+
* about a read other than the one this reader was built for, which is what a `QvdFile` does per call;
|
|
5135
|
+
* `paging` to say whether the read being asked about is a paging read, which defaults to whether this
|
|
5136
|
+
* reader is one.
|
|
5066
5137
|
* @return {any} The answer - see `checkMemory`.
|
|
5067
5138
|
*/
|
|
5068
|
-
checkParsed(window, { chunkSize = null, fields = void 0, materialisesRows = void 0 } = {}) {
|
|
5139
|
+
checkParsed(window, { chunkSize = null, fields = void 0, materialisesRows = void 0, paging = this._symbolCache !== null } = {}) {
|
|
5069
5140
|
assert4(this._header && this._allFields, "The QVD file header has not been parsed.");
|
|
5070
5141
|
const header = this._header["QvdTableHeader"];
|
|
5071
5142
|
const totalRows = headerInteger(header["NoOfRecords"]);
|
|
@@ -5076,11 +5147,13 @@ var init_QvdFileReader = __esm({
|
|
|
5076
5147
|
const resolved = resolveWindow(window, totalRows);
|
|
5077
5148
|
const windowRows = resolved.limit;
|
|
5078
5149
|
const liveRows = chunkSize === null ? null : { rows: chunkSize * 2, perChunk: 2 };
|
|
5079
|
-
const analysisAhead = this.
|
|
5150
|
+
const analysisAhead = paging ? false : this._analysisWouldRun(window, resolved, totalRows, symbolTableLength);
|
|
5080
5151
|
const measured = getMemoryBudget();
|
|
5081
5152
|
const ask = /* @__PURE__ */ __name((asked, rows) => {
|
|
5082
|
-
const
|
|
5083
|
-
const
|
|
5153
|
+
const held = paging ? this._fieldsHeldAfter(asked, this._allFields) : asked;
|
|
5154
|
+
const bytes = symbolBytesOf(held, symbolTableLength);
|
|
5155
|
+
const read = symbolBytesOf(paging ? this._fieldsReadBy(asked) : asked, symbolTableLength);
|
|
5156
|
+
const retained = paging ? symbolBytesOf(held.slice(asked.length), symbolTableLength) : 0;
|
|
5084
5157
|
return checkMemory({
|
|
5085
5158
|
measured,
|
|
5086
5159
|
symbolTableSize: bytes,
|
|
@@ -5091,8 +5164,9 @@ var init_QvdFileReader = __esm({
|
|
|
5091
5164
|
materialisesRows: builds,
|
|
5092
5165
|
live: liveRows,
|
|
5093
5166
|
// A paging read keeps whole columns, so it is charged for whole columns - see `estimateMemoryUsage`.
|
|
5094
|
-
wholeSymbols:
|
|
5095
|
-
|
|
5167
|
+
wholeSymbols: paging,
|
|
5168
|
+
retainedBytes: retained,
|
|
5169
|
+
bytesHeld: this._bytesHeld(read, rows, recordSize, liveRows, analysisAhead, bytes - retained),
|
|
5096
5170
|
// What it reads from the file, which is not what it holds: the symbol areas it has still to read,
|
|
5097
5171
|
// and every record the window covers, read a slice at a time and not kept - twice over where the
|
|
5098
5172
|
// symbol-usage pass will run, since it reads them before the decode reads them again.
|
|
@@ -5425,12 +5499,16 @@ var init_QvdFile = __esm({
|
|
|
5425
5499
|
/**
|
|
5426
5500
|
* What a read of this file would cost, and whether it fits - with no I/O at all.
|
|
5427
5501
|
*
|
|
5428
|
-
*
|
|
5429
|
-
*
|
|
5502
|
+
* Without `chunkSize` it asks about a page, and answers for the page this file would read next: the
|
|
5503
|
+
* columns it names plus the ones earlier pages decoded and kept, since those are part of what the page
|
|
5504
|
+
* costs. With `chunkSize` it asks about an `iterate()` of the file instead - which this object cannot
|
|
5505
|
+
* make, but a caller holding it may want to weigh - and answers exactly as `QvdDataFrame.checkRead()`
|
|
5506
|
+
* would, from the header this file already holds rather than by reading it again.
|
|
5430
5507
|
*
|
|
5431
5508
|
* @param {{offset?: number, limit?: number|null, maxRows?: number|null, fields?: Array<string>|null,
|
|
5432
5509
|
* as?: 'rows'|'columns', chunkSize?: number|null}} [options] The read being asked about - the same
|
|
5433
|
-
* bag `rows()` takes, plus `as`
|
|
5510
|
+
* bag `rows()` takes, plus `as` to say which shape of page, and `chunkSize` to ask about an
|
|
5511
|
+
* `iterate()` of the file rather than a page.
|
|
5434
5512
|
* @return {any} The answer - `fits`, `reason`, `estimate`, `budget`, `exact`, `suggestions`.
|
|
5435
5513
|
* @throws {QvdValidationError} If the file is closed, or an option's value is not valid.
|
|
5436
5514
|
*/
|
|
@@ -5449,7 +5527,7 @@ var init_QvdFile = __esm({
|
|
|
5449
5527
|
if (chunkSize !== null) {
|
|
5450
5528
|
requireChunkSize(chunkSize, this._options.path);
|
|
5451
5529
|
}
|
|
5452
|
-
const reader = this._readers[as] ?? this._reader;
|
|
5530
|
+
const reader = chunkSize !== null ? this._reader : this._readers[as] ?? this._reader;
|
|
5453
5531
|
return reader.checkParsed(normaliseWindow(windowFrom(options), this._options.path), {
|
|
5454
5532
|
chunkSize,
|
|
5455
5533
|
// Resolved here rather than left to the reader, exactly as `_page` resolves it. A warm reader is
|
|
@@ -5458,7 +5536,12 @@ var init_QvdFile = __esm({
|
|
|
5458
5536
|
// file after a page naming one of them, it reported 27,490 bytes for a read that costs 108,160:
|
|
5459
5537
|
// understating, which is the direction that approves a read the read then refuses.
|
|
5460
5538
|
fields: options.fields === void 0 ? this._options.fields ?? null : options.fields,
|
|
5461
|
-
materialisesRows: as === "rows"
|
|
5539
|
+
materialisesRows: as === "rows",
|
|
5540
|
+
// Said outright rather than read off the reader. The header reader has paging on, because a check
|
|
5541
|
+
// made before the first page has to be priced as that page will be - so it cannot tell an `iterate()`
|
|
5542
|
+
// question from a page one by its own mode, and routing to it alone still priced the iterate as a
|
|
5543
|
+
// page wherever a bounded window would have been filtered.
|
|
5544
|
+
...chunkSize === null ? {} : { paging: false }
|
|
5462
5545
|
});
|
|
5463
5546
|
}
|
|
5464
5547
|
/**
|