/// <summary> /// <see cref="DirectoryTaxonomyWriter(Directory, OpenMode, ITaxonomyWriterCache)"/> /// </summary> /// <exception cref="IOException"></exception> public SnapshotDirectoryTaxonomyWriter(Directory directory, OpenMode openMode, ITaxonomyWriterCache cache) : base(directory, openMode, cache) { }
/// <summary> /// Construct a Taxonomy writer. /// </summary> /// <param name="directory"> /// The <see cref="Store.Directory"/> in which to store the taxonomy. Note that /// the taxonomy is written directly to that directory (not to a /// subdirectory of it). </param> /// <param name="openMode"> /// Specifies how to open a taxonomy for writing: <see cref="OpenMode.APPEND"/> /// means open an existing index for append (failing if the index does /// not yet exist). <see cref="OpenMode.CREATE"/> means create a new index (first /// deleting the old one if it already existed). /// <see cref="OpenMode.CREATE_OR_APPEND"/> appends to an existing index if there /// is one, otherwise it creates a new index. </param> /// <param name="cache"> /// A <see cref="ITaxonomyWriterCache"/> implementation which determines /// the in-memory caching policy. See for example /// <see cref="WriterCache.LruTaxonomyWriterCache"/> and <see cref="Cl2oTaxonomyWriterCache"/>. /// If null or missing, <see cref="DefaultTaxonomyWriterCache()"/> is used. </param> /// <exception cref="CorruptIndexException"> /// if the taxonomy is corrupted. </exception> /// <exception cref="LockObtainFailedException"> /// if the taxonomy is locked by another writer. If it is known /// that no other concurrent writer is active, the lock might /// have been left around by an old dead process, and should be /// removed using <see cref="Unlock(Directory)"/>. </exception> /// <exception cref="IOException"> /// if another error occurred. </exception> public DirectoryTaxonomyWriter(Directory directory, OpenMode openMode, ITaxonomyWriterCache cache) { dir = directory; IndexWriterConfig config = CreateIndexWriterConfig(openMode); indexWriter = OpenIndexWriter(dir, config); // verify (to some extent) that merge policy in effect would preserve category docids if (indexWriter != null) { Debug.Assert(!(indexWriter.Config.MergePolicy is TieredMergePolicy), "for preserving category docids, merging none-adjacent segments is not allowed"); } // after we opened the writer, and the index is locked, it's safe to check // the commit data and read the index epoch openMode = config.OpenMode; if (!DirectoryReader.IndexExists(directory)) { indexEpoch = 1; } else { string epochStr = null; IDictionary <string, string> commitData = ReadCommitData(directory); if (commitData != null && commitData.TryGetValue(INDEX_EPOCH, out string value)) { epochStr = value; } // no commit data, or no epoch in it means an old taxonomy, so set its epoch to 1, for lack // of a better value. indexEpoch = epochStr == null ? 1 : Convert.ToInt64(epochStr, 16); } if (openMode == OpenMode.CREATE) { ++indexEpoch; } FieldType ft = new FieldType(TextField.TYPE_NOT_STORED); ft.OmitNorms = true; parentStreamField = new Field(Consts.FIELD_PAYLOADS, parentStream, ft); fullPathField = new StringField(Consts.FULL, "", Field.Store.YES); if (indexWriter == null) { return; } nextID = indexWriter.MaxDoc; if (cache == null) { cache = DefaultTaxonomyWriterCache(); } this.cache = cache; if (nextID == 0) { cacheIsComplete = true; // Make sure that the taxonomy always contain the root category // with category id 0. AddCategory(new FacetLabel()); } else { // There are some categories on the disk, which we have not yet // read into the cache, and therefore the cache is incomplete. // We choose not to read all the categories into the cache now, // to avoid terrible performance when a taxonomy index is opened // to add just a single category. We will do it later, after we // notice a few cache misses. cacheIsComplete = false; } }