ngramFilter = $ngramFilter; $this->contentRepo = $contentRepo; $this->logger = $logger; } /** * Is the prefilter trustworthy for this term type right now? * * @param string $type 'category' or 'tag'. * @return bool True when the cache has enough entries AND covers enough of * the published terms; false on cold/insufficient coverage. */ public function isReady(string $type): bool { if ($type !== self::TYPE_CATEGORY && $type !== self::TYPE_TAG) { return false; } $cacheCount = $this->ngramFilter->getCacheCountForType($type); if ($cacheCount < self::TERM_MIN_CACHE_ENTRIES) { $this->logger->debugMessage(sprintf( "Term n-gram prefilter not ready (min entries): type=%s count=%d (need %d)", $type, $cacheCount, self::TERM_MIN_CACHE_ENTRIES )); return false; } $publishedCount = $this->publishedCountFor($type); if ($publishedCount <= 0) { // No published terms of this type: nothing to prefilter against. return false; } $ratio = $cacheCount / $publishedCount; if ($ratio < self::TERM_MIN_COVERAGE_RATIO) { $this->logger->debugMessage(sprintf( "Term n-gram prefilter not ready (low coverage): type=%s ratio=%.2f (need %.2f)", $type, $ratio, self::TERM_MIN_COVERAGE_RATIO )); return false; } return true; } /** * @param string $type * @return int Published term count for the type, or 0 on unknown type. */ private function publishedCountFor(string $type): int { $repo = $this->contentRepo; if (!is_object($repo)) { return 0; } if ($type === self::TYPE_CATEGORY && method_exists($repo, 'getPublishedCategoryCount')) { return (int)$repo->getPublishedCategoryCount(); } if ($type === self::TYPE_TAG && method_exists($repo, 'getPublishedTagCount')) { return (int)$repo->getPublishedTagCount(); } return 0; } }