Beispiel #1
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 \Zend\Search\Lucene\Storage\Directory\Filesystem|string $directory
     * @throws \Zend\Search\Lucene\Exception\InvalidArgumentException
     * @throws \Zend\Search\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.');
        } else if ($this->_generation == 0) {
            $this->_readPre21SegmentsFile();
        } else {
            $this->_readSegmentsFile();
        }
    }
Beispiel #2
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);
 }
 /**
  * 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);
     }
 }
Beispiel #4
0
 /**
  * Release exclusive optimization lock
  *
  * @param \Zend\Search\Lucene\Storage\Directory $lockDirectory
  */
 public static function releaseOptimizationLock(Directory $lockDirectory)
 {
     $lock = $lockDirectory->getFileObject(self::OPTIMIZATION_LOCK_FILE);
     $lock->unlock();
 }