/** * Get name for new segment * * @return string */ private function _newSegmentName() { Zend_Search_Lucene_LockManager::obtainWriteLock($this->_directory); $generation = Zend_Search_Lucene::getActualGeneration($this->_directory); $segmentsFile = $this->_directory->getFileObject(Zend_Search_Lucene::getSegmentFileName($generation), false); $segmentsFile->seek(12); // 12 = 4 (int, file format marker) + 8 (long, index version) $segmentNameCounter = $segmentsFile->readInt(); $segmentsFile->seek(12); // 12 = 4 (int, file format marker) + 8 (long, index version) $segmentsFile->writeInt($segmentNameCounter + 1); // Flash output to guarantee that wrong value will not be loaded between unlock and // return (which calls $segmentsFile destructor) $segmentsFile->flush(); Zend_Search_Lucene_LockManager::releaseWriteLock($this->_directory); return '_' . base_convert($segmentNameCounter, 10, 36); }
public function __construct($directory = null, $create = false) { if ($directory === null) { require_once 'Zend/Search/Lucene/Exception.php'; throw new Zend_Search_Exception('No index directory specified'); } if ($directory instanceof Zend_Search_Lucene_Storage_Directory_Filesystem) { $this->_directory = $directory; $this->_closeDirOnExit = false; } else { $this->_directory = new Zend_Search_Lucene_Storage_Directory_Filesystem($directory); $this->_closeDirOnExit = true; } $this->_segmentInfos = array(); // Mark index as "under processing" to prevent other processes from premature index cleaning Zend_Search_Lucene_LockManager::obtainReadLock($this->_directory); $this->_generation = self::getActualGeneration($this->_directory); if ($create) { require_once 'Zend/Search/Lucene/Exception.php'; try { Zend_Search_Lucene_LockManager::obtainWriteLock($this->_directory); } catch (Zend_Search_Lucene_Exception $e) { Zend_Search_Lucene_LockManager::releaseReadLock($this->_directory); if (strpos($e->getMessage(), 'Can\'t obtain exclusive index lock') === false) { throw $e; } else { throw new Zend_Search_Lucene_Exception('Can\'t create index. It\'s under processing now'); } } if ($this->_generation == -1) { // Directory doesn't contain existing index, start from 1 $this->_generation = 1; $nameCounter = 0; } else { // Directory contains existing index $segmentsFile = $this->_directory->getFileObject(self::getSegmentFileName($this->_generation)); $segmentsFile->seek(12); // 12 = 4 (int, file format marker) + 8 (long, index version) $nameCounter = $segmentsFile->readInt(); $this->_generation++; } Zend_Search_Lucene_Index_Writer::createIndex($this->_directory, $this->_generation, $nameCounter); Zend_Search_Lucene_LockManager::releaseWriteLock($this->_directory); } if ($this->_generation == -1) { require_once 'Zend/Search/Lucene/Exception.php'; throw new Zend_Search_Lucene_Exception('Index doesn\'t exists in the specified directory.'); } else { if ($this->_generation == 0) { $this->_readPre21SegmentsFile(); } else { $this->_readSegmentsFile(); } } }
/** * Оптимизация индекса */ public function optimize() { $zsl = $this->get_index(); $zsl->optimize(); // ВНИМАНИЕ!!! // Код, который следует далее, зависит от версии формата индекса Lucene // и может перестать работать и/или приводить к возникновению ошибок // в будущем при изменении формата, используемого Zend_Search_Lucene! // После некорректного завершения переиндексирования могут остаться "лишние" // файлы: устроим чистку... try { $path = $this->get_index_path(); //$directory = $zsl->getDirectory(); $directory = new Zend_Search_Lucene_Storage_Directory_Filesystem($path); Zend_Search_Lucene_LockManager::obtainWriteLock($directory); $generation = Zend_Search_Lucene::getActualGeneration($directory); $files_to_keep = array("segments.gen", Zend_Search_Lucene_LockManager::WRITE_LOCK_FILE, Zend_Search_Lucene_LockManager::READ_LOCK_FILE, Zend_Search_Lucene_LockManager::READ_LOCK_PROCESSING_LOCK_FILE, Zend_Search_Lucene_LockManager::OPTIMIZATION_LOCK_FILE); if ($generation > 0) { $segments_file_name = Zend_Search_Lucene::getSegmentFileName($generation); $files_to_keep[] = $segments_file_name; $segments_file = $directory->getFileObject($segments_file_name); // после оптимизации должен остаться только один сегмент // найдём имя этого сегмента $segments_file->seek(16); // 4 (int, file format marker) + 8 (long, index version) + 4 (int, segment name counter) $seg_count = $segments_file->readInt(); if ($seg_count == 1) { $seg_name = $segments_file->readString(); $files_to_keep[] = "{$seg_name}.cfs"; $files_to_keep[] = "{$seg_name}.sti"; if ($seg_name && chdir($path)) { $files_to_delete = array_diff(glob("*"), $files_to_keep); foreach ($files_to_delete as $f) { unlink($f); } } } } } catch (Exception $e) { // something went south, probably it was impossible to get the write lock // or read some file // trigger_error(get_class($e) . ": {$e->getMessage()}", E_USER_WARNING); } Zend_Search_Lucene_LockManager::releaseWriteLock($directory); }
/** * Write changes if it's necessary. */ public function writeChanges() { if (!$this->_deletedDirty) { return; } if (extension_loaded('bitset')) { $delBytes = $this->_deleted; $bitCount = count(bitset_to_array($delBytes)); } else { $byteCount = floor($this->_docCount / 8) + 1; $delBytes = str_repeat(chr(0), $byteCount); for ($count = 0; $count < $byteCount; $count++) { $byte = 0; for ($bit = 0; $bit < 8; $bit++) { if (isset($this->_deleted[$count * 8 + $bit])) { $byte |= 1 << $bit; } } $delBytes[$count] = chr($byte); } $bitCount = count($this->_deleted); } // Get new generation number Zend_Search_Lucene_LockManager::obtainWriteLock($this->_directory); $delFileList = array(); foreach ($this->_directory->fileList() as $file) { if ($file == $this->_name . '.del') { // Matches <segment_name>.del file name $delFileList[] = 0; } else { if (preg_match('/^' . $this->_name . '_([a-zA-Z0-9]+)\\.del$/i', $file, $matches)) { // Matches <segment_name>_NNN.del file names $delFileList[] = (int) base_convert($matches[1], 36, 10); } } } if (count($delFileList) == 0) { // There is no deletions file for current segment in the directory // Set detetions file generation number to 1 $this->_delGen = 1; } else { // There are some deletions files for current segment in the directory // Set detetions file generation number to the highest + 1 $this->_delGen = max($delFileList) + 1; } $delFile = $this->_directory->createFile($this->_name . '_' . base_convert($this->_delGen, 10, 36) . '.del'); Zend_Search_Lucene_LockManager::releaseWriteLock($this->_directory); $delFile->writeInt($this->_docCount); $delFile->writeInt($bitCount); $delFile->writeBytes($delBytes); $this->_deletedDirty = false; }
public function __construct($directory = null, $create = false) { if ($directory === null) { throw new Zend_Search_Exception('No index directory specified'); } if (is_string($directory)) { $this->_directory = new Zend_Search_Lucene_Storage_Directory_Filesystem($directory); $this->_closeDirOnExit = true; } else { $this->_directory = $directory; $this->_closeDirOnExit = false; } $this->_segmentInfos = array(); Zend_Search_Lucene_LockManager::obtainReadLock($this->_directory); $this->_generation = self::getActualGeneration($this->_directory); if ($create) { try { Zend_Search_Lucene_LockManager::obtainWriteLock($this->_directory); } catch (Zend_Search_Lucene_Exception $e) { Zend_Search_Lucene_LockManager::releaseReadLock($this->_directory); if (strpos($e->getMessage(), 'Can\'t obtain exclusive index lock') === false) { throw new Zend_Search_Lucene_Exception($e->getMessage(), $e->getCode(), $e); } else { throw new Zend_Search_Lucene_Exception('Can\'t create index. It\'s under processing now', 0, $e); } } if ($this->_generation == -1) { $this->_generation = 1; $nameCounter = 0; } else { $segmentsFile = $this->_directory->getFileObject(self::getSegmentFileName($this->_generation)); $segmentsFile->seek(12); $nameCounter = $segmentsFile->readInt(); $this->_generation++; } Zend_Search_Lucene_Index_Writer::createIndex($this->_directory, $this->_generation, $nameCounter); Zend_Search_Lucene_LockManager::releaseWriteLock($this->_directory); } if ($this->_generation == -1) { throw new Zend_Search_Lucene_Exception('Index doesn\'t exists in the specified directory.'); } else { if ($this->_generation == 0) { $this->_readPre21SegmentsFile(); } else { $this->_readSegmentsFile(); } } }