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

📄 writer.php

📁 很棒的在线教学系统
💻 PHP
📖 第 1 页 / 共 2 页
字号:
            $this->_newSegments[$newSegment->getName()] = $newSegment;        }        $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 + -