1<?php 2 3namespace dokuwiki\Search\Query; 4 5/** 6 * A set of pages with associated scores 7 * 8 * Represents concrete search results where each page has a numeric score 9 * (typically word frequency counts). Provides set operations for combining 10 * results during query evaluation. 11 */ 12class PageSet implements StackEntry 13{ 14 /** @var array<string, int> page ID => score */ 15 protected array $pages; 16 17 /** 18 * @param array<string, int> $pages page ID => score 19 */ 20 public function __construct(array $pages = []) 21 { 22 $this->pages = $pages; 23 } 24 25 /** 26 * @return array<string, int> page ID => score 27 */ 28 public function getPages(): array 29 { 30 return $this->pages; 31 } 32 33 /** 34 * Intersect with another PageSet, summing scores for pages present in both 35 * 36 * @return self pages present in both sets 37 */ 38 public function intersect(PageSet $other): self 39 { 40 $otherPages = $other->getPages(); 41 $result = []; 42 foreach ($this->pages as $id => $score) { 43 if (isset($otherPages[$id])) { 44 $result[$id] = $score + $otherPages[$id]; 45 } 46 } 47 return new self($result); 48 } 49 50 /** 51 * Unite with another PageSet, summing scores where pages overlap 52 * 53 * @return self pages present in either set 54 */ 55 public function unite(PageSet $other): self 56 { 57 $result = $this->pages; 58 foreach ($other->getPages() as $id => $score) { 59 $result[$id] = ($result[$id] ?? 0) + $score; 60 } 61 return new self($result); 62 } 63 64 /** 65 * Remove pages that exist in the other PageSet 66 * 67 * @return self pages in this set but not in $other 68 */ 69 public function subtract(PageSet $other): self 70 { 71 return new self(array_diff_key($this->pages, $other->getPages())); 72 } 73 74 /** 75 * @return bool true if this set contains no pages 76 */ 77 public function isEmpty(): bool 78 { 79 return empty($this->pages); 80 } 81} 82