/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; using Directory = Lucene.Net.Store.Directory; namespace Lucene.Net.Index { /// A that wraps around any other /// and adds the ability to hold and /// later release a single "snapshot" of an index. While /// the snapshot is held, the will not /// remove any files associated with it even if the index is /// otherwise being actively, arbitrarily changed. Because /// we wrap another arbitrary , this /// gives you the freedom to continue using whatever /// you would normally want to use with your /// index. Note that you can re-use a single instance of /// SnapshotDeletionPolicy across multiple writers as long /// as they are against the same index Directory. Any /// snapshot held when a writer is closed will "survive" /// when the next writer is opened. /// ///

WARNING: This API is a new and experimental and /// may suddenly change.

///

public class SnapshotDeletionPolicy : IndexDeletionPolicy { private IndexCommit lastCommit; private IndexDeletionPolicy primary; private System.String snapshot; public SnapshotDeletionPolicy(IndexDeletionPolicy primary) { this.primary = primary; } public virtual void OnInit(IList commits) where T : IndexCommit { lock (this) { primary.OnInit(WrapCommits(commits)); lastCommit = commits[commits.Count - 1]; } } public virtual void OnCommit(IList commits) where T : IndexCommit { lock (this) { primary.OnCommit(WrapCommits(commits)); lastCommit = commits[commits.Count - 1]; } } /// Take a snapshot of the most recent commit to the /// index. You must call release() to free this snapshot. /// Note that while the snapshot is held, the files it /// references will not be deleted, which will consume /// additional disk space in your index. If you take a /// snapshot at a particularly bad time (say just before /// you call optimize()) then in the worst case this could /// consume an extra 1X of your total index size, until /// you release the snapshot. /// public virtual IndexCommit Snapshot() { lock (this) { if (lastCommit == null) { throw new System.SystemException("no index commits to snapshot !"); } if (snapshot == null) snapshot = lastCommit.SegmentsFileName; else throw new System.SystemException("snapshot is already set; please call release() first"); return lastCommit; } } /// Release the currently held snapshot. public virtual void Release() { lock (this) { if (snapshot != null) snapshot = null; else throw new System.SystemException("snapshot was not set; please call snapshot() first"); } } private class MyCommitPoint : IndexCommit { private void InitBlock(SnapshotDeletionPolicy enclosingInstance) { this.enclosingInstance = enclosingInstance; } private SnapshotDeletionPolicy enclosingInstance; public SnapshotDeletionPolicy Enclosing_Instance { get { return enclosingInstance; } } internal IndexCommit cp; internal MyCommitPoint(SnapshotDeletionPolicy enclosingInstance, IndexCommit cp) { InitBlock(enclosingInstance); this.cp = cp; } public override string ToString() { return "SnapshotDeletionPolicy.SnapshotCommitPoint(" + cp + ")"; } public override string SegmentsFileName { get { return cp.SegmentsFileName; } } public override ICollection FileNames { get { return cp.FileNames; } } public override Directory Directory { get { return cp.Directory; } } public override void Delete() { lock (Enclosing_Instance) { // Suppress the delete request if this commit point is // our current snapshot. if (Enclosing_Instance.snapshot == null || !Enclosing_Instance.snapshot.Equals(SegmentsFileName)) cp.Delete(); } } public override bool IsDeleted { get { return cp.IsDeleted; } } public override long Version { get { return cp.Version; } } public override long Generation { get { return cp.Generation; } } public override IDictionary UserData { get { return cp.UserData; } } public override bool IsOptimized { get { return cp.IsOptimized; } } } private IList WrapCommits(IList commits) where T : IndexCommit { int count = commits.Count; var myCommits = new List(count); for (int i = 0; i < count; i++) { myCommits.Add(new MyCommitPoint(this, commits[i])); } return myCommits; } } }