@gmod/bam 7.9.1 → 8.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 +5 -1
- package/dist/bamFile.d.ts +50 -28
- package/dist/bamFile.js +99 -209
- package/dist/bamFile.js.map +1 -1
- package/dist/indexFile.d.ts +3 -3
- package/dist/indexFile.js +14 -12
- package/dist/indexFile.js.map +1 -1
- package/dist/util.d.ts +1 -21
- package/dist/util.js +6 -28
- package/dist/util.js.map +1 -1
- package/esm/bamFile.d.ts +50 -28
- package/esm/bamFile.js +99 -209
- package/esm/bamFile.js.map +1 -1
- package/esm/indexFile.d.ts +3 -3
- package/esm/indexFile.js +14 -12
- package/esm/indexFile.js.map +1 -1
- package/esm/util.d.ts +1 -21
- package/esm/util.js +4 -27
- package/esm/util.js.map +1 -1
- package/package.json +12 -11
- package/src/bamFile.ts +126 -243
- package/src/indexFile.ts +14 -12
- package/src/util.ts +4 -27
package/esm/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gmod/bam",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"packageManager": "pnpm@11.15.1",
|
|
5
5
|
"description": "Parser for BAM and BAM index (bai) files",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/GMOD/bam-js.git"
|
|
9
|
+
"url": "git+https://github.com/GMOD/bam-js.git"
|
|
10
10
|
},
|
|
11
11
|
"type": "module",
|
|
12
12
|
"sideEffects": false,
|
|
@@ -51,23 +51,24 @@
|
|
|
51
51
|
"genomics"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@gmod/bgzf-filehandle": "^6.2
|
|
54
|
+
"@gmod/bgzf-filehandle": "^6.3.2",
|
|
55
|
+
"@gmod/shared-read-cache": "^1.3.0",
|
|
55
56
|
"@jbrowse/quick-lru": "^7.3.5",
|
|
56
57
|
"crc": "^4.3.2",
|
|
57
|
-
"generic-filehandle2": "^2.2.
|
|
58
|
+
"generic-filehandle2": "^2.2.1"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
61
|
"@eslint/js": "^10.0.1",
|
|
61
|
-
"@types/node": "^25.9.
|
|
62
|
-
"@vitest/coverage-v8": "^4.1.
|
|
63
|
-
"eslint": "^10.
|
|
64
|
-
"eslint-plugin-import-x": "^4.
|
|
62
|
+
"@types/node": "^25.9.5",
|
|
63
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
64
|
+
"eslint": "^10.8.0",
|
|
65
|
+
"eslint-plugin-import-x": "^4.17.1",
|
|
65
66
|
"git-cliff": "^2.13.1",
|
|
66
|
-
"prettier": "^3.
|
|
67
|
+
"prettier": "^3.9.6",
|
|
67
68
|
"rimraf": "^6.1.3",
|
|
68
69
|
"typescript": "^6.0.3",
|
|
69
|
-
"typescript-eslint": "^8.
|
|
70
|
-
"vitest": "^4.1.
|
|
70
|
+
"typescript-eslint": "^8.65.0",
|
|
71
|
+
"vitest": "^4.1.10"
|
|
71
72
|
},
|
|
72
73
|
"publishConfig": {
|
|
73
74
|
"access": "public"
|
package/src/bamFile.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { unzip, unzipChunkSlice } from '@gmod/bgzf-filehandle'
|
|
2
|
+
import { SharedReadCache } from '@gmod/shared-read-cache'
|
|
2
3
|
import crc32 from 'crc/calculators/crc32'
|
|
3
4
|
import { LocalFile, RemoteFile } from 'generic-filehandle2'
|
|
4
5
|
|
|
@@ -63,20 +64,6 @@ interface ChunkEntry<T> {
|
|
|
63
64
|
features: T[]
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
interface InFlightChunk<T> {
|
|
67
|
-
promise: Promise<ChunkEntry<T>>
|
|
68
|
-
// Signals of the callers still waiting on this read. The read is cancelled
|
|
69
|
-
// only once every one of them has given up — see joinChunkRead and ADR 0007.
|
|
70
|
-
signals: Set<AbortSignal>
|
|
71
|
-
// true once a caller joins without a signal, which pins the read
|
|
72
|
-
pinned: boolean
|
|
73
|
-
// aborts when every caller has given up. what the read actually runs under
|
|
74
|
-
controller: AbortController
|
|
75
|
-
// aborted to take this read's listeners back off its callers' signals
|
|
76
|
-
dispose: AbortController
|
|
77
|
-
settled: boolean
|
|
78
|
-
}
|
|
79
|
-
|
|
80
67
|
/**
|
|
81
68
|
* Whether a chunk's first record already lies past `chrId:..-max`, which means
|
|
82
69
|
* every later chunk does too and none of them need to be read.
|
|
@@ -114,93 +101,31 @@ function chunkCacheKey(chunk: Chunk) {
|
|
|
114
101
|
}
|
|
115
102
|
|
|
116
103
|
// Every record in an entry is a view into its chunk's decompressed buffer, so
|
|
117
|
-
// caching one entry pins that whole buffer
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
|
|
104
|
+
// caching one entry pins that whole buffer. A count-based LRU therefore gives no
|
|
105
|
+
// bound on memory at all, which is why this budgets by decompressed bytes.
|
|
106
|
+
//
|
|
107
|
+
// Sized to hold SEVERAL of the largest query a consumer will issue, not one. A
|
|
108
|
+
// budget below a single query's working set does not merely cache less — it
|
|
109
|
+
// evicts each chunk before the next pan can reuse it, so the hit rate is zero
|
|
110
|
+
// and the re-decompress is paid every time (ADR 0014).
|
|
111
|
+
//
|
|
112
|
+
// What sets that scale is the caller's own byte gate, not how deep data can get.
|
|
113
|
+
// jbrowse compares `estimatedBytesForRegions` — COMPRESSED bytes, from the index
|
|
114
|
+
// — against its `fetchSizeLimit` and refuses to query above it. Default 5MB
|
|
115
|
+
// compressed; its own SV demo raises that to 30MB for PacBio HiFi. At the 2.1-7.3x
|
|
116
|
+
// BGZF ratios measured across the jb2bench corpus, that is 10-37MB decompressed
|
|
117
|
+
// per query at the stock gate and 63-219MB at the raised one, so six pan windows
|
|
118
|
+
// want ~219MB and ~378MB respectively. 512MB clears both.
|
|
119
|
+
//
|
|
120
|
+
// It costs a consumer on ordinary data nothing, being a ceiling rather than an
|
|
121
|
+
// allocation: 20x short-read data holds 7MB here whatever this is set to.
|
|
122
|
+
export const DEFAULT_MAX_CACHE_BYTES = 512 * 1024 * 1024
|
|
124
123
|
|
|
125
124
|
// How many of a query's chunks to read at once. Six is the HTTP/1.1
|
|
126
125
|
// per-host connection cap browsers enforce, so going much above it buys
|
|
127
126
|
// nothing on the transport that matters and only widens peak memory.
|
|
128
127
|
const MAX_CONCURRENT_CHUNK_READS = 6
|
|
129
128
|
|
|
130
|
-
class ChunkFeatureCache<T> {
|
|
131
|
-
private _maxBytes: number
|
|
132
|
-
private entries = new Map<string, ChunkEntry<T>>()
|
|
133
|
-
private bytes = 0
|
|
134
|
-
|
|
135
|
-
constructor(maxBytes: number) {
|
|
136
|
-
this._maxBytes = maxBytes
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
get maxBytes() {
|
|
140
|
-
return this._maxBytes
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Accessor rather than a plain field so lowering the budget frees memory now.
|
|
144
|
-
// As a field, a caller trimming the cache under memory pressure got nothing
|
|
145
|
-
// back until the next chunk read happened to call set().
|
|
146
|
-
set maxBytes(maxBytes: number) {
|
|
147
|
-
this._maxBytes = maxBytes
|
|
148
|
-
this.evict()
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
get size() {
|
|
152
|
-
return this.entries.size
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
get byteSize() {
|
|
156
|
-
return this.bytes
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
get(key: string) {
|
|
160
|
-
const entry = this.entries.get(key)
|
|
161
|
-
if (entry) {
|
|
162
|
-
// re-insert so Map iteration order stays least-recently-used first
|
|
163
|
-
this.entries.delete(key)
|
|
164
|
-
this.entries.set(key, entry)
|
|
165
|
-
}
|
|
166
|
-
return entry
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
set(key: string, entry: ChunkEntry<T>) {
|
|
170
|
-
this.delete(key)
|
|
171
|
-
this.entries.set(key, entry)
|
|
172
|
-
this.bytes += entry.bytes
|
|
173
|
-
this.evict()
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Evict from the least-recently-used end. The size > 1 guard means a single
|
|
177
|
-
// chunk larger than the whole budget is still kept: the caller needs it for
|
|
178
|
-
// the query in flight, and dropping it would only force a re-decompress.
|
|
179
|
-
private evict() {
|
|
180
|
-
const lru = this.entries.keys()
|
|
181
|
-
while (this.bytes > this._maxBytes && this.entries.size > 1) {
|
|
182
|
-
this.delete(lru.next().value!)
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
delete(key: string) {
|
|
187
|
-
const entry = this.entries.get(key)
|
|
188
|
-
if (entry) {
|
|
189
|
-
this.entries.delete(key)
|
|
190
|
-
this.bytes -= entry.bytes
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
clear() {
|
|
195
|
-
this.entries.clear()
|
|
196
|
-
this.bytes = 0
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
[Symbol.iterator]() {
|
|
200
|
-
return this.entries[Symbol.iterator]()
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
129
|
export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
205
130
|
public renameRefSeq: (a: string) => string
|
|
206
131
|
public bam: GenericFilehandle
|
|
@@ -210,14 +135,18 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
210
135
|
public index?: BAI | CSI
|
|
211
136
|
public htsget = false
|
|
212
137
|
public headerP?: ReturnType<BamFile<T>['getHeaderPre']>
|
|
138
|
+
/**
|
|
139
|
+
* The signal `headerP` was started under, while it is still in flight. The
|
|
140
|
+
* header is parsed once and every query awaits it, so without this the first
|
|
141
|
+
* query to arrive would own a read all the others depend on — see
|
|
142
|
+
* {@link getHeader}.
|
|
143
|
+
*/
|
|
144
|
+
private headerSignal?: AbortSignal
|
|
213
145
|
|
|
214
|
-
//
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// instead of racing. Entries live only until the read settles; the resolved
|
|
219
|
-
// features land in chunkFeatureCache.
|
|
220
|
-
private inFlightChunks = new Map<string, InFlightChunk<T>>()
|
|
146
|
+
// Parsed features by chunk, bounded by decompressed bytes. Also the
|
|
147
|
+
// in-flight map: concurrent queries for the same chunk share one read rather
|
|
148
|
+
// than racing to decompress it twice.
|
|
149
|
+
public chunkFeatureCache: SharedReadCache<Chunk, ChunkEntry<T>>
|
|
221
150
|
|
|
222
151
|
private RecordClass: BamRecordClass<T>
|
|
223
152
|
|
|
@@ -248,12 +177,38 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
248
177
|
renameRefSeqs?: (a: string) => string
|
|
249
178
|
htsget?: boolean
|
|
250
179
|
recordClass?: BamRecordClass<T>
|
|
251
|
-
/**
|
|
180
|
+
/**
|
|
181
|
+
* Budget for the parsed-chunk cache, in decompressed bytes. Defaults to
|
|
182
|
+
* {@link DEFAULT_MAX_CACHE_BYTES}.
|
|
183
|
+
*
|
|
184
|
+
* A **retention** bound, not a bound on peak memory, and the difference is
|
|
185
|
+
* not small on deep data. Three things sit outside it: a read still in
|
|
186
|
+
* flight is never evicted, and up to `MAX_CONCURRENT_CHUNK_READS` of those
|
|
187
|
+
* run at once; the last settled entry is kept whatever the budget; and a
|
|
188
|
+
* query holds every chunk it parsed until it returns, whether or not the
|
|
189
|
+
* cache still does. On 1000x long-read data a single chunk decompresses to
|
|
190
|
+
* 180MB and six in flight is 476MB, neither of which this number can bound.
|
|
191
|
+
*
|
|
192
|
+
* Set it too low and the cache does not degrade gracefully — it inverts. A
|
|
193
|
+
* budget under one query's working set evicts each chunk before the next pan
|
|
194
|
+
* reuses it, so the hit rate is zero, the full re-decompress is paid on every
|
|
195
|
+
* pan, and the memory is retained anyway. Size it to hold several queries or
|
|
196
|
+
* pass `Infinity` and bound memory some other way; do not pick a number
|
|
197
|
+
* between the two (ADR 0014).
|
|
198
|
+
*/
|
|
252
199
|
maxCacheBytes?: number
|
|
253
200
|
}) {
|
|
254
201
|
this.renameRefSeq = renameRefSeqs
|
|
255
202
|
this.RecordClass = (recordClass ?? BAMFeature) as BamRecordClass<T>
|
|
256
|
-
this.chunkFeatureCache = new
|
|
203
|
+
this.chunkFeatureCache = new SharedReadCache<Chunk, ChunkEntry<T>>({
|
|
204
|
+
maxSize: maxCacheBytes,
|
|
205
|
+
// decompressed bytes, not entry count: parsed records are views into
|
|
206
|
+
// their chunk's decompressed buffer, so a cached entry pins that whole
|
|
207
|
+
// buffer and entry count says nothing about memory
|
|
208
|
+
sizeOf: entry => entry.bytes,
|
|
209
|
+
cacheKey: chunkCacheKey,
|
|
210
|
+
fill: (chunk, signal) => this._readChunkFeatures(chunk, { signal }),
|
|
211
|
+
})
|
|
257
212
|
|
|
258
213
|
const bamFh = resolveFilehandle(bamFilehandle, bamPath, bamUrl)
|
|
259
214
|
if (bamFh) {
|
|
@@ -362,14 +317,70 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
362
317
|
return samHeader
|
|
363
318
|
}
|
|
364
319
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
320
|
+
/**
|
|
321
|
+
* Parse the header, or join the parse already running.
|
|
322
|
+
*
|
|
323
|
+
* The header is parsed once for the life of this object and every query goes
|
|
324
|
+
* through it — `getSeqId` awaits it before anything else — so it is a read
|
|
325
|
+
* shared between queries, and the third place in this file where a
|
|
326
|
+
* cancellation could leak from the query that asked for it to a query that
|
|
327
|
+
* did not. `getHeaderPre` threads `opts` into both the index parse and the
|
|
328
|
+
* BAM read, so without this the first query to arrive owns a read every other
|
|
329
|
+
* query depends on: when it pans away, every concurrent query fails with its
|
|
330
|
+
* abort even though its own signal is untouched.
|
|
331
|
+
*
|
|
332
|
+
* Same bounded retry as `IndexFile.parse`, for the same reason — the header
|
|
333
|
+
* is parsed once, so there is no repeated waste to recover — and bounded at
|
|
334
|
+
* one attempt so the pathological case is a duplicate parse rather than a
|
|
335
|
+
* recursion whose depth depends on how the aborts interleave.
|
|
336
|
+
*
|
|
337
|
+
* SYNC: ~/src/gmod/tabix-js/src/tabixIndexedFile.ts getParsedHeader — same
|
|
338
|
+
* shape for the same reason.
|
|
339
|
+
*/
|
|
340
|
+
async getHeader(
|
|
341
|
+
opts?: BaseOpts,
|
|
342
|
+
retried = false,
|
|
343
|
+
): Promise<Awaited<ReturnType<BamFile<T>['getHeaderPre']>>> {
|
|
344
|
+
throwIfAborted(opts?.signal)
|
|
345
|
+
const pending = this.headerP
|
|
346
|
+
if (!pending) {
|
|
347
|
+
return this.startHeaderParse(opts)
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// read before awaiting: the owner is forgotten as soon as the parse settles
|
|
351
|
+
const ownerSignal = this.headerSignal
|
|
352
|
+
try {
|
|
353
|
+
return await pending
|
|
354
|
+
} catch (e) {
|
|
355
|
+
if (retried || !ownerSignal?.aborted || opts?.signal?.aborted) {
|
|
369
356
|
throw e
|
|
370
|
-
}
|
|
357
|
+
}
|
|
358
|
+
return this.getHeader(opts, true)
|
|
371
359
|
}
|
|
372
|
-
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
private startHeaderParse(opts?: BaseOpts) {
|
|
363
|
+
const pending = this.getHeaderPre(opts)
|
|
364
|
+
this.headerP = pending
|
|
365
|
+
this.headerSignal = opts?.signal
|
|
366
|
+
// Drop a rejection rather than keeping it, so one transient failure does not
|
|
367
|
+
// poison the header for the lifetime of the file. Both branches are
|
|
368
|
+
// identity-checked so a retry started after this settles is not cleared by
|
|
369
|
+
// the attempt it already replaced.
|
|
370
|
+
pending.then(
|
|
371
|
+
() => {
|
|
372
|
+
if (this.headerP === pending) {
|
|
373
|
+
this.headerSignal = undefined
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
() => {
|
|
377
|
+
if (this.headerP === pending) {
|
|
378
|
+
this.headerP = undefined
|
|
379
|
+
this.headerSignal = undefined
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
)
|
|
383
|
+
return pending
|
|
373
384
|
}
|
|
374
385
|
|
|
375
386
|
async getHeaderText(opts: BaseOpts = {}) {
|
|
@@ -408,89 +419,6 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
408
419
|
return this._fetchChunkFeatures(chunks, chrId, min, max, opts)
|
|
409
420
|
}
|
|
410
421
|
|
|
411
|
-
// Read a chunk, publish it to the cache, and keep the in-flight promise
|
|
412
|
-
// discoverable while it runs.
|
|
413
|
-
//
|
|
414
|
-
// The read runs under this entry's own controller rather than any one
|
|
415
|
-
// caller's signal, because the read is shared: it must survive until every
|
|
416
|
-
// caller waiting on it has given up. joinChunkRead is what registers them.
|
|
417
|
-
private _startChunkRead(cacheKey: string, chunk: Chunk) {
|
|
418
|
-
const controller = new AbortController()
|
|
419
|
-
const promise = this._readChunkFeatures(chunk, {
|
|
420
|
-
signal: controller.signal,
|
|
421
|
-
}).then(entry => {
|
|
422
|
-
this.chunkFeatureCache.set(cacheKey, entry)
|
|
423
|
-
return entry
|
|
424
|
-
})
|
|
425
|
-
const inFlight: InFlightChunk<T> = {
|
|
426
|
-
promise,
|
|
427
|
-
signals: new Set(),
|
|
428
|
-
pinned: false,
|
|
429
|
-
controller,
|
|
430
|
-
dispose: new AbortController(),
|
|
431
|
-
settled: false,
|
|
432
|
-
}
|
|
433
|
-
this.inFlightChunks.set(cacheKey, inFlight)
|
|
434
|
-
// `.then(f, f)` rather than `.finally(f)` so the handler's own promise never
|
|
435
|
-
// carries an unhandled rejection.
|
|
436
|
-
const clear = () => {
|
|
437
|
-
inFlight.settled = true
|
|
438
|
-
// nothing reads these once the read has settled, and holding them would
|
|
439
|
-
// pin each caller's AbortController behind this entry
|
|
440
|
-
inFlight.dispose.abort()
|
|
441
|
-
inFlight.signals.clear()
|
|
442
|
-
// only clear our own entry: a later read for this chunk may have replaced it
|
|
443
|
-
if (this.inFlightChunks.get(cacheKey) === inFlight) {
|
|
444
|
-
this.inFlightChunks.delete(cacheKey)
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
promise.then(clear, clear)
|
|
448
|
-
return inFlight
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Register a caller's interest, so the read survives until that caller has
|
|
452
|
-
// given up too.
|
|
453
|
-
//
|
|
454
|
-
// A caller with no signal cannot give up, so it pins the read: there is no
|
|
455
|
-
// longer any set of aborts that should stop it. That is the honest reading of
|
|
456
|
-
// a caller that never asked to be cancellable, and it means one signal-free
|
|
457
|
-
// query makes that chunk's read uncancellable for everyone joined to it.
|
|
458
|
-
private joinChunkRead(inFlight: InFlightChunk<T>, signal?: AbortSignal) {
|
|
459
|
-
if (signal === undefined) {
|
|
460
|
-
inFlight.pinned = true
|
|
461
|
-
} else if (signal.aborted) {
|
|
462
|
-
// A caller that has already given up is not a waiter, and must not be
|
|
463
|
-
// counted as one: an `abort` listener never fires on a signal that
|
|
464
|
-
// aborted before it was added, so nothing would ever take this signal
|
|
465
|
-
// back out of the set. The count would never reach zero and the read
|
|
466
|
-
// would be uncancellable for everyone joined to it, silently.
|
|
467
|
-
//
|
|
468
|
-
// `_cachedChunkFeatures` rejects such a caller before it reaches here,
|
|
469
|
-
// with no `await` in between, so this is unreachable today. It is here
|
|
470
|
-
// because this is the bug that shipped, and an invariant that fails this
|
|
471
|
-
// quietly should not rest on a check twenty lines away. `@gmod/cram`
|
|
472
|
-
// guards the same spot for the same reason; see its ADR 0003.
|
|
473
|
-
if (!inFlight.pinned && inFlight.signals.size === 0) {
|
|
474
|
-
inFlight.controller.abort(signal.reason)
|
|
475
|
-
}
|
|
476
|
-
} else if (!inFlight.signals.has(signal)) {
|
|
477
|
-
// guarded so one signal joining twice — a viewAsPairs query reaching the
|
|
478
|
-
// same chunk for a read and for its mate — does not add two listeners
|
|
479
|
-
inFlight.signals.add(signal)
|
|
480
|
-
signal.addEventListener(
|
|
481
|
-
'abort',
|
|
482
|
-
() => {
|
|
483
|
-
inFlight.signals.delete(signal)
|
|
484
|
-
if (!inFlight.pinned && inFlight.signals.size === 0) {
|
|
485
|
-
inFlight.controller.abort(signal.reason)
|
|
486
|
-
}
|
|
487
|
-
},
|
|
488
|
-
// `once` covers the abort firing; `dispose` covers it never firing
|
|
489
|
-
{ once: true, signal: inFlight.dispose.signal },
|
|
490
|
-
)
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
422
|
// Parsed records for a chunk, reading and decompressing it only on a miss.
|
|
495
423
|
// Every path that wants a chunk's features goes through here — mate lookups
|
|
496
424
|
// included, since a viewAsPairs query revisits the same mate chunks each time
|
|
@@ -505,56 +433,11 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
505
433
|
chunk: Chunk,
|
|
506
434
|
opts: BaseOpts,
|
|
507
435
|
): Promise<T[]> {
|
|
508
|
-
//
|
|
509
|
-
//
|
|
510
|
-
//
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
// must not be registered as a waiter on someone else's: see joinChunkRead.
|
|
514
|
-
// @gmod/cram checks in exactly this position, in SliceRecordCache.getOrFill.
|
|
515
|
-
throwIfAborted(opts.signal)
|
|
516
|
-
|
|
517
|
-
const cacheKey = chunkCacheKey(chunk)
|
|
518
|
-
const cached = this.chunkFeatureCache.get(cacheKey)
|
|
519
|
-
if (cached) {
|
|
520
|
-
return cached.features
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Join a read already running for this chunk rather than decompressing it a
|
|
524
|
-
// second time. jbrowse fetches a row of adjacent blocks concurrently and
|
|
525
|
-
// they collapse onto very few chunk keys, so without this a query pays for
|
|
526
|
-
// the same inflate several times over — the dominant cost of a cold query
|
|
527
|
-
// (ADR 0003).
|
|
528
|
-
let pending = this.inFlightChunks.get(cacheKey)
|
|
529
|
-
// A read every caller has abandoned is on its way out but may not have
|
|
530
|
-
// noticed yet. Start a fresh one rather than joining one already doomed.
|
|
531
|
-
if (pending?.controller.signal.aborted && !pending.settled) {
|
|
532
|
-
if (this.inFlightChunks.get(cacheKey) === pending) {
|
|
533
|
-
this.inFlightChunks.delete(cacheKey)
|
|
534
|
-
}
|
|
535
|
-
pending = undefined
|
|
536
|
-
}
|
|
537
|
-
pending ??= this._startChunkRead(cacheKey, chunk)
|
|
538
|
-
// Only a read still running has anything to cancel. Joining a settled one
|
|
539
|
-
// would add this caller to a set nothing will ever take it out of, since
|
|
540
|
-
// the entry drops its abort listeners when it settles.
|
|
541
|
-
if (!pending.settled) {
|
|
542
|
-
this.joinChunkRead(pending, opts.signal)
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
try {
|
|
546
|
-
const entry = await pending.promise
|
|
547
|
-
// the read finished, but this caller gave up while waiting for it
|
|
548
|
-
throwIfAborted(opts.signal)
|
|
549
|
-
return entry.features
|
|
550
|
-
} catch (e) {
|
|
551
|
-
// Prefer this caller's own cancellation to whatever the shared read
|
|
552
|
-
// reported. If we asked to stop, that is the answer we want — and when
|
|
553
|
-
// the read itself was cancelled it is because we, and everyone else,
|
|
554
|
-
// asked it to.
|
|
555
|
-
throwIfAborted(opts.signal)
|
|
556
|
-
throw e
|
|
557
|
-
}
|
|
436
|
+
// The cache does the rest: one read per chunk shared by every caller that
|
|
437
|
+
// asks for it while it is in flight, cancelled only once every one of them
|
|
438
|
+
// has given up (ADR 0007), and bounded by decompressed bytes.
|
|
439
|
+
const entry = await this.chunkFeatureCache.get(chunk, opts.signal)
|
|
440
|
+
return entry.features
|
|
558
441
|
}
|
|
559
442
|
|
|
560
443
|
private async _fetchChunkFeatures(
|
package/src/indexFile.ts
CHANGED
|
@@ -53,14 +53,14 @@ export default abstract class IndexFile<
|
|
|
53
53
|
public filehandle: GenericFilehandle
|
|
54
54
|
public renameRefSeq: (s: string) => string
|
|
55
55
|
|
|
56
|
-
private
|
|
56
|
+
private parseP?: Promise<TParsed>
|
|
57
57
|
/**
|
|
58
|
-
* The signal `
|
|
58
|
+
* The signal `parseP` was started under, while it is still in flight. The
|
|
59
59
|
* index is parsed once and shared by every query against the file, so without
|
|
60
60
|
* this the first query to arrive would own a read all the others depend on —
|
|
61
61
|
* see {@link parse}.
|
|
62
62
|
*/
|
|
63
|
-
private
|
|
63
|
+
private parseSignal?: AbortSignal
|
|
64
64
|
|
|
65
65
|
constructor({
|
|
66
66
|
filehandle,
|
|
@@ -128,6 +128,8 @@ export default abstract class IndexFile<
|
|
|
128
128
|
return optimizeChunks(chunks, this.getLowestChunk(ba, min))
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
// SYNC: ~/src/gmod/tabix-js/src/indexFile.ts parse — same owner-signal
|
|
132
|
+
// tracking and one-attempt retry, and the same reasoning below.
|
|
131
133
|
/**
|
|
132
134
|
* Parse the index, or join the parse already running.
|
|
133
135
|
*
|
|
@@ -153,13 +155,13 @@ export default abstract class IndexFile<
|
|
|
153
155
|
*/
|
|
154
156
|
async parse(opts: BaseOpts = {}, retried = false): Promise<TParsed> {
|
|
155
157
|
throwIfAborted(opts.signal)
|
|
156
|
-
const pending = this.
|
|
158
|
+
const pending = this.parseP
|
|
157
159
|
if (!pending) {
|
|
158
160
|
return this.startParse(opts)
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
// read before awaiting: the owner is forgotten as soon as the parse settles
|
|
162
|
-
const ownerSignal = this.
|
|
164
|
+
const ownerSignal = this.parseSignal
|
|
163
165
|
try {
|
|
164
166
|
return await pending
|
|
165
167
|
} catch (e) {
|
|
@@ -172,22 +174,22 @@ export default abstract class IndexFile<
|
|
|
172
174
|
|
|
173
175
|
private startParse(opts: BaseOpts) {
|
|
174
176
|
const pending = this._parse(opts)
|
|
175
|
-
this.
|
|
176
|
-
this.
|
|
177
|
+
this.parseP = pending
|
|
178
|
+
this.parseSignal = opts.signal
|
|
177
179
|
// Drop a rejection rather than keeping it, so one transient failure does not
|
|
178
180
|
// poison the index for the lifetime of the file. Both branches are
|
|
179
181
|
// identity-checked so a retry started after this settles is not cleared by
|
|
180
182
|
// the attempt it already replaced.
|
|
181
183
|
pending.then(
|
|
182
184
|
() => {
|
|
183
|
-
if (this.
|
|
184
|
-
this.
|
|
185
|
+
if (this.parseP === pending) {
|
|
186
|
+
this.parseSignal = undefined
|
|
185
187
|
}
|
|
186
188
|
},
|
|
187
189
|
() => {
|
|
188
|
-
if (this.
|
|
189
|
-
this.
|
|
190
|
-
this.
|
|
190
|
+
if (this.parseP === pending) {
|
|
191
|
+
this.parseP = undefined
|
|
192
|
+
this.parseSignal = undefined
|
|
191
193
|
}
|
|
192
194
|
},
|
|
193
195
|
)
|
package/src/util.ts
CHANGED
|
@@ -39,33 +39,10 @@ export interface BaseOpts {
|
|
|
39
39
|
* underneath you. (The Chunk objects themselves are never mutated; a merged
|
|
40
40
|
* span produces a new instance.)
|
|
41
41
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
* `AbortSignal`, and callers pass duck-typed ones — `test/csi.test.ts` casts a
|
|
47
|
-
* bare `{ aborted }` through `as AbortSignal`, which is a fair model of what
|
|
48
|
-
* consumers do; calling a missing method there is a `TypeError` rather than the
|
|
49
|
-
* cancellation the caller asked for, which is a strictly worse failure.
|
|
50
|
-
*
|
|
51
|
-
* And it sets a browser floor. `AbortSignal.prototype.throwIfAborted` and
|
|
52
|
-
* `AbortSignal.reason` are Safari 15.4 / Chrome 100 / Firefox 97 (March 2022) —
|
|
53
|
-
* higher than anything else in this dependency tree needs, since
|
|
54
|
-
* `generic-filehandle2` only ever forwards a signal to `fetch`, and higher than
|
|
55
|
-
* every sibling gmod library, which use plain `.aborted`. Three lines here
|
|
56
|
-
* keeps that floor where it was.
|
|
57
|
-
*
|
|
58
|
-
* Faithful to the spec otherwise: an aborted signal throws its `reason`
|
|
59
|
-
* whatever that is, and only synthesizes an `AbortError` when there is none.
|
|
60
|
-
*/
|
|
61
|
-
export function throwIfAborted(signal?: AbortSignal) {
|
|
62
|
-
if (signal?.aborted) {
|
|
63
|
-
const { reason } = signal
|
|
64
|
-
throw reason === undefined
|
|
65
|
-
? new DOMException('This operation was aborted', 'AbortError')
|
|
66
|
-
: reason
|
|
67
|
-
}
|
|
68
|
-
}
|
|
42
|
+
// Re-exported so the internal import path stays './util.ts'. The
|
|
43
|
+
// implementation moved to @gmod/shared-read-cache, which needs it anyway --
|
|
44
|
+
// every consumer of that package was carrying an identical copy.
|
|
45
|
+
export { throwIfAborted } from '@gmod/shared-read-cache'
|
|
69
46
|
|
|
70
47
|
export function optimizeChunks(chunks: Chunk[], lowest?: OffsetCoords) {
|
|
71
48
|
const n = chunks.length
|