UNPKG

all-package-names

Version:

Fast lookup and iteration over all NPM package names

69 lines 2.68 kB
const DEFAULT_PAGE_SIZE = 16 * 1024; const DEFAULT_CACHE_PAGES = 64; /** * Small paged reader for repeated random access against a file handle. * * Pages are cached in insertion order and the oldest page is evicted when the * cache grows past `maxCachedPages`. */ export class PagedReader { pageSize; maxCachedPages; cache = new Map(); handle; constructor(handle, options = {}) { this.handle = handle; this.pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE; this.maxCachedPages = options.maxCachedPages ?? DEFAULT_CACHE_PAGES; } async read(offset, length) { if (length <= 0) { return Buffer.alloc(0); } const startPage = Math.floor(offset / this.pageSize); const endPage = Math.floor((offset + length - 1) / this.pageSize); const firstPageOffset = offset % this.pageSize; if (startPage === endPage) { const page = await this.readPage(startPage); return page.subarray(firstPageOffset, firstPageOffset + length); } const buffer = Buffer.allocUnsafe(length); let written = 0; for (let pageNumber = startPage; pageNumber <= endPage; pageNumber += 1) { const page = await this.readPage(pageNumber); const sliceStart = pageNumber === startPage ? firstPageOffset : 0; const remaining = length - written; const sliceEnd = Math.min(page.length, sliceStart + remaining); written += page.copy(buffer, written, sliceStart, sliceEnd); } return buffer; } async readByte(offset) { if (offset < 0) { return undefined; } const pageNumber = Math.floor(offset / this.pageSize); const page = await this.readPage(pageNumber); return page[offset % this.pageSize]; } async readPage(pageNumber) { const cached = this.cache.get(pageNumber); if (cached !== undefined) { this.cache.delete(pageNumber); this.cache.set(pageNumber, cached); return cached; } const buffer = Buffer.allocUnsafe(this.pageSize); const { bytesRead } = await this.handle.read(buffer, 0, this.pageSize, pageNumber * this.pageSize); const page = bytesRead === this.pageSize ? buffer : buffer.subarray(0, bytesRead); this.cache.set(pageNumber, page); if (this.cache.size > this.maxCachedPages) { const first = this.cache.keys().next(); if (!first.done) { this.cache.delete(first.value); } } return page; } } //# sourceMappingURL=paged-reader.js.map