/** * 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); }
private function _close() { if ($this->_closed) { // index is already closed and resources are cleaned up return; } $this->commit(); // Release "under processing" flag Zend_Search_Lucene_LockManager::releaseReadLock($this->_directory); if ($this->_closeDirOnExit) { $this->_directory->close(); } $this->_directory = null; $this->_writer = null; $this->_segmentInfos = null; $this->_closed = true; }
/** * Оптимизация индекса */ 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; }
private function _close() { if ($this->_closed) { return; } $this->commit(); Zend_Search_Lucene_LockManager::releaseReadLock($this->_directory); if ($this->_closeDirOnExit) { $this->_directory->close(); } $this->_directory = null; $this->_writer = null; $this->_segmentInfos = null; $this->_closed = true; }