const sectionKey = (key) => key .split(",") .map((value) => Math.floor(Number(value) / 16)) .join(","); /** Block positions indexed by their 16³ section without copying block values. */ export class SectionBlockMap extends Map { #sections = new Map(); constructor(entries) { super(); if (entries != null) for (const [key, value] of entries) this.set(key, value); } set(key, value) { if (!super.has(key)) this.#index(key, sectionKey(key)); return super.set(key, value); } /** Insert using a section ID already validated by the caller. */ setInSection(key, value, section) { if (!super.has(key)) this.#index(key, section); return super.set(key, value); } #index(key, section) { let keys = this.#sections.get(section); if (!keys) this.#sections.set(section, (keys = new Set())); keys.add(key); } delete(key) { if (!super.delete(key)) return false; const section = sectionKey(key), keys = this.#sections.get(section); keys.delete(key); if (!keys.size) this.#sections.delete(section); return true; } /** Remove every stored block in a section and return the number removed. */ deleteSection(section) { const keys = this.#sections.get(section); if (!keys) return 0; const count = keys.size; for (const key of keys) super.delete(key); keys.clear(); this.#sections.delete(section); return count; } clear() { super.clear(); this.#sections.clear(); } /** Live key iterator; an absent or empty section contains no stored blocks. */ keysInSection(section) { return this.#sections.get(section)?.keys() ?? [][Symbol.iterator](); } /** Sections containing stored blocks; empty loaded sections have no entries. */ loadedSectionKeys() { return this.#sections.keys(); } }