xref: /dokuwiki/inc/Search/Query/PageSet.php (revision 9369b4a991666bc911474806b106d8958e79f4c1)
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