+++ /dev/null
-package org.apache.lucene.index;
-
-/**
- * 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.
- */
-
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.Collection;
-
-import org.apache.lucene.analysis.MockAnalyzer;
-import org.apache.lucene.analysis.WhitespaceAnalyzer;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-import org.apache.lucene.index.IndexWriterConfig.OpenMode;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.ScoreDoc;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.util.LuceneTestCase;
-
-/*
- Verify we can read the pre-2.1 file format, do searches
- against it, and add documents to it.
-*/
-
-public class TestDeletionPolicy extends LuceneTestCase {
-
- private void verifyCommitOrder(List<? extends IndexCommit> commits) throws IOException {
- final IndexCommit firstCommit = commits.get(0);
- long last = SegmentInfos.generationFromSegmentsFileName(firstCommit.getSegmentsFileName());
- assertEquals(last, firstCommit.getGeneration());
- long lastVersion = firstCommit.getVersion();
- long lastTimestamp = firstCommit.getTimestamp();
- for(int i=1;i<commits.size();i++) {
- final IndexCommit commit = commits.get(i);
- long now = SegmentInfos.generationFromSegmentsFileName(commit.getSegmentsFileName());
- long nowVersion = commit.getVersion();
- long nowTimestamp = commit.getTimestamp();
- assertTrue("SegmentInfos commits are out-of-order", now > last);
- assertTrue("SegmentInfos versions are out-of-order", nowVersion > lastVersion);
- assertTrue("SegmentInfos timestamps are out-of-order: now=" + nowTimestamp + " vs last=" + lastTimestamp, nowTimestamp >= lastTimestamp);
- assertEquals(now, commit.getGeneration());
- last = now;
- lastVersion = nowVersion;
- lastTimestamp = nowTimestamp;
- }
- }
-
- class KeepAllDeletionPolicy implements IndexDeletionPolicy {
- int numOnInit;
- int numOnCommit;
- Directory dir;
- public void onInit(List<? extends IndexCommit> commits) throws IOException {
- verifyCommitOrder(commits);
- numOnInit++;
- }
- public void onCommit(List<? extends IndexCommit> commits) throws IOException {
- IndexCommit lastCommit = commits.get(commits.size()-1);
- IndexReader r = IndexReader.open(dir, true);
- assertEquals("lastCommit.isOptimized()=" + lastCommit.isOptimized() + " vs IndexReader.isOptimized=" + r.isOptimized(), r.isOptimized(), lastCommit.isOptimized());
- r.close();
- verifyCommitOrder(commits);
- numOnCommit++;
- }
- }
-
- /**
- * This is useful for adding to a big index when you know
- * readers are not using it.
- */
- class KeepNoneOnInitDeletionPolicy implements IndexDeletionPolicy {
- int numOnInit;
- int numOnCommit;
- public void onInit(List<? extends IndexCommit> commits) throws IOException {
- verifyCommitOrder(commits);
- numOnInit++;
- // On init, delete all commit points:
- for (final IndexCommit commit : commits) {
- commit.delete();
- assertTrue(commit.isDeleted());
- }
- }
- public void onCommit(List<? extends IndexCommit> commits) throws IOException {
- verifyCommitOrder(commits);
- int size = commits.size();
- // Delete all but last one:
- for(int i=0;i<size-1;i++) {
- ((IndexCommit) commits.get(i)).delete();
- }
- numOnCommit++;
- }
- }
-
- class KeepLastNDeletionPolicy implements IndexDeletionPolicy {
- int numOnInit;
- int numOnCommit;
- int numToKeep;
- int numDelete;
- Set<String> seen = new HashSet<String>();
-
- public KeepLastNDeletionPolicy(int numToKeep) {
- this.numToKeep = numToKeep;
- }
-
- public void onInit(List<? extends IndexCommit> commits) throws IOException {
- if (VERBOSE) {
- System.out.println("TEST: onInit");
- }
- verifyCommitOrder(commits);
- numOnInit++;
- // do no deletions on init
- doDeletes(commits, false);
- }
-
- public void onCommit(List<? extends IndexCommit> commits) throws IOException {
- if (VERBOSE) {
- System.out.println("TEST: onCommit");
- }
- verifyCommitOrder(commits);
- doDeletes(commits, true);
- }
-
- private void doDeletes(List<? extends IndexCommit> commits, boolean isCommit) {
-
- // Assert that we really are only called for each new
- // commit:
- if (isCommit) {
- String fileName = ((IndexCommit) commits.get(commits.size()-1)).getSegmentsFileName();
- if (seen.contains(fileName)) {
- throw new RuntimeException("onCommit was called twice on the same commit point: " + fileName);
- }
- seen.add(fileName);
- numOnCommit++;
- }
- int size = commits.size();
- for(int i=0;i<size-numToKeep;i++) {
- ((IndexCommit) commits.get(i)).delete();
- numDelete++;
- }
- }
- }
-
- /*
- * Delete a commit only when it has been obsoleted by N
- * seconds.
- */
- class ExpirationTimeDeletionPolicy implements IndexDeletionPolicy {
-
- Directory dir;
- double expirationTimeSeconds;
- int numDelete;
-
- public ExpirationTimeDeletionPolicy(Directory dir, double seconds) {
- this.dir = dir;
- this.expirationTimeSeconds = seconds;
- }
-
- public void onInit(List<? extends IndexCommit> commits) throws IOException {
- verifyCommitOrder(commits);
- onCommit(commits);
- }
-
- public void onCommit(List<? extends IndexCommit> commits) throws IOException {
- verifyCommitOrder(commits);
-
- IndexCommit lastCommit = commits.get(commits.size()-1);
-
- // Any commit older than expireTime should be deleted:
- double expireTime = dir.fileModified(lastCommit.getSegmentsFileName())/1000.0 - expirationTimeSeconds;
-
- for (final IndexCommit commit : commits) {
- double modTime = dir.fileModified(commit.getSegmentsFileName())/1000.0;
- if (commit != lastCommit && modTime < expireTime) {
- commit.delete();
- numDelete += 1;
- }
- }
- }
- }
-
- /*
- * Test "by time expiration" deletion policy:
- */
- public void testExpirationTimeDeletionPolicy() throws IOException, InterruptedException {
-
- final double SECONDS = 2.0;
-
- Directory dir = newDirectory();
- ExpirationTimeDeletionPolicy policy = new ExpirationTimeDeletionPolicy(dir, SECONDS);
- IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT,
- new MockAnalyzer(random))
- .setIndexDeletionPolicy(policy);
- MergePolicy mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, true);
- }
- IndexWriter writer = new IndexWriter(dir, conf);
- writer.close();
-
- final int ITER = 9;
-
- long lastDeleteTime = 0;
- for(int i=0;i<ITER;i++) {
- // Record last time when writer performed deletes of
- // past commits
- lastDeleteTime = System.currentTimeMillis();
- conf = newIndexWriterConfig(TEST_VERSION_CURRENT,
- new MockAnalyzer(random)).setOpenMode(
- OpenMode.APPEND).setIndexDeletionPolicy(policy);
- mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, true);
- }
- writer = new IndexWriter(dir, conf);
- for(int j=0;j<17;j++) {
- addDoc(writer);
- }
- writer.close();
-
- if (i < ITER-1) {
- // Make sure to sleep long enough so that some commit
- // points will be deleted:
- Thread.sleep((int) (1000.0*(SECONDS/5.0)));
- }
- }
-
- // First, make sure the policy in fact deleted something:
- assertTrue("no commits were deleted", policy.numDelete > 0);
-
- // Then simplistic check: just verify that the
- // segments_N's that still exist are in fact within SECONDS
- // seconds of the last one's mod time, and, that I can
- // open a reader on each:
- long gen = SegmentInfos.getCurrentSegmentGeneration(dir);
-
- String fileName = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
- "",
- gen);
- dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
-
- boolean oneSecondResolution = true;
-
- while(gen > 0) {
- try {
- IndexReader reader = IndexReader.open(dir, true);
- reader.close();
- fileName = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
- "",
- gen);
-
- // if we are on a filesystem that seems to have only
- // 1 second resolution, allow +1 second in commit
- // age tolerance:
- long modTime = dir.fileModified(fileName);
- oneSecondResolution &= (modTime % 1000) == 0;
- final long leeway = (long) ((SECONDS + (oneSecondResolution ? 1.0:0.0))*1000);
-
- assertTrue("commit point was older than " + SECONDS + " seconds (" + (lastDeleteTime - modTime) + " msec) but did not get deleted ", lastDeleteTime - modTime <= leeway);
- } catch (IOException e) {
- // OK
- break;
- }
-
- dir.deleteFile(IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen));
- gen--;
- }
-
- dir.close();
- }
-
- /*
- * Test a silly deletion policy that keeps all commits around.
- */
- public void testKeepAllDeletionPolicy() throws IOException {
- for(int pass=0;pass<2;pass++) {
-
- if (VERBOSE) {
- System.out.println("TEST: cycle pass=" + pass);
- }
-
- boolean useCompoundFile = (pass % 2) != 0;
-
- // Never deletes a commit
- KeepAllDeletionPolicy policy = new KeepAllDeletionPolicy();
-
- Directory dir = newDirectory();
- policy.dir = dir;
-
- IndexWriterConfig conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setIndexDeletionPolicy(policy).setMaxBufferedDocs(10)
- .setMergeScheduler(new SerialMergeScheduler());
- MergePolicy mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- IndexWriter writer = new IndexWriter(dir, conf);
- for(int i=0;i<107;i++) {
- addDoc(writer);
- }
- writer.close();
-
- final boolean isOptimized;
- {
- IndexReader r = IndexReader.open(dir);
- isOptimized = r.isOptimized();
- r.close();
- }
- if (!isOptimized) {
- conf = newIndexWriterConfig(TEST_VERSION_CURRENT,
- new WhitespaceAnalyzer(TEST_VERSION_CURRENT)).setOpenMode(
- OpenMode.APPEND).setIndexDeletionPolicy(policy);
- mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, true);
- }
- if (VERBOSE) {
- System.out.println("TEST: open writer for optimize");
- }
- writer = new IndexWriter(dir, conf);
- writer.setInfoStream(VERBOSE ? System.out : null);
- writer.optimize();
- writer.close();
- }
- assertEquals(isOptimized ? 0:1, policy.numOnInit);
-
- // If we are not auto committing then there should
- // be exactly 2 commits (one per close above):
- assertEquals(1 + (isOptimized ? 0:1), policy.numOnCommit);
-
- // Test listCommits
- Collection<IndexCommit> commits = IndexReader.listCommits(dir);
- // 2 from closing writer
- assertEquals(1 + (isOptimized ? 0:1), commits.size());
-
- // Make sure we can open a reader on each commit:
- for (final IndexCommit commit : commits) {
- IndexReader r = IndexReader.open(commit, null, false);
- r.close();
- }
-
- // Simplistic check: just verify all segments_N's still
- // exist, and, I can open a reader on each:
- dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
- long gen = SegmentInfos.getCurrentSegmentGeneration(dir);
- while(gen > 0) {
- IndexReader reader = IndexReader.open(dir, true);
- reader.close();
- dir.deleteFile(IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen));
- gen--;
-
- if (gen > 0) {
- // Now that we've removed a commit point, which
- // should have orphan'd at least one index file.
- // Open & close a writer and assert that it
- // actually removed something:
- int preCount = dir.listAll().length;
- writer = new IndexWriter(dir, newIndexWriterConfig(
- TEST_VERSION_CURRENT,
- new MockAnalyzer(random)).setOpenMode(
- OpenMode.APPEND).setIndexDeletionPolicy(policy));
- writer.close();
- int postCount = dir.listAll().length;
- assertTrue(postCount < preCount);
- }
- }
-
- dir.close();
- }
- }
-
- /* Uses KeepAllDeletionPolicy to keep all commits around,
- * then, opens a new IndexWriter on a previous commit
- * point. */
- public void testOpenPriorSnapshot() throws IOException {
- // Never deletes a commit
- KeepAllDeletionPolicy policy = new KeepAllDeletionPolicy();
-
- Directory dir = newDirectory();
- policy.dir = dir;
-
- IndexWriter writer = new IndexWriter(
- dir,
- newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
- setIndexDeletionPolicy(policy).
- setMaxBufferedDocs(2).
- setMergePolicy(newLogMergePolicy(10))
- );
- for(int i=0;i<10;i++) {
- addDoc(writer);
- if ((1+i)%2 == 0)
- writer.commit();
- }
- writer.close();
-
- Collection<IndexCommit> commits = IndexReader.listCommits(dir);
- assertEquals(5, commits.size());
- IndexCommit lastCommit = null;
- for (final IndexCommit commit : commits) {
- if (lastCommit == null || commit.getGeneration() > lastCommit.getGeneration())
- lastCommit = commit;
- }
- assertTrue(lastCommit != null);
-
- // Now add 1 doc and optimize
- writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT,
- new MockAnalyzer(random)).setIndexDeletionPolicy(policy));
- addDoc(writer);
- assertEquals(11, writer.numDocs());
- writer.optimize();
- writer.close();
-
- assertEquals(6, IndexReader.listCommits(dir).size());
-
- // Now open writer on the commit just before optimize:
- writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setIndexDeletionPolicy(policy).setIndexCommit(lastCommit));
- assertEquals(10, writer.numDocs());
-
- // Should undo our rollback:
- writer.rollback();
-
- IndexReader r = IndexReader.open(dir, true);
- // Still optimized, still 11 docs
- assertTrue(r.isOptimized());
- assertEquals(11, r.numDocs());
- r.close();
-
- writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setIndexDeletionPolicy(policy).setIndexCommit(lastCommit));
- assertEquals(10, writer.numDocs());
- // Commits the rollback:
- writer.close();
-
- // Now 8 because we made another commit
- assertEquals(7, IndexReader.listCommits(dir).size());
-
- r = IndexReader.open(dir, true);
- // Not optimized because we rolled it back, and now only
- // 10 docs
- assertTrue(!r.isOptimized());
- assertEquals(10, r.numDocs());
- r.close();
-
- // Reoptimize
- writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexDeletionPolicy(policy));
- writer.optimize();
- writer.close();
-
- r = IndexReader.open(dir, true);
- assertTrue(r.isOptimized());
- assertEquals(10, r.numDocs());
- r.close();
-
- // Now open writer on the commit just before optimize,
- // but this time keeping only the last commit:
- writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).setIndexCommit(lastCommit));
- assertEquals(10, writer.numDocs());
-
- // Reader still sees optimized index, because writer
- // opened on the prior commit has not yet committed:
- r = IndexReader.open(dir, true);
- assertTrue(r.isOptimized());
- assertEquals(10, r.numDocs());
- r.close();
-
- writer.close();
-
- // Now reader sees unoptimized index:
- r = IndexReader.open(dir, true);
- assertTrue(!r.isOptimized());
- assertEquals(10, r.numDocs());
- r.close();
-
- dir.close();
- }
-
-
- /* Test keeping NO commit points. This is a viable and
- * useful case eg where you want to build a big index and
- * you know there are no readers.
- */
- public void testKeepNoneOnInitDeletionPolicy() throws IOException {
- for(int pass=0;pass<2;pass++) {
-
- boolean useCompoundFile = (pass % 2) != 0;
-
- KeepNoneOnInitDeletionPolicy policy = new KeepNoneOnInitDeletionPolicy();
-
- Directory dir = newDirectory();
-
- IndexWriterConfig conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.CREATE).setIndexDeletionPolicy(policy)
- .setMaxBufferedDocs(10);
- MergePolicy mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- IndexWriter writer = new IndexWriter(dir, conf);
- for(int i=0;i<107;i++) {
- addDoc(writer);
- }
- writer.close();
-
- conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.APPEND).setIndexDeletionPolicy(policy);
- mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, true);
- }
- writer = new IndexWriter(dir, conf);
- writer.optimize();
- writer.close();
-
- assertEquals(1, policy.numOnInit);
- // If we are not auto committing then there should
- // be exactly 2 commits (one per close above):
- assertEquals(2, policy.numOnCommit);
-
- // Simplistic check: just verify the index is in fact
- // readable:
- IndexReader reader = IndexReader.open(dir, true);
- reader.close();
-
- dir.close();
- }
- }
-
- /*
- * Test a deletion policy that keeps last N commits.
- */
- public void testKeepLastNDeletionPolicy() throws IOException {
- final int N = 5;
-
- for(int pass=0;pass<2;pass++) {
-
- boolean useCompoundFile = (pass % 2) != 0;
-
- Directory dir = newDirectory();
-
- KeepLastNDeletionPolicy policy = new KeepLastNDeletionPolicy(N);
-
- for(int j=0;j<N+1;j++) {
- IndexWriterConfig conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.CREATE).setIndexDeletionPolicy(policy)
- .setMaxBufferedDocs(10);
- MergePolicy mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- IndexWriter writer = new IndexWriter(dir, conf);
- for(int i=0;i<17;i++) {
- addDoc(writer);
- }
- writer.optimize();
- writer.close();
- }
-
- assertTrue(policy.numDelete > 0);
- assertEquals(N, policy.numOnInit);
- assertEquals(N+1, policy.numOnCommit);
-
- // Simplistic check: just verify only the past N segments_N's still
- // exist, and, I can open a reader on each:
- dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
- long gen = SegmentInfos.getCurrentSegmentGeneration(dir);
- for(int i=0;i<N+1;i++) {
- try {
- IndexReader reader = IndexReader.open(dir, true);
- reader.close();
- if (i == N) {
- fail("should have failed on commits prior to last " + N);
- }
- } catch (IOException e) {
- if (i != N) {
- throw e;
- }
- }
- if (i < N) {
- dir.deleteFile(IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen));
- }
- gen--;
- }
-
- dir.close();
- }
- }
-
- /*
- * Test a deletion policy that keeps last N commits
- * around, with reader doing deletes.
- */
- public void testKeepLastNDeletionPolicyWithReader() throws IOException {
- final int N = 10;
-
- for(int pass=0;pass<2;pass++) {
-
- boolean useCompoundFile = (pass % 2) != 0;
-
- KeepLastNDeletionPolicy policy = new KeepLastNDeletionPolicy(N);
-
- Directory dir = newDirectory();
- IndexWriterConfig conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.CREATE).setIndexDeletionPolicy(policy).setMergePolicy(newLogMergePolicy());
- MergePolicy mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- IndexWriter writer = new IndexWriter(dir, conf);
- writer.close();
- Term searchTerm = new Term("content", "aaa");
- Query query = new TermQuery(searchTerm);
-
- for(int i=0;i<N+1;i++) {
- if (VERBOSE) {
- System.out.println("\nTEST: cycle i=" + i);
- }
- conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.APPEND).setIndexDeletionPolicy(policy).setMergePolicy(newLogMergePolicy());
- mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- writer = new IndexWriter(dir, conf);
- writer.setInfoStream(VERBOSE ? System.out : null);
- for(int j=0;j<17;j++) {
- addDoc(writer);
- }
- // this is a commit
- if (VERBOSE) {
- System.out.println("TEST: close writer");
- }
- writer.close();
- IndexReader reader = IndexReader.open(dir, policy, false);
- reader.deleteDocument(3*i+1);
- reader.setNorm(4*i+1, "content", 2.0F);
- IndexSearcher searcher = newSearcher(reader);
- ScoreDoc[] hits = searcher.search(query, null, 1000).scoreDocs;
- assertEquals(16*(1+i), hits.length);
- // this is a commit
- if (VERBOSE) {
- System.out.println("TEST: close reader numOnCommit=" + policy.numOnCommit);
- }
- reader.close();
- searcher.close();
- }
- conf = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.APPEND).setIndexDeletionPolicy(policy);
- mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- IndexReader r = IndexReader.open(dir);
- final boolean wasOptimized = r.isOptimized();
- r.close();
- writer = new IndexWriter(dir, conf);
- writer.optimize();
- // this is a commit
- writer.close();
-
- assertEquals(2*(N+1)+1, policy.numOnInit);
- assertEquals(2*(N+2) - (wasOptimized ? 1:0), policy.numOnCommit);
-
- IndexSearcher searcher = new IndexSearcher(dir, false);
- ScoreDoc[] hits = searcher.search(query, null, 1000).scoreDocs;
- assertEquals(176, hits.length);
-
- // Simplistic check: just verify only the past N segments_N's still
- // exist, and, I can open a reader on each:
- long gen = SegmentInfos.getCurrentSegmentGeneration(dir);
-
- dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
- int expectedCount = 176;
- searcher.close();
- for(int i=0;i<N+1;i++) {
- try {
- IndexReader reader = IndexReader.open(dir, true);
-
- // Work backwards in commits on what the expected
- // count should be.
- searcher = newSearcher(reader);
- hits = searcher.search(query, null, 1000).scoreDocs;
- if (i > 1) {
- if (i % 2 == 0) {
- expectedCount += 1;
- } else {
- expectedCount -= 17;
- }
- }
- assertEquals(expectedCount, hits.length);
- searcher.close();
- reader.close();
- if (i == N) {
- fail("should have failed on commits before last 5");
- }
- } catch (IOException e) {
- if (i != N) {
- throw e;
- }
- }
- if (i < N) {
- dir.deleteFile(IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen));
- }
- gen--;
- }
- dir.close();
- }
- }
-
- /*
- * Test a deletion policy that keeps last N commits
- * around, through creates.
- */
- public void testKeepLastNDeletionPolicyWithCreates() throws IOException {
-
- final int N = 10;
-
- for(int pass=0;pass<2;pass++) {
-
- boolean useCompoundFile = (pass % 2) != 0;
-
- KeepLastNDeletionPolicy policy = new KeepLastNDeletionPolicy(N);
-
- Directory dir = newDirectory();
- IndexWriterConfig conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.CREATE).setIndexDeletionPolicy(policy)
- .setMaxBufferedDocs(10);
- MergePolicy mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- IndexWriter writer = new IndexWriter(dir, conf);
- writer.close();
- Term searchTerm = new Term("content", "aaa");
- Query query = new TermQuery(searchTerm);
-
- for(int i=0;i<N+1;i++) {
-
- conf = newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.APPEND).setIndexDeletionPolicy(policy)
- .setMaxBufferedDocs(10);
- mp = conf.getMergePolicy();
- if (mp instanceof LogMergePolicy) {
- setUseCompoundFile(mp, useCompoundFile);
- }
- writer = new IndexWriter(dir, conf);
- for(int j=0;j<17;j++) {
- addDoc(writer);
- }
- // this is a commit
- writer.close();
- IndexReader reader = IndexReader.open(dir, policy, false);
- reader.deleteDocument(3);
- reader.setNorm(5, "content", 2.0F);
- IndexSearcher searcher = newSearcher(reader);
- ScoreDoc[] hits = searcher.search(query, null, 1000).scoreDocs;
- assertEquals(16, hits.length);
- // this is a commit
- reader.close();
- searcher.close();
-
- writer = new IndexWriter(dir, newIndexWriterConfig(
- TEST_VERSION_CURRENT, new MockAnalyzer(random))
- .setOpenMode(OpenMode.CREATE).setIndexDeletionPolicy(policy));
- // This will not commit: there are no changes
- // pending because we opened for "create":
- writer.close();
- }
-
- assertEquals(3*(N+1), policy.numOnInit);
- assertEquals(3*(N+1)+1, policy.numOnCommit);
-
- IndexSearcher searcher = new IndexSearcher(dir, false);
- ScoreDoc[] hits = searcher.search(query, null, 1000).scoreDocs;
- assertEquals(0, hits.length);
-
- // Simplistic check: just verify only the past N segments_N's still
- // exist, and, I can open a reader on each:
- long gen = SegmentInfos.getCurrentSegmentGeneration(dir);
-
- dir.deleteFile(IndexFileNames.SEGMENTS_GEN);
- int expectedCount = 0;
-
- for(int i=0;i<N+1;i++) {
- try {
- IndexReader reader = IndexReader.open(dir, true);
-
- // Work backwards in commits on what the expected
- // count should be.
- searcher = newSearcher(reader);
- hits = searcher.search(query, null, 1000).scoreDocs;
- assertEquals(expectedCount, hits.length);
- searcher.close();
- if (expectedCount == 0) {
- expectedCount = 16;
- } else if (expectedCount == 16) {
- expectedCount = 17;
- } else if (expectedCount == 17) {
- expectedCount = 0;
- }
- reader.close();
- if (i == N) {
- fail("should have failed on commits before last " + N);
- }
- } catch (IOException e) {
- if (i != N) {
- throw e;
- }
- }
- if (i < N) {
- dir.deleteFile(IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS, "", gen));
- }
- gen--;
- }
-
- dir.close();
- }
- }
-
- private void addDoc(IndexWriter writer) throws IOException
- {
- Document doc = new Document();
- doc.add(newField("content", "aaa", Field.Store.NO, Field.Index.ANALYZED));
- writer.addDocument(doc);
- }
-}