metaPath = $metaPath; $this->provider = $provider; // runtime liegt im selben Verzeichnis $this->runtimePath = $runTimePath; } // ===================================================== // META (Governance – unverändert lassen!) // ===================================================== public function ensureExists(): void { if (!is_file($this->metaPath)) { $this->writeMeta(1); } } public function readMeta(): ?array { if (!is_file($this->metaPath)) { return null; } return json_decode( (string) file_get_contents($this->metaPath), true ); } public function validateAgainstCurrent(): void { $meta = $this->readMeta(); $current = $this->provider ->getConfiguration() ->toStructureArray(); if ($meta === null) { return; } foreach ($current as $key => $value) { if (($meta[$key] ?? null) !== $value) { throw new \RuntimeException( 'Index structure changed. Global Reindex required.' ); } } } public function writeMetaForGlobalReindex(): void { $current = $this->readMeta(); $nextVersion = ($current['index_version'] ?? 0) + 1; $this->writeMeta($nextVersion); } public function writeMeta(int $indexVersion): void { $config = $this->provider->getConfiguration(); $payload = array_merge( [ 'index_version' => $indexVersion, 'created_at' => (new \DateTimeImmutable())->format(DATE_ATOM), ], $config->toStructureArray() ); $dir = dirname($this->metaPath); if (!is_dir($dir)) { mkdir($dir, 0777, true); } file_put_contents( $this->metaPath, json_encode( $payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES ) ); } // ===================================================== // RUNTIME (Chunk Counter etc.) // ===================================================== private function ensureRuntimeFileExists(): void { if (is_file($this->runtimePath)) { return; } $dir = dirname($this->runtimePath); if (!is_dir($dir)) { mkdir($dir, 0777, true); } $payload = [ 'chunk_count' => 0, 'last_rebuild_at' => null, ]; file_put_contents( $this->runtimePath, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) ); } public function updateRuntimeStats(int $chunkCount): void { $this->ensureRuntimeFileExists(); $payload = [ 'chunk_count' => $chunkCount, 'last_rebuild_at' => (new \DateTimeImmutable())->format(DATE_ATOM), ]; file_put_contents( $this->runtimePath, json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) ); } public function getRuntimeChunkCount(): int { $this->ensureRuntimeFileExists(); $data = json_decode( (string) file_get_contents($this->runtimePath), true ); return (int)($data['chunk_count'] ?? 0); } }