001: package org.apache.lucene.index;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import java.util.Collection;
021: import java.util.List;
022: import java.util.ArrayList;
023: import java.io.IOException;
024:
025: /** A {@link IndexDeletionPolicy} that wraps around any other
026: * {@link IndexDeletionPolicy} and adds the ability to hold and
027: * later release a single "snapshot" of an index. While
028: * the snapshot is held, the {@link IndexWriter} will not
029: * remove any files associated with it even if the index is
030: * otherwise being actively, arbitrarily changed. Because
031: * we wrap another arbitrary {@link IndexDeletionPolicy}, this
032: * gives you the freedom to continue using whatever {@link
033: * IndexDeletionPolicy} you would normally want to use with your
034: * index. */
035:
036: public class SnapshotDeletionPolicy implements IndexDeletionPolicy {
037:
038: private IndexCommitPoint lastCommit;
039: private IndexDeletionPolicy primary;
040: private IndexCommitPoint snapshot;
041:
042: public SnapshotDeletionPolicy(IndexDeletionPolicy primary) {
043: this .primary = primary;
044: }
045:
046: public synchronized void onInit(List commits) throws IOException {
047: primary.onInit(wrapCommits(commits));
048: lastCommit = (IndexCommitPoint) commits.get(commits.size() - 1);
049: }
050:
051: public synchronized void onCommit(List commits) throws IOException {
052: primary.onCommit(wrapCommits(commits));
053: lastCommit = (IndexCommitPoint) commits.get(commits.size() - 1);
054: }
055:
056: /** Take a snapshot of the most recent commit to the
057: * index. You must call release() to free this snapshot.
058: * Note that while the snapshot is held, the files it
059: * references will not be deleted, which will consume
060: * additional disk space in your index. If you take a
061: * snapshot at a particularly bad time (say just before
062: * you call optimize()) then in the worst case this could
063: * consume an extra 1X of your total index size, until
064: * you release the snapshot. */
065: public synchronized IndexCommitPoint snapshot() {
066: if (snapshot == null)
067: snapshot = lastCommit;
068: else
069: throw new IllegalStateException(
070: "snapshot is already set; please call release() first");
071: return snapshot;
072: }
073:
074: /** Release the currently held snapshot. */
075: public synchronized void release() {
076: if (snapshot != null)
077: snapshot = null;
078: else
079: throw new IllegalStateException(
080: "snapshot was not set; please call snapshot() first");
081: }
082:
083: private class MyCommitPoint implements IndexCommitPoint {
084: IndexCommitPoint cp;
085:
086: MyCommitPoint(IndexCommitPoint cp) {
087: this .cp = cp;
088: }
089:
090: public String getSegmentsFileName() {
091: return cp.getSegmentsFileName();
092: }
093:
094: public Collection getFileNames() throws IOException {
095: return cp.getFileNames();
096: }
097:
098: public void delete() {
099: synchronized (SnapshotDeletionPolicy.this ) {
100: // Suppress the delete request if this commit point is
101: // our current snapshot.
102: if (snapshot != cp)
103: cp.delete();
104: }
105: }
106: }
107:
108: private List wrapCommits(List commits) {
109: final int count = commits.size();
110: List myCommits = new ArrayList(count);
111: for (int i = 0; i < count; i++)
112: myCommits.add(new MyCommitPoint((IndexCommitPoint) commits
113: .get(i)));
114: return myCommits;
115: }
116: }
|