private Contains ( Lucene.Net.Index.SegmentCommitInfo si ) : bool | ||
si | Lucene.Net.Index.SegmentCommitInfo | |
리턴 | bool |
/// <summary> /// Checks if any merges are now necessary and returns a /// <see cref="MergePolicy.MergeSpecification"/> if so. A merge /// is necessary when there are more than /// <see cref="MergeFactor"/> segments at a given level. When /// multiple levels have too many segments, this method /// will return multiple merges, allowing the /// <see cref="MergeScheduler"/> to use concurrency. /// </summary> public override MergeSpecification FindMerges(MergeTrigger mergeTrigger, SegmentInfos infos) { int numSegments = infos.Count; if (IsVerbose) { Message("findMerges: " + numSegments + " segments"); } // Compute levels, which is just log (base mergeFactor) // of the size of each segment IList <SegmentInfoAndLevel> levels = new List <SegmentInfoAndLevel>(); var norm = (float)Math.Log(m_mergeFactor); ICollection <SegmentCommitInfo> mergingSegments = m_writer.Get().MergingSegments; for (int i = 0; i < numSegments; i++) { SegmentCommitInfo info = infos.Info(i); long size = Size(info); // Floor tiny segments if (size < 1) { size = 1; } SegmentInfoAndLevel infoLevel = new SegmentInfoAndLevel(info, (float)Math.Log(size) / norm, i); levels.Add(infoLevel); if (IsVerbose) { long segBytes = SizeBytes(info); string extra = mergingSegments.Contains(info) ? " [merging]" : ""; if (size >= m_maxMergeSize) { extra += " [skip: too large]"; } Message("seg=" + m_writer.Get().SegString(info) + " level=" + infoLevel.level + " size=" + String.Format(CultureInfo.InvariantCulture, "{0:0.00} MB", segBytes / 1024 / 1024.0) + extra); } } float levelFloor; if (m_minMergeSize <= 0) { levelFloor = (float)0.0; } else { levelFloor = (float)(Math.Log(m_minMergeSize) / norm); } // Now, we quantize the log values into levels. The // first level is any segment whose log size is within // LEVEL_LOG_SPAN of the max size, or, who has such as // segment "to the right". Then, we find the max of all // other segments and use that to define the next level // segment, etc. MergeSpecification spec = null; int numMergeableSegments = levels.Count; int start = 0; while (start < numMergeableSegments) { // Find max level of all segments not already // quantized. float maxLevel = levels[start].level; for (int i = 1 + start; i < numMergeableSegments; i++) { float level = levels[i].level; if (level > maxLevel) { maxLevel = level; } } // Now search backwards for the rightmost segment that // falls into this level: float levelBottom; if (maxLevel <= levelFloor) { // All remaining segments fall into the min level levelBottom = -1.0F; } else { levelBottom = (float)(maxLevel - LEVEL_LOG_SPAN); // Force a boundary at the level floor if (levelBottom < levelFloor && maxLevel >= levelFloor) { levelBottom = levelFloor; } } int upto = numMergeableSegments - 1; while (upto >= start) { if (levels[upto].level >= levelBottom) { break; } upto--; } if (IsVerbose) { Message(" level " + levelBottom.ToString("0.0") + " to " + maxLevel.ToString("0.0") + ": " + (1 + upto - start) + " segments"); } // Finally, record all merges that are viable at this level: int end = start + m_mergeFactor; while (end <= 1 + upto) { bool anyTooLarge = false; bool anyMerging = false; for (int i = start; i < end; i++) { SegmentCommitInfo info = levels[i].info; anyTooLarge |= (Size(info) >= m_maxMergeSize || SizeDocs(info) >= m_maxMergeDocs); if (mergingSegments.Contains(info)) { anyMerging = true; break; } } if (anyMerging) { // skip } else if (!anyTooLarge) { if (spec == null) { spec = new MergeSpecification(); } IList <SegmentCommitInfo> mergeInfos = new List <SegmentCommitInfo>(); for (int i = start; i < end; i++) { mergeInfos.Add(levels[i].info); Debug.Assert(infos.Contains(levels[i].info)); } if (IsVerbose) { Message(" add merge=" + m_writer.Get().SegString(mergeInfos) + " start=" + start + " end=" + end); } spec.Add(new OneMerge(mergeInfos)); } else if (IsVerbose) { Message(" " + start + " to " + end + ": contains segment over maxMergeSize or maxMergeDocs; skipping"); } start = end; end = start + m_mergeFactor; } start = 1 + upto; } return(spec); }