Index: lucene/src/test/org/apache/lucene/index/TestNRTDeletedOpenFileCount.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ lucene/src/test/org/apache/lucene/index/TestNRTDeletedOpenFileCount.java Wed Nov 17 08:44:18 2010 -0500 @@ -0,0 +1,189 @@ +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.File; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.lucene.analysis.MockAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.index.codecs.CodecProvider; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.store.FSDirectory; +import org.apache.lucene.store.MockDirectoryWrapper; +import org.apache.lucene.util.LineFileDocs; +import org.apache.lucene.util.LuceneTestCase; +import org.apache.lucene.util._TestUtil; +import org.junit.Test; + +import static org.junit.Assert.*; +import static org.junit.Assume.*; + +// TODO +// - update document too +// - delete by term/query +// - mix in commit, optimize, addIndexes +// - install a merged segment warmer that loads stored +// docs!! + +public class TestNRTDeletedOpenFileCount extends LuceneTestCase { + + private final static String WIKI_LINE_FILE = "/lucene/data/enwiki-20100302-lines-1k.txt"; + + @Test + public void testDeleteOpenFileCount() throws Exception { + + if (CodecProvider.getDefaultCodec().equals("SimpleText")) { + // no + CodecProvider.setDefaultCodec("Standard"); + CodecProvider.getDefault().setDefaultFieldCodec("Standard"); + } + + final File wikiFile = new File(WIKI_LINE_FILE); + assumeTrue("wiki line file \"" + WIKI_LINE_FILE + "\" does not exist", wikiFile.exists()); + + final LineFileDocs docs = new LineFileDocs(wikiFile); + final MockDirectoryWrapper dir = new MockDirectoryWrapper(random, FSDirectory.open(_TestUtil.getTempDir("nrtopenfiles"))); + final IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer())); + if (VERBOSE) { + writer.setInfoStream(System.out); + } + MergeScheduler ms = writer.getMergeScheduler(); + if (ms instanceof ConcurrentMergeScheduler) { + // try to keep max file open count down + ((ConcurrentMergeScheduler) ms).setMaxThreadCount(1); + ((ConcurrentMergeScheduler) ms).setMaxMergeCount(1); + } + LogMergePolicy lmp = (LogMergePolicy) writer.getMergePolicy(); + if (lmp.getMergeFactor() > 5) { + lmp.setMergeFactor(5); + } + + final int NUM_THREADS = 4; + final int RUN_TIME_SEC = 50; + + final AtomicBoolean failed = new AtomicBoolean(); + final AtomicInteger addCount = new AtomicInteger(); + final long stopTime = System.currentTimeMillis() + RUN_TIME_SEC*1000; + Thread[] threads = new Thread[NUM_THREADS]; + for(int thread=0;thread 0; + //assertEquals("open but deleted: " + openDeletedFiles, 0, openDeletedFiles.size()); + if (VERBOSE) { + System.out.println("TEST: now open"); + } + r = IndexReader.open(writer); + } + if (VERBOSE) { + System.out.println("TEST: got new reader=" + r); + } + //System.out.println("numDocs=" + r.numDocs() + " openDelFileCount=" + dir.openDeleteFileCount()); + smokeTestReader(r); + } + + //System.out.println("numDocs=" + r.numDocs() + " openDelFileCount=" + dir.openDeleteFileCount()); + r.close(); + final Set openDeletedFiles = dir.getOpenDeletedFiles(); + if (openDeletedFiles.size() > 0) { + System.out.println("OBD files: " + openDeletedFiles); + } + any |= openDeletedFiles.size() > 0; + + assertFalse("saw non-zero open-but-deleted count", any); + + for(int thread=0;thread threadDocs = new ThreadLocal(); + + // Document instance is re-used per-thread + public Document nextDoc() throws IOException { + String line; + synchronized(this) { + line = reader.readLine(); + if (line == null) { + return null; + } + } + + DocState docState = threadDocs.get(); + if (docState == null) { + docState = new DocState(); + threadDocs.set(docState); + } + + int spot = line.indexOf(SEP); + if (spot == -1) { + throw new RuntimeException("line: [" + line + "] is in an invalid format !"); + } + int spot2 = line.indexOf(SEP, 1 + spot); + if (spot2 == -1) { + throw new RuntimeException("line: [" + line + "] is in an invalid format !"); + } + + docState.body.setValue(line.substring(1+spot2, line.length())); + final String title = line.substring(0, spot); + docState.title.setValue(title); + docState.titleTokenized.setValue(title); + docState.date.setValue(line.substring(1+spot, spot2)); + docState.id.setValue(Integer.toString(id.getAndIncrement())); + return docState.doc; + } +}