@minecraft/creator-tools
Version:
Minecraft Creator Tools command line and libraries.
151 lines (150 loc) • 6 kB
TypeScript
import IFile from "../storage/IFile";
import LevelKeyValue from "./LevelKeyValue";
import { IErrorMessage, IErrorable } from "../core/IErrorable";
import LevelDbIndex, { ILevelDbFileIndex, ILevelDbLogIndex } from "./LevelDbIndex";
/**
* Options for initializing LevelDb.
*/
export interface ILevelDbInitOptions {
/** Whether to unload file content after parsing (default: true for lazy mode) */
unloadFilesAfterParse?: boolean;
/**
* Use lazy loading mode - only load manifest initially, load files on-demand.
* This dramatically reduces initial memory usage for large worlds.
* Default: false (full load for backwards compatibility)
*/
lazyLoad?: boolean;
/**
* Maximum number of keys to keep in memory when using lazy mode.
* Older keys will be evicted when this limit is reached.
* Default: 50000
*/
maxKeysInMemory?: number;
/**
* Progress callback for loading operations.
*/
progressCallback?: (phase: string, current: number, total: number) => void;
}
/**
* Represents chunk coordinates extracted from LevelDB keys.
* Used for incremental chunk updates when new LDB files are detected.
*/
export interface IChunkCoordinate {
x: number;
z: number;
dimension: number;
}
export default class LevelDb implements IErrorable {
ldbFiles: IFile[];
logFiles: IFile[];
manifestFiles: IFile[];
keys: Map<string, LevelKeyValue | false | undefined>;
isInErrorState?: boolean;
errorMessages?: IErrorMessage[];
comparator?: string;
logNumber?: number;
previousLogNumber?: number;
nextFileNumber?: number;
lastSequence?: number;
compactPointerLevels?: number[];
compactPointerStrings?: string[];
deletedFileLevel?: number[];
deletedFileNumber?: number[];
newFileLevel?: number[];
newFileNumber?: number[];
newFileSize?: number[];
newFileSmallest?: string[];
newFileLargest?: string[];
context?: string;
/** Index for lazy loading - tracks file metadata without loading content */
private _index?;
/** Whether lazy loading mode is enabled */
private _isLazyMode;
/** Maximum keys to keep in memory during lazy mode */
private _maxKeysInMemory;
/** LRU tracking for key eviction in lazy mode */
private _keyAccessOrder;
/** Set of keys that have been loaded but may be evicted */
private _loadedKeys;
/** Whether initial metadata has been loaded */
private _isInitialized;
/** Get whether lazy loading mode is enabled */
get isLazyMode(): boolean;
/** Get the file index for lazy loading */
get index(): LevelDbIndex | undefined;
/** Get the number of keys currently in memory */
get keysInMemoryCount(): number;
constructor(ldbFileArr: IFile[], logFileArr: IFile[], manifestFilesArr: IFile[], context?: string);
private _pushError;
init(log?: (message: string) => Promise<void>, options?: {
unloadFilesAfterParse?: boolean;
}): Promise<void>;
/**
* Initialize in lazy loading mode - only loads manifest metadata.
* Files are loaded on-demand when keys are requested.
*
* This dramatically reduces initial memory usage for large worlds.
* Call loadAllFiles() to fully load everything, or use getKey() for on-demand loading.
*/
initLazy(options?: ILevelDbInitOptions): Promise<void>;
/**
* Load all files in lazy mode. This is useful after initLazy() when you want
* to fully populate all keys (e.g., for world enumeration).
*
* @param options Options for loading
* @returns The number of keys loaded
*/
loadAllFiles(options?: {
progressCallback?: (phase: string, current: number, total: number) => void;
unloadFilesAfterParse?: boolean;
}): Promise<number>;
/**
* Load a specific file's keys into memory.
* Used for on-demand loading in lazy mode.
*/
loadFile(fileIndex: ILevelDbFileIndex | ILevelDbLogIndex): Promise<number>;
private _logFileParsedSizes;
/**
* Parse a new or modified LDB/LOG file and return the chunk coordinates affected.
* This is used for incremental updates when the file system detects new files.
*
* @param file The LDB or LOG file to parse
* @returns Array of unique chunk coordinates affected by keys in this file
*/
parseIncrementalFile(file: IFile): Promise<IChunkCoordinate[]>;
/**
* Extract chunk coordinates from a key name if it represents chunk data.
*/
private _extractChunkFromKey;
/**
* Evict old keys to stay under the memory limit.
* Uses LRU (least recently used) eviction.
*/
private _evictKeysIfNeeded;
/**
* Track key access for LRU eviction.
*/
private _trackKeyAccess;
/**
* Get a key's value, loading the containing file if necessary (lazy mode).
* In non-lazy mode, this is a simple map lookup.
*
* @param key The key to retrieve
* @returns The LevelKeyValue, false (if deleted), or undefined (if not found)
*/
getKey(key: string): Promise<LevelKeyValue | false | undefined>;
/**
* Clear all loaded keys and reset to just the index metadata.
* Useful for freeing memory after processing a world.
*/
clearLoadedKeys(): void;
parseLdbContent(content: Uint8Array, context?: string): number | false;
parseIndexBytes(data: Uint8Array, offset: number, length: number, indexKeys: {
[id: string]: LevelKeyValue | undefined;
}, context?: string): boolean;
parseLdbBlockBytes(data: Uint8Array, offset: number, length: number, context?: string): number;
parseLogContent(content: Uint8Array, context?: string): number;
addValueFromLog(content: Uint8Array, index: number, length: number, context?: string): number;
parseManifestContent(content: Uint8Array, context?: string): void;
addValueFromManifest(content: Uint8Array, index: number, length: number, context?: string): void;
}