xref: /dokuwiki/inc/Search/Index/MemoryIndex.php (revision 9bd7d62f47cb0e2a7651fefd7106f6ac10625281)
1*9bd7d62fSAndreas Gohr<?php
2*9bd7d62fSAndreas Gohr
3*9bd7d62fSAndreas Gohrnamespace dokuwiki\Search\Index;
4*9bd7d62fSAndreas Gohr
5*9bd7d62fSAndreas Gohruse dokuwiki\Search\Exception\IndexWriteException;
6*9bd7d62fSAndreas Gohr
7*9bd7d62fSAndreas Gohr/**
8*9bd7d62fSAndreas Gohr * Access to a single index file
9*9bd7d62fSAndreas Gohr *
10*9bd7d62fSAndreas Gohr * Access using this class always happens by loading the full index into memory.
11*9bd7d62fSAndreas Gohr * All modifications need to be explicitly made permanent using the save() method.
12*9bd7d62fSAndreas Gohr * Should be used for small indexes that receive many changes at once.
13*9bd7d62fSAndreas Gohr */
14*9bd7d62fSAndreas Gohrclass MemoryIndex extends AbstractIndex
15*9bd7d62fSAndreas Gohr{
16*9bd7d62fSAndreas Gohr
17*9bd7d62fSAndreas Gohr    /** @var string the raw data lines of the index, no newlines */
18*9bd7d62fSAndreas Gohr    protected $data;
19*9bd7d62fSAndreas Gohr
20*9bd7d62fSAndreas Gohr    /**
21*9bd7d62fSAndreas Gohr     * Loads the full contents of the index into memory
22*9bd7d62fSAndreas Gohr     *
23*9bd7d62fSAndreas Gohr     * @inheritdoc
24*9bd7d62fSAndreas Gohr     */
25*9bd7d62fSAndreas Gohr    public function __construct($idx, $suffix = '')
26*9bd7d62fSAndreas Gohr    {
27*9bd7d62fSAndreas Gohr        parent::__construct($idx, $suffix);
28*9bd7d62fSAndreas Gohr
29*9bd7d62fSAndreas Gohr        $this->data = [];
30*9bd7d62fSAndreas Gohr        if (!file_exists($this->filename)) return;
31*9bd7d62fSAndreas Gohr        $this->data = file($this->filename, FILE_IGNORE_NEW_LINES);
32*9bd7d62fSAndreas Gohr
33*9bd7d62fSAndreas Gohr    }
34*9bd7d62fSAndreas Gohr
35*9bd7d62fSAndreas Gohr    /** @inheritdoc */
36*9bd7d62fSAndreas Gohr    public function changeRow($rid, $value)
37*9bd7d62fSAndreas Gohr    {
38*9bd7d62fSAndreas Gohr        if ($rid > count($this->data)) {
39*9bd7d62fSAndreas Gohr            $this->data = array_pad($this->data, $rid, '');
40*9bd7d62fSAndreas Gohr        }
41*9bd7d62fSAndreas Gohr        $this->data[$rid] = $value;
42*9bd7d62fSAndreas Gohr    }
43*9bd7d62fSAndreas Gohr
44*9bd7d62fSAndreas Gohr    /** @inheritdoc */
45*9bd7d62fSAndreas Gohr    public function retrieveRow($rid)
46*9bd7d62fSAndreas Gohr    {
47*9bd7d62fSAndreas Gohr        if (isset($this->data[$rid])) return $this->data[$rid];
48*9bd7d62fSAndreas Gohr        return '';
49*9bd7d62fSAndreas Gohr    }
50*9bd7d62fSAndreas Gohr
51*9bd7d62fSAndreas Gohr    /**
52*9bd7d62fSAndreas Gohr     * Save the changed index back to its file
53*9bd7d62fSAndreas Gohr     *
54*9bd7d62fSAndreas Gohr     * @throws IndexWriteException
55*9bd7d62fSAndreas Gohr     */
56*9bd7d62fSAndreas Gohr    public function save()
57*9bd7d62fSAndreas Gohr    {
58*9bd7d62fSAndreas Gohr        global $conf;
59*9bd7d62fSAndreas Gohr
60*9bd7d62fSAndreas Gohr        $tempname = $this->filename . '.tmp';
61*9bd7d62fSAndreas Gohr
62*9bd7d62fSAndreas Gohr        $fh = @fopen($tempname, 'w');
63*9bd7d62fSAndreas Gohr        if (!$fh) {
64*9bd7d62fSAndreas Gohr            throw new IndexWriteException("Failed to write $tempname");
65*9bd7d62fSAndreas Gohr        }
66*9bd7d62fSAndreas Gohr        fwrite($fh, implode("\n", $this->data));
67*9bd7d62fSAndreas Gohr        if (!empty($lines)) {
68*9bd7d62fSAndreas Gohr            fwrite($fh, "\n");
69*9bd7d62fSAndreas Gohr        }
70*9bd7d62fSAndreas Gohr        fclose($fh);
71*9bd7d62fSAndreas Gohr
72*9bd7d62fSAndreas Gohr        if ($conf['fperm']) {
73*9bd7d62fSAndreas Gohr            chmod($tempname, $conf['fperm']);
74*9bd7d62fSAndreas Gohr        }
75*9bd7d62fSAndreas Gohr
76*9bd7d62fSAndreas Gohr        if (!io_rename($tempname, $this->filename)) {
77*9bd7d62fSAndreas Gohr            throw new IndexWriteException("Failed to write {$this->filename}");
78*9bd7d62fSAndreas Gohr        }
79*9bd7d62fSAndreas Gohr    }
80*9bd7d62fSAndreas Gohr
81*9bd7d62fSAndreas Gohr}
82