File
Blob: src/worker/git/pack/indexer/resolve/deferred.ts
| 1 | import type { PackEntryTable, ResolveOptions } from "../types"; |
| 2 | |
| 3 | import type { InPackDependencyQueue } from "./dependencies"; |
| 4 | import { throwIfAborted } from "./errors"; |
| 5 | import { resolveDeltaEntry } from "./helpers"; |
| 6 | import type { PayloadLRU } from "./payloadCache"; |
| 7 | import { type SequentialReader } from "./reader"; |
| 8 | import type { RefBaseLookup } from "./refLookup"; |
| 9 | |
| 10 | interface DrainReadyDeferredQueueArgs { |
| 11 | readyDeferred: number[]; |
| 12 | deferredQueued: Uint8Array; |
| 13 | resolved: number; |
| 14 | initialResolvedCount: number; |
| 15 | totalUnresolved: number; |
| 16 | log: ResolveOptions["log"]; |
| 17 | resolveOpts: ResolveOptions; |
| 18 | table: PackEntryTable; |
| 19 | lru: PayloadLRU; |
| 20 | reader: SequentialReader; |
| 21 | resolvedTypeCodes: Uint8Array; |
| 22 | refLookup: RefBaseLookup | null; |
| 23 | dependencyQueue?: InPackDependencyQueue; |
| 24 | baseIndex: Int32Array; |
| 25 | isBase: Uint8Array; |
| 26 | deadlines: Uint32Array; |
| 27 | } |
| 28 | |
| 29 | export async function drainReadyDeferredQueue(args: DrainReadyDeferredQueueArgs): Promise<number> { |
| 30 | for (let readyPos = 0; readyPos < args.readyDeferred.length; readyPos++) { |
| 31 | throwIfAborted(args.resolveOpts.signal, args.log, "resolve:deferred-drain"); |
| 32 | // The queue can grow while we iterate: resolving one deferred delta may |
| 33 | // publish the OID needed by additional deferred REF_DELTAs. Iterating by |
| 34 | // index lets us drain those follow-on entries in the same pass. |
| 35 | const index = args.readyDeferred[readyPos]; |
| 36 | args.deferredQueued[index] = 0; |
| 37 | if (args.table.resolved[index]) continue; |
| 38 | |
| 39 | const bi = args.baseIndex[index]; |
| 40 | if (bi < 0 || !args.table.resolved[bi]) continue; |
| 41 | |
| 42 | args.lru.setCurrentOffset(args.table.offsets[index]); |
| 43 | await resolveDeltaEntry({ |
| 44 | index, |
| 45 | resolveOpts: args.resolveOpts, |
| 46 | table: args.table, |
| 47 | lru: args.lru, |
| 48 | deltaReader: args.reader, |
| 49 | baseReader: args.reader, |
| 50 | baseIndex: args.baseIndex, |
| 51 | resolvedTypeCodes: args.resolvedTypeCodes, |
| 52 | isBase: args.isBase, |
| 53 | deadlines: args.deadlines, |
| 54 | refLookup: args.refLookup, |
| 55 | dependencyQueue: args.dependencyQueue, |
| 56 | readyDeferred: args.readyDeferred, |
| 57 | deferredQueued: args.deferredQueued, |
| 58 | }); |
| 59 | args.resolved++; |
| 60 | const newlyResolved = args.resolved - args.initialResolvedCount; |
| 61 | if (newlyResolved > 0 && newlyResolved % 10000 === 0) { |
| 62 | args.log.debug("resolve:progress", { |
| 63 | resolved: newlyResolved, |
| 64 | total: args.totalUnresolved, |
| 65 | }); |
| 66 | } |
| 67 | } |
| 68 | |
| 69 | args.readyDeferred.length = 0; |
| 70 | return args.resolved; |
| 71 | } |