⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 writer.php

📁 zend的加强包 zend的加强包
💻 PHP
📖 第 1 页 / 共 2 页
字号:
        $this->commit();    }    /**     * Update segments file by adding current segment to a list     *     * @throws Zend_Search_Lucene_Exception     */    private function _updateSegments()    {        // Get an exclusive index lock        Zend_Search_Lucene_LockManager::obtainWriteLock($this->_directory);        $generation = Zend_Search_Lucene::getActualGeneration($this->_directory);        $segmentsFile   = $this->_directory->getFileObject(Zend_Search_Lucene::getSegmentFileName($generation), false);        $newSegmentFile = $this->_directory->createFile(Zend_Search_Lucene::getSegmentFileName(++$generation), false);        try {            $genFile = $this->_directory->getFileObject('segments.gen', false);        } catch (Zend_Search_Lucene_Exception $e) {            if (strpos($e->getMessage(), 'is not readable') !== false) {                $genFile = $this->_directory->createFile('segments.gen');            } else {                throw $e;            }        }                $genFile->writeInt((int)0xFFFFFFFE);        // Write generation (first copy)        $genFile->writeLong($generation);
        try {            // Write format marker            $newSegmentFile->writeInt((int)0xFFFFFFFD);                // Skip format identifier            $segmentsFile->seek(4, SEEK_CUR);            // $version = $segmentsFile->readLong() + $this->_versionUpdate;            // Process version on 32-bit platforms            $versionHigh = $segmentsFile->readInt();            $versionLow  = $segmentsFile->readInt();            $version = $versionHigh * ((double)0xFFFFFFFF + 1) +                       (($versionLow < 0)? (double)0xFFFFFFFF - (-1 - $versionLow) : $versionLow);            $version += $this->_versionUpdate;            $this->_versionUpdate = 0;            $newSegmentFile->writeInt((int)($version/((double)0xFFFFFFFF + 1)));            $newSegmentFile->writeInt((int)($version & 0xFFFFFFFF));                // Write segment name counter            $newSegmentFile->writeInt($segmentsFile->readInt());                // Get number of segments offset            $numOfSegmentsOffset = $newSegmentFile->tell();            // Write dummy data (segment counter)            $newSegmentFile->writeInt(0);                // Read number of segemnts            $segmentsCount = $segmentsFile->readInt();
            $segments = array();            for ($count = 0; $count < $segmentsCount; $count++) {                $segName = $segmentsFile->readString();                $segSize = $segmentsFile->readInt();                    if ($generation == 1 /* retrieved generation is 0 */) {                    // pre-2.1 index format                    $delGenHigh = 0;                    $delGenLow  = 0;                    $hasSingleNormFile = false;                    $numField = (int)0xFFFFFFFF;                    $isCompound = 1;                } else {                    //$delGen          = $segmentsFile->readLong();                    $delGenHigh        = $segmentsFile->readInt();                    $delGenLow         = $segmentsFile->readInt();                    $hasSingleNormFile = $segmentsFile->readByte();                    $numField          = $segmentsFile->readInt();                        $normGens = array();                    if ($numField != (int)0xFFFFFFFF) {                        for ($count1 = 0; $count1 < $numField; $count1++) {                            $normGens[] = $segmentsFile->readLong();                        }                    }                    $isCompound        = $segmentsFile->readByte();                }                    if (!in_array($segName, $this->_segmentsToDelete)) {                    // Load segment if necessary                    if (!isset($this->_segmentInfos[$segName])) {                        $delGen = $delGenHigh * ((double)0xFFFFFFFF + 1) +                                     (($delGenLow < 0)? (double)0xFFFFFFFF - (-1 - $delGenLow) : $delGenLow);                        $this->_segmentInfos[$segName] =                                     new Zend_Search_Lucene_Index_SegmentInfo($this->_directory,                                                                             $segName,                                                                             $segSize,                                                                             $delGen,                                                                             $hasSingleNormFile,                                                                             $isCompound);                    } else {                        // Retrieve actual detetions file generation number                        $delGen = $this->_segmentInfos[$segName]->getDelGen();                                                if ($delGen >= 0) {                            $delGenHigh = (int)($delGen/((double)0xFFFFFFFF + 1));                            $delGenLow  =(int)($delGen & 0xFFFFFFFF);                        } else {                            $delGenHigh = $delGenLow = (int)0xFFFFFFFF;                        }                    }                                        $newSegmentFile->writeString($segName);                    $newSegmentFile->writeInt($segSize);                    $newSegmentFile->writeInt($delGenHigh);                    $newSegmentFile->writeInt($delGenLow);                    $newSegmentFile->writeByte($hasSingleNormFile);                    $newSegmentFile->writeInt($numField);                    if ($numField != (int)0xFFFFFFFF) {                        foreach ($normGens as $normGen) {                            $newSegmentFile->writeLong($normGen);                        }                    }                    $newSegmentFile->writeByte($isCompound);                        $segments[$segName] = $segSize;                }            }            $segmentsFile->close();                $segmentsCount = count($segments) + count($this->_newSegments);                foreach ($this->_newSegments as $segName => $segmentInfo) {                $newSegmentFile->writeString($segName);                $newSegmentFile->writeInt($segmentInfo->count());                    // delete file generation: -1 (there is no delete file yet)                $newSegmentFile->writeInt((int)0xFFFFFFFF);$newSegmentFile->writeInt((int)0xFFFFFFFF);                // HasSingleNormFile                $newSegmentFile->writeByte($segmentInfo->hasSingleNormFile());                // NumField                $newSegmentFile->writeInt((int)0xFFFFFFFF);                // IsCompoundFile                $newSegmentFile->writeByte($segmentInfo->isCompound());                    $segments[$segmentInfo->getName()] = $segmentInfo->count();                $this->_segmentInfos[$segName] = $segmentInfo;            }            $this->_newSegments = array();                $newSegmentFile->seek($numOfSegmentsOffset);            $newSegmentFile->writeInt($segmentsCount);  // Update segments count            $newSegmentFile->close();        } catch (Exception $e) {
            /** Restore previous index generation */
            $generation--;
            $genFile->seek(4, SEEK_SET);
            // Write generation number twice
            $genFile->writeLong($generation); $genFile->writeLong($generation);

            // Release index write lock
            Zend_Search_Lucene_LockManager::releaseWriteLock($this->_directory);
            
            // Throw the exception
            throw $e;
        }        // Write generation (second copy)        $genFile->writeLong($generation);
        
        // Check if another update process is not running now
        // If yes, skip clean-up procedure
        if (Zend_Search_Lucene_LockManager::escalateReadLock($this->_directory)) {
            /**
             * Clean-up directory
             */
            $filesToDelete = array();
            $filesTypes    = array();
            $filesNumbers  = array();
            
            // list of .del files of currently used segments
            // each segment can have several generations of .del files
            // only last should not be deleted
            $delFiles = array();
            
            foreach ($this->_directory->fileList() as $file) {
                if ($file == 'deletable') {
                    // 'deletable' file
                    $filesToDelete[] = $file;
                    $filesTypes[]    = 0; // delete this file first, since it's not used starting from Lucene v2.1
                    $filesNumbers[]  = 0;
                } else if ($file == 'segments') {
                    // 'segments' file
    
                    $filesToDelete[] = $file;
                    $filesTypes[]    = 1; // second file to be deleted "zero" version of segments file (Lucene pre-2.1)
                    $filesNumbers[]  = 0;
                } else if (preg_match('/^segments_[a-zA-Z0-9]+$/i', $file)) {
                    // 'segments_xxx' file
                    // Check if it's not a just created generation file
                    if ($file != Zend_Search_Lucene::getSegmentFileName($generation)) {
                        $filesToDelete[] = $file;
                        $filesTypes[]    = 2; // first group of files for deletions
                        $filesNumbers[]  = (int)base_convert(substr($file, 9), 36, 10); // ordered by segment generation numbers 
                    }
                } else if (preg_match('/(^_([a-zA-Z0-9]+))\.f\d+$/i', $file, $matches)) {
                    // one of per segment files ('<segment_name>.f<decimal_number>')
                    // Check if it's not one of the segments in the current segments set
                    if (!isset($segments[$matches[1]])) {
                        $filesToDelete[] = $file;
                        $filesTypes[]    = 3; // second group of files for deletions
                        $filesNumbers[]  = (int)base_convert($matches[2], 36, 10); // order by segment number 
                    }
                } else if (preg_match('/(^_([a-zA-Z0-9]+))(_([a-zA-Z0-9]+))\.del$/i', $file, $matches)) {
                    // one of per segment files ('<segment_name>_<del_generation>.del' where <segment_name> is '_<segment_number>')
                    // Check if it's not one of the segments in the current segments set
                    if (!isset($segments[$matches[1]])) {
                        $filesToDelete[] = $file;
                        $filesTypes[]    = 3; // second group of files for deletions
                        $filesNumbers[]  = (int)base_convert($matches[2], 36, 10); // order by segment number 
                    } else {
                        $segmentNumber = (int)base_convert($matches[2], 36, 10);
                        $delGeneration = (int)base_convert($matches[4], 36, 10);
                        if (!isset($delFiles[$segmentNumber])) {
                            $delFiles[$segmentNumber] = array();
                        }
                        $delFiles[$segmentNumber][$delGeneration] = $file;
                    }
                } else if (isset(self::$_indexExtensions[substr($file, strlen($file)-4)])) {
                    // one of per segment files ('<segment_name>.<ext>')
                    $segmentName = substr($file, 0, strlen($file) - 4);
                    // Check if it's not one of the segments in the current segments set
                    if (!isset($segments[$segmentName])  &&
                        ($this->_currentSegment === null  ||  $this->_currentSegment->getName() != $segmentName)) {
                        $filesToDelete[] = $file;
                        $filesTypes[]    = 3; // second group of files for deletions
                        $filesNumbers[]  = (int)base_convert(substr($file, 1 /* skip '_' */, strlen($file)-5), 36, 10); // order by segment number 
                    }
                }
            }

            $maxGenNumber = 0;
            // process .del files of currently used segments
            foreach ($delFiles as $segmentNumber => $segmentDelFiles) {
                ksort($delFiles[$segmentNumber], SORT_NUMERIC);
                array_pop($delFiles[$segmentNumber]); // remove last delete file generation from candidates for deleting
                
                end($delFiles[$segmentNumber]);
                $lastGenNumber = key($delFiles[$segmentNumber]);
                if ($lastGenNumber > $maxGenNumber) {
                    $maxGenNumber = $lastGenNumber; 
                }
            }
            foreach ($delFiles as $segmentNumber => $segmentDelFiles) {
                foreach ($segmentDelFiles as $delGeneration => $file) {
                        $filesToDelete[] = $file;
                        $filesTypes[]    = 4; // third group of files for deletions
                        $filesNumbers[]  = $segmentNumber*$maxGenNumber + $delGeneration; // order by <segment_number>,<del_generation> pair 
                }
            }
            
            // Reorder files for deleting
            array_multisort($filesTypes,    SORT_ASC, SORT_NUMERIC,
                            $filesNumbers,  SORT_ASC, SORT_NUMERIC,
                            $filesToDelete, SORT_ASC, SORT_STRING);
            
            foreach ($filesToDelete as $file) {
                try {
                    $this->_directory->deleteFile($file);
                } catch (Zend_Search_Lucene_Exception $e) {
                    if (strpos($e->getMessage(), 'Can\'t delete file') === false) {
                        // That's not "file is under processing or already deleted" exception
                        // Pass it through
                        throw $e;
                    }
                }
            }
            
            // Return read lock into the previous state
            Zend_Search_Lucene_LockManager::deEscalateReadLock($this->_directory);
        } else {
            // Only release resources if another index reader is running now
            foreach ($this->_segmentsToDelete as $segName) {
                foreach (self::$_indexExtensions as $ext) {
                    $this->_directory->purgeFile($segName . $ext);
                }
            }
        }

        // Clean-up _segmentsToDelete container
        $this->_segmentsToDelete = array();
        

        // Release index write lock        Zend_Search_Lucene_LockManager::releaseWriteLock($this->_directory);        // Remove unused segments from segments list        foreach ($this->_segmentInfos as $segName => $segmentInfo) {            if (!isset($segments[$segName])) {                unset($this->_segmentInfos[$segName]);            }        }
    }    /**     * Commit current changes     */    public function commit()    {        if ($this->_currentSegment !== null) {            $newSegment = $this->_currentSegment->close();            if ($newSegment !== null) {                $this->_newSegments[$newSegment->getName()] = $newSegment;            }            $this->_currentSegment = null;        }        $this->_updateSegments();    }    /**     * Merges the provided indexes into this index.     *     * @param array $readers     * @return void     */    public function addIndexes($readers)    {        /**         * @todo implementation         */    }    /**     * Merges all segments together into new one
     * 
     * Returns true on success and false if another optimization or auto-optimization process 
     * is running now      *     * @return boolean     */    public function optimize()    {        if (Zend_Search_Lucene_LockManager::obtainOptimizationLock($this->_directory) === false) {
            return false;
        }

        $this->_mergeSegments($this->_segmentInfos);
        
        Zend_Search_Lucene_LockManager::releaseOptimizationLock($this->_directory);
        
        return true;    }    /**     * 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);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -