/*------------------------------------------------------------------------------ * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team * * Distributable under the terms of either the Apache License (Version 2.0) or * the GNU Lesser General Public License, as specified in the COPYING file. ------------------------------------------------------------------------------*/ #ifndef _lucene_index_MergePolicy_ #define _lucene_index_MergePolicy_ #include "CLucene/util/VoidList.h" CL_CLASS_DEF(store,Directory) CL_NS_DEF(index) class SegmentInfo; class SegmentInfos; class IndexWriter; /** *
Expert: a MergePolicy determines the sequence of * primitive merge operations to be used for overall merge * and optimize operations.
* *Whenever the segments in an index have been altered by * {@link IndexWriter}, either the addition of a newly * flushed segment, addition of many segments from * addIndexes* calls, or a previous merge that may now need * to cascade, {@link IndexWriter} invokes {@link * #findMerges} to give the MergePolicy a chance to pick * merges that are now required. This method returns a * {@link MergeSpecification} instance describing the set of * merges that should be done, or null if no merges are * necessary. When IndexWriter.optimize is called, it calls * {@link #findMergesForOptimize} and the MergePolicy should * then return the necessary merges.
* *Note that the policy can return more than one merge at * a time. In this case, if the writer is using {@link * SerialMergeScheduler}, the merges will be run * sequentially but if it is using {@link * ConcurrentMergeScheduler} they will be run concurrently.
* *The default MergePolicy is {@link * LogByteSizeMergePolicy}.
*NOTE: This API is new and still experimental * (subject to change suddenly in the next release)
*/ class CLUCENE_EXPORT MergePolicy: public CL_NS(util)::NamedObject { public: /** OneMerge provides the information necessary to perform * an individual primitive merge operation, resulting in * a single new segment. The merge spec includes the * subset of segments to be merged as well as whether the * new segment should use the compound file format. */ class CLUCENE_EXPORT OneMerge: public CL_NS(util)::NamedObject { public: DEFINE_MUTEX(THIS_LOCK) SegmentInfo* info; // used by IndexWriter bool mergeDocStores; // used by IndexWriter bool optimize; // used by IndexWriter SegmentInfos* segmentsClone; // used by IndexWriter bool increfDone; // used by IndexWriter bool registerDone; // used by IndexWriter int64_t mergeGen; // used by IndexWriter bool isExternal; // used by IndexWriter int32_t maxNumSegmentsOptimize; // used by IndexWriter SegmentInfos* segments; const bool useCompoundFile; bool aborted; CLuceneError error; /** * Constructor * @memory, segments object is consumed. The SegmentInfo objects within are referenced */ OneMerge(SegmentInfos* segments, bool _useCompoundFile); ~OneMerge(); /** Record that an exception occurred while executing * this merge */ void setException(CLuceneError& error); /** Retrieve previous exception set by {@link * #setException}. */ const CLuceneError& getException(); /** Mark this merge as aborted. If this is called * before the merge is committed then the merge will * not be committed. */ void abort(); /** Returns true if this merge was aborted. */ bool isAborted(); void checkAborted(CL_NS(store)::Directory* dir); std::string segString(CL_NS(store)::Directory* dir) const; static const char* getClassName(); virtual const char* getObjectName() const; }; /** * A MergeSpecification instance provides the information * necessary to perform multiple merges. It simply * contains a list of {@link OneMerge} instances. */ class CLUCENE_EXPORT MergeSpecification { public: MergeSpecification(); ~MergeSpecification(); /** * The subset of segments to be included in the primitive merge. */ CL_NS(util)::CLArrayListThis class implements a {@link MergePolicy} that tries * to merge segments into levels of exponentially * increasing size, where each level has < mergeFactor * segments in it. Whenever a given levle has mergeFactor * segments or more in it, they will be merged.
* *This class is abstract and requires a subclass to * define the {@link #size} method which specifies how a * segment's size is determined. {@link LogDocMergePolicy} * is one subclass that measures size by document count in * the segment. {@link LogByteSizeMergePolicy} is another * subclass that measures size as the total byte size of the * file(s) for the segment.
*/ class CLUCENE_EXPORT LogMergePolicy: public MergePolicy { int32_t mergeFactor; int32_t maxMergeDocs; bool _useCompoundFile; bool _useCompoundDocStore; IndexWriter* writer; void message(const std::string& message); bool isOptimized(SegmentInfos* infos, IndexWriter* writer, int32_t maxNumSegments, std::vectorReturns the number of segments that are merged at * once and also controls the total number of segments * allowed to accumulate in the index.
*/ int32_t getMergeFactor(); /** Determines how often segment indices are merged by * addDocument(). With smaller values, less RAM is used * while indexing, and searches on unoptimized indices are * faster, but indexing speed is slower. With larger * values, more RAM is used during indexing, and while * searches on unoptimized indices are slower, indexing is * faster. Thus larger values (> 10) are best for batch * index creation, and smaller values (< 10) for indices * that are interactively maintained. */ void setMergeFactor(int32_t mergeFactor); // Javadoc inherited bool useCompoundFile(SegmentInfos* infos, SegmentInfo* info); /** Sets whether compound file format should be used for * newly flushed and newly merged segments. */ void setUseCompoundFile(bool useCompoundFile); /** Returns true if newly flushed and newly merge segments * are written in compound file format. @see * #setUseCompoundFile */ bool getUseCompoundFile(); // Javadoc inherited bool useCompoundDocStore(SegmentInfos* infos); /** Sets whether compound file format should be used for * newly flushed and newly merged doc store * segment files (term vectors and stored fields). */ void setUseCompoundDocStore(bool useCompoundDocStore); /** Returns true if newly flushed and newly merge doc * store segment files (term vectors and stored fields) * are written in compound file format. @see * #setUseCompoundDocStore */ bool getUseCompoundDocStore(); void close(); /** Returns the merges necessary to optimize the index. * This merge policy defines "optimized" to mean only one * segment in the index, where that segment has no * deletions pending nor separate norms, and it is in * compound file format if the current useCompoundFile * setting is true. This method returns multiple merges * (mergeFactor at a time) so the {@link MergeScheduler} * in use may make use of concurrency. */ MergeSpecification* findMergesForOptimize(SegmentInfos* segmentInfos, IndexWriter* writer, int32_t maxSegmentCount, std::vectorDetermines the largest segment (measured by * document count) that may be merged with other segments. * Small values (e.g., less than 10,000) are best for * interactive indexing, as this limits the length of * pauses while indexing to a few seconds. Larger values * are best for batched indexing and speedier * searches.
* *The default value is {@link Integer#MAX_VALUE}.
* *The default merge policy ({@link * LogByteSizeMergePolicy}) also allows you to set this * limit by net size (in MB) of the segment, using {@link * LogByteSizeMergePolicy#setMaxMergeMB}.
*/ void setMaxMergeDocs(int32_t maxMergeDocs); /** Returns the largest segment (measured by document * count) that may be merged with other segments. * @see #setMaxMergeDocs */ int32_t getMaxMergeDocs(); virtual bool instanceOf(const char* otherobject) const; static const char* getClassName(); virtual const char* getObjectName() const; }; /** This is a {@link LogMergePolicy} that measures size of a * segment as the number of documents (not taking deletions * into account). */ class CLUCENE_EXPORT LogDocMergePolicy: public LogMergePolicy { public: /** Default minimum segment size. @see setMinMergeDocs */ LUCENE_STATIC_CONSTANT(int32_t, DEFAULT_MIN_MERGE_DOCS = 1000); LogDocMergePolicy(); /** Sets the minimum size for the lowest level segments. * Any segments below this size are considered to be on * the same level (even if they vary drastically in size) * and will be merged whenever there are mergeFactor of * them. This effectively truncates the "int64_t tail" of * small segments that would otherwise be created into a * single level. If you set this too large, it could * greatly increase the merging cost during indexing (if * you flush many small segments). */ void setMinMergeDocs(int32_t minMergeDocs); /** Get the minimum size for a segment to remain * un-merged. * @see #setMinMergeDocs **/ int32_t getMinMergeDocs(); static const char* getClassName(); virtual const char* getObjectName() const; protected: int64_t size(SegmentInfo* info); }; /** This is a {@link LogMergePolicy} that measures size of a * segment as the total byte size of the segment's files. */ class CLUCENE_EXPORT LogByteSizeMergePolicy: public LogMergePolicy { protected: int64_t size(SegmentInfo* info); public: /** Default minimum segment size. @see setMinMergeMB */ static const float_t DEFAULT_MIN_MERGE_MB; /** Default maximum segment size. A segment of this size * or larger will never be merged. @see setMaxMergeMB */ static const float_t DEFAULT_MAX_MERGE_MB; LogByteSizeMergePolicy(); /**Determines the largest segment (measured by total * byte size of the segment's files, in MB) that may be * merged with other segments. Small values (e.g., less * than 50 MB) are best for interactive indexing, as this * limits the length of pauses while indexing to a few * seconds. Larger values are best for batched indexing * and speedier searches.
* *Note that {@link #setMaxMergeDocs} is also * used to check whether a segment is too large for * merging (it's either or).
*/ void setMaxMergeMB(float_t mb); /** Returns the largest segment (meaured by total byte * size of the segment's files, in MB) that may be merged * with other segments. * @see #setMaxMergeMB */ float_t getMaxMergeMB(); /** Sets the minimum size for the lowest level segments. * Any segments below this size are considered to be on * the same level (even if they vary drastically in size) * and will be merged whenever there are mergeFactor of * them. This effectively truncates the "long tail" of * small segments that would otherwise be created into a * single level. If you set this too large, it could * greatly increase the merging cost during indexing (if * you flush many small segments). */ void setMinMergeMB(float_t mb); /** Get the minimum size for a segment to remain * un-merged. * @see #setMinMergeMB **/ float_t getMinMergeMB(); static const char* getClassName(); virtual const char* getObjectName() const; }; CL_NS_END #endif