/**
  * Generate compound index file
  */
 protected function _generateCFS()
 {
     $cfsFile = $this->_directory->createFile($this->_name . '.cfs');
     $cfsFile->writeVInt(count($this->_files));
     $dataOffsetPointers = array();
     foreach ($this->_files as $fileName) {
         $dataOffsetPointers[$fileName] = $cfsFile->tell();
         $cfsFile->writeLong(0);
         // write dummy data
         $cfsFile->writeString($fileName);
     }
     foreach ($this->_files as $fileName) {
         // Get actual data offset
         $dataOffset = $cfsFile->tell();
         // Seek to the data offset pointer
         $cfsFile->seek($dataOffsetPointers[$fileName]);
         // Write actual data offset value
         $cfsFile->writeLong($dataOffset);
         // Seek back to the end of file
         $cfsFile->seek($dataOffset);
         $dataFile = $this->_directory->getFileObject($fileName);
         $byteCount = $this->_directory->fileLength($fileName);
         while ($byteCount > 0) {
             $data = $dataFile->readBytes(min($byteCount, 131072));
             $byteCount -= strlen($data);
             $cfsFile->writeBytes($data);
         }
         $this->_directory->deleteFile($fileName);
     }
 }
Exemple #2
0
 /**
  * Opens the index.
  *
  * IndexReader constructor needs Directory as a parameter. It should be
  * a string with a path to the index folder or a Directory object.
  *
  * @param \ZendSearch\Lucene\Storage\Directory\Filesystem|string $directory
  * @throws \ZendSearch\Lucene\Exception\InvalidArgumentException
  * @throws \ZendSearch\Lucene\Exception\RuntimeException
  */
 public function __construct($directory = null, $create = false)
 {
     if ($directory === null) {
         throw new InvalidArgumentException('No index directory specified');
     }
     if (is_string($directory)) {
         $this->_directory = new Directory\Filesystem($directory);
         $this->_closeDirOnExit = true;
     } else {
         $this->_directory = $directory;
         $this->_closeDirOnExit = false;
     }
     $this->_segmentInfos = array();
     // Mark index as "under processing" to prevent other processes from premature index cleaning
     LockManager::obtainReadLock($this->_directory);
     $this->_generation = self::getActualGeneration($this->_directory);
     if ($create) {
         try {
             LockManager::obtainWriteLock($this->_directory);
         } catch (\Exception $e) {
             LockManager::releaseReadLock($this->_directory);
             if (strpos($e->getMessage(), 'Can\'t obtain exclusive index lock') === false) {
                 throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
             } else {
                 throw new RuntimeException('Can\'t create index. It\'s under processing now', 0, $e);
             }
         }
         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++;
         }
         Index\Writer::createIndex($this->_directory, $this->_generation, $nameCounter);
         LockManager::releaseWriteLock($this->_directory);
     }
     if ($this->_generation == -1) {
         throw new RuntimeException('Index doesn\'t exists in the specified directory.');
     } elseif ($this->_generation == 0) {
         $this->_readPre21SegmentsFile();
     } else {
         $this->_readSegmentsFile();
     }
 }
Exemple #3
0
 /**
  * Get name for new segment
  *
  * @return string
  */
 private function _newSegmentName()
 {
     Lucene\LockManager::obtainWriteLock($this->_directory);
     $generation = Lucene\Index::getActualGeneration($this->_directory);
     $segmentsFile = $this->_directory->getFileObject(Lucene\Index::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();
     Lucene\LockManager::releaseWriteLock($this->_directory);
     return '_' . base_convert($segmentNameCounter, 10, 36);
 }
 /**
  * Release exclusive optimization lock
  *
  * @param \ZendSearch\Lucene\Storage\Directory $lockDirectory
  */
 public static function releaseOptimizationLock(Directory $lockDirectory)
 {
     $lock = $lockDirectory->getFileObject(self::OPTIMIZATION_LOCK_FILE);
     $lock->unlock();
 }
 /**
  * Load terms dictionary index
  *
  * @throws \ZendSearch\Lucene\Exception\ExceptionInterface
  */
 private function _loadDictionaryIndex()
 {
     // Check, if index is already serialized
     if ($this->_directory->fileExists($this->_name . '.sti')) {
         // Load serialized dictionary index data
         $stiFile = $this->_directory->getFileObject($this->_name . '.sti');
         $stiFileData = $stiFile->readBytes($this->_directory->fileLength($this->_name . '.sti'));
         // Load dictionary index data
         if (($unserializedData = @unserialize($stiFileData)) !== false) {
             list($this->_termDictionary, $this->_termDictionaryInfos) = $unserializedData;
             return;
         }
     }
     // Load data from .tii file and generate .sti file
     // Prefetch dictionary index data
     $tiiFile = $this->openCompoundFile('.tii');
     $tiiFileData = $tiiFile->readBytes($this->compoundFileLength('.tii'));
     // Load dictionary index data
     list($this->_termDictionary, $this->_termDictionaryInfos) = DictionaryLoader::load($tiiFileData);
     $stiFileData = serialize(array($this->_termDictionary, $this->_termDictionaryInfos));
     $stiFile = $this->_directory->createFile($this->_name . '.sti');
     $stiFile->writeBytes($stiFileData);
 }