UNPKG

@phroun/paged-buffer

Version:

High-performance buffer system for editing massive files with intelligent memory management and undo/redo capabilities

177 lines 6.29 kB
"use strict"; /** * Enhanced Page metadata with simplified line tracking (marks moved to global system) */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MarkInfo = exports.LineInfo = exports.PageInfo = void 0; const crypto = __importStar(require("crypto")); /** * Enhanced Page metadata with simplified line tracking and no marks management * (Marks are now handled globally by the page coordinate system) */ class PageInfo { constructor(pageKey, fileOffset, originalSize, checksum = null) { // Runtime state this.isDirty = false; // Has been modified this.isLoaded = false; // Currently in memory this.isDetached = false; // Conflicts with source file this.data = null; // In-memory data buffer // Simplified line tracking - just store newline positions this.newlinePositions = []; // Array of relative positions of \n characters this.linesCacheValid = false; // Whether newline positions are up to date this.pageKey = pageKey; this.fileOffset = fileOffset; this.originalSize = originalSize; this.checksum = checksum; this.currentSize = originalSize; this.lastAccess = Date.now(); } /** * Calculate fast checksum for change detection */ static calculateChecksum(data) { return crypto.createHash('md5').update(data).digest('hex'); } /** * Update page with new data and invalidate caches as needed */ updateData(data) { this.data = data; this.currentSize = data.length; this.isDirty = true; this.isLoaded = true; this.lastAccess = Date.now(); // Invalidate caches when data changes this.linesCacheValid = false; // Rebuild line information immediately for loaded pages this._rebuildLineCache(data); } /** * Rebuild the newline positions cache */ _rebuildLineCache(data) { this.newlinePositions = []; // Single pass through data to find all newlines for (let i = 0; i < data.length; i++) { if (data[i] === 0x0A) { // \n this.newlinePositions.push(i); } } this.linesCacheValid = true; } /** * Ensure line cache is valid and up to date */ ensureLineCacheValid() { if (!this.linesCacheValid && this.isLoaded && this.data) { this._rebuildLineCache(this.data); } } /** * Get the number of newlines in this page */ getNewlineCount() { this.ensureLineCacheValid(); return this.newlinePositions.length; } /** * Get global line starts contributed by this page */ getGlobalLineStarts(pageVirtualStart) { this.ensureLineCacheValid(); const starts = []; // Each newline creates a line start at position + 1 for (const nlPos of this.newlinePositions) { const globalLineStart = pageVirtualStart + nlPos + 1; starts.push(globalLineStart); } return starts; } /** * Update line cache after a modification within this page */ updateAfterModification(_offset, _deletedBytes, _insertedData) { // Invalidate cache - we'll rebuild on next access this.linesCacheValid = false; } /** * Verify page integrity against original file */ verifyIntegrity(originalData) { if (!this.checksum) return false; const currentChecksum = PageInfo.calculateChecksum(originalData); return currentChecksum === this.checksum; } /** * Get memory usage statistics for this page */ getMemoryStats() { let memoryUsed = 0; if (this.data) { memoryUsed += this.data.length; } // Newline positions memory (much smaller than before) memoryUsed += this.newlinePositions.length * 4; // 4 bytes per position return { dataSize: this.data ? this.data.length : 0, newlineCount: this.newlinePositions.length, newlinePositionsSize: this.newlinePositions.length, marksCount: 0, // No marks stored here anymore estimatedMemoryUsed: memoryUsed, isLoaded: this.isLoaded, isDirty: this.isDirty, linesCacheValid: this.linesCacheValid, marksValid: true // Always valid since no marks }; } } exports.PageInfo = PageInfo; // Backwards compatibility exports class LineInfo { constructor(startOffset, length, endsWithNewline = false) { this.startOffset = startOffset; this.length = length; this.endsWithNewline = endsWithNewline; } get endOffset() { return this.startOffset + this.length; } get contentLength() { return this.endsWithNewline ? this.length - 1 : this.length; } } exports.LineInfo = LineInfo; // Legacy class kept for compatibility but no longer used class MarkInfo { constructor(name, pageOffset, virtualAddress) { this.name = name; this.pageOffset = pageOffset; this.virtualAddress = virtualAddress; } } exports.MarkInfo = MarkInfo; //# sourceMappingURL=page-info.js.map