10b1bbbbbSAndreas Gohr<?php 20b1bbbbbSAndreas Gohr 30b1bbbbbSAndreas Gohrnamespace dokuwiki\Search\Query; 40b1bbbbbSAndreas Gohr 50b1bbbbbSAndreas Gohr/** 60b1bbbbbSAndreas Gohr * A set of pages with associated scores 70b1bbbbbSAndreas Gohr * 80b1bbbbbSAndreas Gohr * Represents concrete search results where each page has a numeric score 90b1bbbbbSAndreas Gohr * (typically word frequency counts). Provides set operations for combining 100b1bbbbbSAndreas Gohr * results during query evaluation. 110b1bbbbbSAndreas Gohr */ 120b1bbbbbSAndreas Gohrclass PageSet implements StackEntry 130b1bbbbbSAndreas Gohr{ 140b1bbbbbSAndreas Gohr /** @var array<string, int> page ID => score */ 150b1bbbbbSAndreas Gohr protected array $pages; 160b1bbbbbSAndreas Gohr 170b1bbbbbSAndreas Gohr /** 180b1bbbbbSAndreas Gohr * @param array<string, int> $pages page ID => score 190b1bbbbbSAndreas Gohr */ 200b1bbbbbSAndreas Gohr public function __construct(array $pages = []) 210b1bbbbbSAndreas Gohr { 220b1bbbbbSAndreas Gohr $this->pages = $pages; 230b1bbbbbSAndreas Gohr } 240b1bbbbbSAndreas Gohr 250b1bbbbbSAndreas Gohr /** 260b1bbbbbSAndreas Gohr * @return array<string, int> page ID => score 270b1bbbbbSAndreas Gohr */ 280b1bbbbbSAndreas Gohr public function getPages(): array 290b1bbbbbSAndreas Gohr { 300b1bbbbbSAndreas Gohr return $this->pages; 310b1bbbbbSAndreas Gohr } 320b1bbbbbSAndreas Gohr 330b1bbbbbSAndreas Gohr /** 340b1bbbbbSAndreas Gohr * Intersect with another PageSet, summing scores for pages present in both 350b1bbbbbSAndreas Gohr * 360b1bbbbbSAndreas Gohr * @return self pages present in both sets 370b1bbbbbSAndreas Gohr */ 380b1bbbbbSAndreas Gohr public function intersect(PageSet $other): self 390b1bbbbbSAndreas Gohr { 400b1bbbbbSAndreas Gohr $otherPages = $other->getPages(); 410b1bbbbbSAndreas Gohr $result = []; 420b1bbbbbSAndreas Gohr foreach ($this->pages as $id => $score) { 430b1bbbbbSAndreas Gohr if (isset($otherPages[$id])) { 440b1bbbbbSAndreas Gohr $result[$id] = $score + $otherPages[$id]; 450b1bbbbbSAndreas Gohr } 460b1bbbbbSAndreas Gohr } 470b1bbbbbSAndreas Gohr return new self($result); 480b1bbbbbSAndreas Gohr } 490b1bbbbbSAndreas Gohr 500b1bbbbbSAndreas Gohr /** 510b1bbbbbSAndreas Gohr * Unite with another PageSet, summing scores where pages overlap 520b1bbbbbSAndreas Gohr * 530b1bbbbbSAndreas Gohr * @return self pages present in either set 540b1bbbbbSAndreas Gohr */ 550b1bbbbbSAndreas Gohr public function unite(PageSet $other): self 560b1bbbbbSAndreas Gohr { 570b1bbbbbSAndreas Gohr $result = $this->pages; 580b1bbbbbSAndreas Gohr foreach ($other->getPages() as $id => $score) { 590b1bbbbbSAndreas Gohr $result[$id] = ($result[$id] ?? 0) + $score; 600b1bbbbbSAndreas Gohr } 610b1bbbbbSAndreas Gohr return new self($result); 620b1bbbbbSAndreas Gohr } 630b1bbbbbSAndreas Gohr 640b1bbbbbSAndreas Gohr /** 650b1bbbbbSAndreas Gohr * Remove pages that exist in the other PageSet 660b1bbbbbSAndreas Gohr * 670b1bbbbbSAndreas Gohr * @return self pages in this set but not in $other 680b1bbbbbSAndreas Gohr */ 690b1bbbbbSAndreas Gohr public function subtract(PageSet $other): self 700b1bbbbbSAndreas Gohr { 710b1bbbbbSAndreas Gohr return new self(array_diff_key($this->pages, $other->getPages())); 720b1bbbbbSAndreas Gohr } 730b1bbbbbSAndreas Gohr 740b1bbbbbSAndreas Gohr /** 750b1bbbbbSAndreas Gohr * @return bool true if this set contains no pages 760b1bbbbbSAndreas Gohr */ 770b1bbbbbSAndreas Gohr public function isEmpty(): bool 780b1bbbbbSAndreas Gohr { 79*9369b4a9SAndreas Gohr return $this->pages === []; 800b1bbbbbSAndreas Gohr } 810b1bbbbbSAndreas Gohr} 82