1<?php 2 3namespace dokuwiki\Search\Index; 4 5/** 6 * Basic Building block to access individual index files 7 */ 8abstract class AbstractIndex 9{ 10 /** @var string name of the index */ 11 protected $idx; 12 13 /** @var string $suffix of the index */ 14 protected $suffix; 15 16 /** @var string full filename to the index */ 17 protected $filename; 18 19 /** @var bool is this index opened for writing? */ 20 protected $isWritable = false; 21 22 /** 23 * Initialize the index 24 * 25 * The $suffix argument is for an index that is split into multiple parts. 26 * Different index files should use different base names. 27 * 28 * @param string $idx name of the index 29 * @param string $suffix subpart identifier 30 * @param bool $isWritable has a sufficient lock been acquired to write to this index? 31 */ 32 public function __construct($idx, $suffix = '', $isWritable = false) 33 { 34 global $conf; 35 $this->filename = $conf['indexdir'] . '/' . $idx . $suffix . '.idx'; 36 $this->idx = $idx; 37 $this->suffix = $suffix; 38 $this->isWritable = $isWritable; 39 } 40 41 /** 42 * @return string the full path to the underlying file 43 */ 44 public function getFilename() 45 { 46 return $this->filename; 47 } 48 49 /** 50 * Does this index exist, yet? 51 * 52 * @return bool 53 */ 54 public function exists() 55 { 56 return file_exists($this->getFilename()); 57 } 58 59 /** 60 * Return the largest numeric suffix for the current index 61 * 62 * This is only useful for indexes that use integer based suffixes (like the wordlength indexes) 63 * 64 * @return int 0 if no numeric suffix indexes are found 65 */ 66 public function max() 67 { 68 global $conf; 69 $result = 0; 70 $files = glob($conf['indexdir'] . '/' . $this->idx . '*.idx'); 71 foreach ($files as $file) { 72 if (preg_match('/(\d)+\.idx$/', $file, $match)) { 73 $num = (int)$match[1]; 74 if ($num > $result) $result = $num; 75 } 76 } 77 78 return $result; 79 } 80 81 /** 82 * Change a line in the index 83 * 84 * If the line doesn't exist, it will be added, creating empty 85 * lines inbetween as necessary 86 * 87 * @param int $rid the line number, count starting at 0 88 * @param string $value line content to write 89 */ 90 abstract public function changeRow($rid, $value); 91 92 /** 93 * Retrieve a line from the index 94 * 95 * Returns an empty string for non-existing lines 96 * 97 * @param int $rid the line number 98 * @return string a line with trailing whitespace removed 99 */ 100 abstract public function retrieveRow($rid); 101 102 /** 103 * Retrieve multiple lines from the index 104 * 105 * Ignores non-existing lines, eg the result array may be smaller than the input $rids 106 * 107 * @param int[] $rids 108 * @return array [rid => value] 109 */ 110 abstract public function retrieveRows($rids); 111 112 /** 113 * Searches the Index for a given value 114 * 115 * If the index is writable and the value is not found it will be added. Otherwise null is returned. 116 * 117 * Entries previously marked as deleted will be restored. FIXME is that true? 118 * 119 * Note the existence of an entry in the index does not say anything about the existence 120 * of the real world object (eg. a page) 121 * 122 * You should preferable use accessCachedValue() instead. 123 * 124 * @param string $value 125 * 126 * @return int|null the RID of the entry, null if not found and not added 127 */ 128 public function getRowID($value) 129 { 130 $result = $this->getRowIDs([$value]); 131 return $result[$value] ?? null; 132 } 133 134 /** 135 * Searches the Index for all given values 136 * 137 * If the index is writable, not found values are added 138 * 139 * @param string[] $values 140 * @return array the RIDs of the entries (value => rid) 141 */ 142 abstract public function getRowIDs($values); 143 144 /** 145 * Find all RIDs matching a regular expression 146 * 147 * A full regular expression including delimiters and modifiers is expected 148 * 149 * @param string $re the regular expression to match against 150 * @return array (rid => value) 151 */ 152 abstract public function search($re); 153 154 /** 155 * Clears the index by deleting its file 156 * @return void 157 */ 158 public function clear() 159 { 160 @unlink($this->filename); 161 } 162 163 /** 164 * Saves the index if needed 165 * 166 * The default implementation does nothing and is only for streamlining the API of 167 * the different index classes 168 * @return void 169 */ 170 public function save() 171 { 172 } 173} 174