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