1886 lines
67 KiB
C#
1886 lines
67 KiB
C#
/*
|
|
* 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 Lucene.Net.Documents;
|
|
using Lucene.Net.Support;
|
|
using NUnit.Framework;
|
|
|
|
using WhitespaceAnalyzer = Lucene.Net.Analysis.WhitespaceAnalyzer;
|
|
using StandardAnalyzer = Lucene.Net.Analysis.Standard.StandardAnalyzer;
|
|
using Document = Lucene.Net.Documents.Document;
|
|
using Field = Lucene.Net.Documents.Field;
|
|
using FieldSelector = Lucene.Net.Documents.FieldSelector;
|
|
using SetBasedFieldSelector = Lucene.Net.Documents.SetBasedFieldSelector;
|
|
using FieldOption = Lucene.Net.Index.IndexReader.FieldOption;
|
|
using AlreadyClosedException = Lucene.Net.Store.AlreadyClosedException;
|
|
using Directory = Lucene.Net.Store.Directory;
|
|
using FSDirectory = Lucene.Net.Store.FSDirectory;
|
|
using LockObtainFailedException = Lucene.Net.Store.LockObtainFailedException;
|
|
using MockRAMDirectory = Lucene.Net.Store.MockRAMDirectory;
|
|
using NoSuchDirectoryException = Lucene.Net.Store.NoSuchDirectoryException;
|
|
using RAMDirectory = Lucene.Net.Store.RAMDirectory;
|
|
using FieldCache = Lucene.Net.Search.FieldCache;
|
|
using IndexSearcher = Lucene.Net.Search.IndexSearcher;
|
|
using ScoreDoc = Lucene.Net.Search.ScoreDoc;
|
|
using TermQuery = Lucene.Net.Search.TermQuery;
|
|
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
|
|
using _TestUtil = Lucene.Net.Util._TestUtil;
|
|
|
|
namespace Lucene.Net.Index
|
|
{
|
|
|
|
[TestFixture]
|
|
public class TestIndexReader:LuceneTestCase
|
|
{
|
|
/// <summary>Main for running test case by itself. </summary>
|
|
[STAThread]
|
|
public static void Main(System.String[] args)
|
|
{
|
|
// TestRunner.run(new TestSuite(typeof(TestIndexReader))); // {{Aroush-2.9}} how is this done in NUnit?
|
|
// TestRunner.run (new TestIndexReader("testBasicDelete"));
|
|
// TestRunner.run (new TestIndexReader("testDeleteReaderWriterConflict"));
|
|
// TestRunner.run (new TestIndexReader("testDeleteReaderReaderConflict"));
|
|
// TestRunner.run (new TestIndexReader("testFilesOpenClose"));
|
|
}
|
|
|
|
public TestIndexReader(System.String name):base(name)
|
|
{
|
|
}
|
|
|
|
public TestIndexReader(): base("")
|
|
{
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestCommitUserData()
|
|
{
|
|
RAMDirectory d = new MockRAMDirectory();
|
|
|
|
System.Collections.Generic.IDictionary<string, string> commitUserData = new System.Collections.Generic.Dictionary<string,string>();
|
|
commitUserData["foo"] = "fighters";
|
|
|
|
// set up writer
|
|
IndexWriter writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.SetMaxBufferedDocs(2);
|
|
for (int i = 0; i < 27; i++)
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
|
|
IndexReader r = IndexReader.Open(d, false);
|
|
r.DeleteDocument(5);
|
|
r.Flush(commitUserData);
|
|
r.Close();
|
|
|
|
SegmentInfos sis = new SegmentInfos();
|
|
sis.Read(d);
|
|
IndexReader r2 = IndexReader.Open(d, false);
|
|
IndexCommit c = r.IndexCommit;
|
|
Assert.AreEqual(c.UserData, commitUserData);
|
|
|
|
Assert.AreEqual(sis.GetCurrentSegmentFileName(), c.SegmentsFileName);
|
|
|
|
Assert.IsTrue(c.Equals(r.IndexCommit));
|
|
|
|
// Change the index
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.SetMaxBufferedDocs(2);
|
|
for (int i = 0; i < 7; i++)
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
|
|
IndexReader r3 = r2.Reopen();
|
|
Assert.IsFalse(c.Equals(r3.IndexCommit));
|
|
Assert.IsFalse(r2.IndexCommit.IsOptimized);
|
|
r3.Close();
|
|
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.Optimize();
|
|
writer.Close();
|
|
|
|
r3 = r2.Reopen();
|
|
Assert.IsTrue(r3.IndexCommit.IsOptimized);
|
|
r2.Close();
|
|
r3.Close();
|
|
d.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestIsCurrent()
|
|
{
|
|
RAMDirectory d = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
// set up reader:
|
|
IndexReader reader = IndexReader.Open(d, false);
|
|
Assert.IsTrue(reader.IsCurrent());
|
|
// modify index by adding another document:
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
Assert.IsFalse(reader.IsCurrent());
|
|
// re-create index:
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
Assert.IsFalse(reader.IsCurrent());
|
|
reader.Close();
|
|
d.Close();
|
|
}
|
|
|
|
/// <summary> Tests the IndexReader.getFieldNames implementation</summary>
|
|
/// <throws> Exception on error </throws>
|
|
[Test]
|
|
public virtual void TestGetFieldNames()
|
|
{
|
|
RAMDirectory d = new MockRAMDirectory();
|
|
// set up writer
|
|
IndexWriter writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
// set up reader
|
|
IndexReader reader = IndexReader.Open(d, true);
|
|
System.Collections.Generic.ICollection<string> fieldNames = reader.GetFieldNames(IndexReader.FieldOption.ALL);
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "keyword"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "text"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unindexed"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unstored"));
|
|
reader.Close();
|
|
// add more documents
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
// want to get some more segments here
|
|
for (int i = 0; i < 5 * writer.MergeFactor; i++)
|
|
{
|
|
AddDocumentWithFields(writer);
|
|
}
|
|
// new fields are in some different segments (we hope)
|
|
for (int i = 0; i < 5 * writer.MergeFactor; i++)
|
|
{
|
|
AddDocumentWithDifferentFields(writer);
|
|
}
|
|
// new termvector fields
|
|
for (int i = 0; i < 5 * writer.MergeFactor; i++)
|
|
{
|
|
AddDocumentWithTermVectorFields(writer);
|
|
}
|
|
|
|
writer.Close();
|
|
// verify fields again
|
|
reader = IndexReader.Open(d, true);
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.ALL);
|
|
Assert.AreEqual(13, fieldNames.Count); // the following fields
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "keyword"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "text"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unindexed"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unstored"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "keyword2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "text2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unindexed2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unstored2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvnot"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "termvector"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvposition"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvoffset"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvpositionoffset"));
|
|
|
|
// verify that only indexed fields were returned
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.INDEXED);
|
|
Assert.AreEqual(11, fieldNames.Count); // 6 original + the 5 termvector fields
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "keyword"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "text"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unstored"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "keyword2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "text2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unstored2"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvnot"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "termvector"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvposition"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvoffset"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvpositionoffset"));
|
|
|
|
// verify that only unindexed fields were returned
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.UNINDEXED);
|
|
Assert.AreEqual(2, fieldNames.Count); // the following fields
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unindexed"));
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "unindexed2"));
|
|
|
|
// verify index term vector fields
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.TERMVECTOR);
|
|
Assert.AreEqual(1, fieldNames.Count); // 1 field has term vector only
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "termvector"));
|
|
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.TERMVECTOR_WITH_POSITION);
|
|
Assert.AreEqual(1, fieldNames.Count); // 4 fields are indexed with term vectors
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvposition"));
|
|
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.TERMVECTOR_WITH_OFFSET);
|
|
Assert.AreEqual(1, fieldNames.Count); // 4 fields are indexed with term vectors
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvoffset"));
|
|
|
|
fieldNames = reader.GetFieldNames(IndexReader.FieldOption.TERMVECTOR_WITH_POSITION_OFFSET);
|
|
Assert.AreEqual(1, fieldNames.Count); // 4 fields are indexed with term vectors
|
|
Assert.IsTrue(CollectionsHelper.Contains(fieldNames, "tvpositionoffset"));
|
|
reader.Close();
|
|
d.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestTermVectors()
|
|
{
|
|
RAMDirectory d = new MockRAMDirectory();
|
|
// set up writer
|
|
IndexWriter writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
// want to get some more segments here
|
|
// new termvector fields
|
|
for (int i = 0; i < 5 * writer.MergeFactor; i++)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field("tvnot", "one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
|
|
doc.Add(new Field("termvector", "one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
|
|
doc.Add(new Field("tvoffset", "one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
|
|
doc.Add(new Field("tvposition", "one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS));
|
|
doc.Add(new Field("tvpositionoffset", "one two two three three three", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
|
|
|
|
writer.AddDocument(doc);
|
|
}
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(d, false);
|
|
FieldSortedTermVectorMapper mapper = new FieldSortedTermVectorMapper(new TermVectorEntryFreqSortedComparator());
|
|
reader.GetTermFreqVector(0, mapper);
|
|
var map = mapper.FieldToTerms;
|
|
Assert.IsTrue(map != null, "map is null and it shouldn't be");
|
|
Assert.IsTrue(map.Count == 4, "map Size: " + map.Count + " is not: " + 4);
|
|
var set_Renamed = map["termvector"];
|
|
foreach (var item in set_Renamed)
|
|
{
|
|
TermVectorEntry entry = (TermVectorEntry)item;
|
|
Assert.IsTrue(entry != null, "entry is null and it shouldn't be");
|
|
System.Console.Out.WriteLine("Entry: " + entry);
|
|
}
|
|
}
|
|
|
|
private void AssertTermDocsCount(System.String msg, IndexReader reader, Term term, int expected)
|
|
{
|
|
TermDocs tdocs = null;
|
|
|
|
try
|
|
{
|
|
tdocs = reader.TermDocs(term);
|
|
Assert.IsNotNull(tdocs, msg + ", null TermDocs");
|
|
int count = 0;
|
|
while (tdocs.Next())
|
|
{
|
|
count++;
|
|
}
|
|
Assert.AreEqual(expected, count, msg + ", count mismatch");
|
|
}
|
|
finally
|
|
{
|
|
if (tdocs != null)
|
|
tdocs.Close();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
public virtual void TestBasicDelete()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
|
|
IndexWriter writer = null;
|
|
IndexReader reader = null;
|
|
Term searchTerm = new Term("content", "aaa");
|
|
|
|
// add 100 documents with term : aaa
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
AddDoc(writer, searchTerm.Text);
|
|
}
|
|
writer.Close();
|
|
|
|
// OPEN READER AT THIS POINT - this should fix the view of the
|
|
// index at the point of having 100 "aaa" documents and 0 "bbb"
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "first docFreq");
|
|
AssertTermDocsCount("first reader", reader, searchTerm, 100);
|
|
reader.Close();
|
|
|
|
// DELETE DOCUMENTS CONTAINING TERM: aaa
|
|
int deleted = 0;
|
|
reader = IndexReader.Open(dir, false);
|
|
deleted = reader.DeleteDocuments(searchTerm);
|
|
Assert.AreEqual(100, deleted, "deleted count");
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "deleted docFreq");
|
|
AssertTermDocsCount("deleted termDocs", reader, searchTerm, 0);
|
|
|
|
// open a 2nd reader to make sure first reader can
|
|
// commit its changes (.del) while second reader
|
|
// is open:
|
|
IndexReader reader2 = IndexReader.Open(dir, false);
|
|
reader.Close();
|
|
|
|
// CREATE A NEW READER and re-test
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "deleted docFreq");
|
|
AssertTermDocsCount("deleted termDocs", reader, searchTerm, 0);
|
|
reader.Close();
|
|
reader2.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestBinaryFields()
|
|
{
|
|
Directory dir = new RAMDirectory();
|
|
byte[] bin = new byte[]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
|
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
AddDoc(writer, "document number " + (i + 1));
|
|
AddDocumentWithFields(writer);
|
|
AddDocumentWithDifferentFields(writer);
|
|
AddDocumentWithTermVectorFields(writer);
|
|
}
|
|
writer.Close();
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
Document doc = new Document();
|
|
doc.Add(new Field("bin1", bin, Field.Store.YES));
|
|
doc.Add(new Field("junk", "junk text", Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(doc);
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
doc = reader.Document(reader.MaxDoc - 1);
|
|
Field[] fields = doc.GetFields("bin1");
|
|
Assert.IsNotNull(fields);
|
|
Assert.AreEqual(1, fields.Length);
|
|
Field b1 = fields[0];
|
|
Assert.IsTrue(b1.IsBinary);
|
|
byte[] data1 = b1.GetBinaryValue();
|
|
Assert.AreEqual(bin.Length, b1.BinaryLength);
|
|
for (int i = 0; i < bin.Length; i++)
|
|
{
|
|
Assert.AreEqual(bin[i], data1[i + b1.BinaryOffset]);
|
|
}
|
|
var lazyFields = Support.Compatibility.SetFactory.CreateHashSet<string>();
|
|
lazyFields.Add("bin1");
|
|
FieldSelector sel = new SetBasedFieldSelector(Support.Compatibility.SetFactory.CreateHashSet<string>(), lazyFields);
|
|
doc = reader.Document(reader.MaxDoc - 1, sel);
|
|
IFieldable[] fieldables = doc.GetFieldables("bin1");
|
|
Assert.IsNotNull(fieldables);
|
|
Assert.AreEqual(1, fieldables.Length);
|
|
IFieldable fb1 = fieldables[0];
|
|
Assert.IsTrue(fb1.IsBinary);
|
|
Assert.AreEqual(bin.Length, fb1.BinaryLength);
|
|
data1 = fb1.GetBinaryValue();
|
|
Assert.AreEqual(bin.Length, fb1.BinaryLength);
|
|
for (int i = 0; i < bin.Length; i++)
|
|
{
|
|
Assert.AreEqual(bin[i], data1[i + fb1.BinaryOffset]);
|
|
}
|
|
reader.Close();
|
|
// force optimize
|
|
|
|
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.Optimize();
|
|
writer.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
doc = reader.Document(reader.MaxDoc - 1);
|
|
fields = doc.GetFields("bin1");
|
|
Assert.IsNotNull(fields);
|
|
Assert.AreEqual(1, fields.Length);
|
|
b1 = fields[0];
|
|
Assert.IsTrue(b1.IsBinary);
|
|
data1 = b1.GetBinaryValue();
|
|
Assert.AreEqual(bin.Length, b1.BinaryLength);
|
|
for (int i = 0; i < bin.Length; i++)
|
|
{
|
|
Assert.AreEqual(bin[i], data1[i + b1.BinaryOffset]);
|
|
}
|
|
reader.Close();
|
|
}
|
|
|
|
// Make sure attempts to make changes after reader is
|
|
// closed throws IOException:
|
|
[Test]
|
|
public virtual void TestChangesAfterClose()
|
|
{
|
|
Directory dir = new RAMDirectory();
|
|
|
|
IndexWriter writer = null;
|
|
IndexReader reader = null;
|
|
Term searchTerm = new Term("content", "aaa");
|
|
|
|
// add 11 documents with term : aaa
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 11; i++)
|
|
{
|
|
AddDoc(writer, searchTerm.Text);
|
|
}
|
|
writer.Close();
|
|
|
|
reader = IndexReader.Open(dir, false);
|
|
|
|
// Close reader:
|
|
reader.Close();
|
|
|
|
// Then, try to make changes:
|
|
Assert.Throws<AlreadyClosedException>(() => reader.DeleteDocument(4), "deleteDocument after close failed to throw IOException");
|
|
Assert.Throws<AlreadyClosedException>(() => reader.SetNorm(5, "aaa", 2.0f), "setNorm after close failed to throw IOException");
|
|
Assert.Throws<AlreadyClosedException>(() => reader.UndeleteAll(), "undeleteAll after close failed to throw IOException");
|
|
}
|
|
|
|
// Make sure we get lock obtain failed exception with 2 writers:
|
|
[Test]
|
|
public virtual void TestLockObtainFailed()
|
|
{
|
|
Directory dir = new RAMDirectory();
|
|
|
|
IndexWriter writer = null;
|
|
IndexReader reader = null;
|
|
Term searchTerm = new Term("content", "aaa");
|
|
|
|
// add 11 documents with term : aaa
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 11; i++)
|
|
{
|
|
AddDoc(writer, searchTerm.Text);
|
|
}
|
|
|
|
// Create reader:
|
|
reader = IndexReader.Open(dir, false);
|
|
|
|
// Try to make changes
|
|
Assert.Throws<LockObtainFailedException>(() => reader.DeleteDocument(4), "deleteDocument should have hit LockObtainFailedException");
|
|
Assert.Throws<LockObtainFailedException>(() =>reader.SetNorm(5, "aaa", 2.0f), "setNorm should have hit LockObtainFailedException");
|
|
Assert.Throws<LockObtainFailedException>(() => reader.UndeleteAll(), "undeleteAll should have hit LockObtainFailedException");
|
|
|
|
writer.Close();
|
|
reader.Close();
|
|
}
|
|
|
|
// Make sure you can set norms & commit even if a reader
|
|
// is open against the index:
|
|
[Test]
|
|
public virtual void TestWritingNorms()
|
|
{
|
|
System.String tempDir = AppSettings.Get("tempDir", "");
|
|
if (tempDir == null)
|
|
throw new System.IO.IOException("tempDir undefined, cannot run test");
|
|
|
|
System.IO.DirectoryInfo indexDir = new System.IO.DirectoryInfo(System.IO.Path.Combine(tempDir, "lucenetestnormwriter"));
|
|
Directory dir = FSDirectory.Open(indexDir);
|
|
IndexWriter writer;
|
|
IndexReader reader;
|
|
Term searchTerm = new Term("content", "aaa");
|
|
|
|
// add 1 documents with term : aaa
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDoc(writer, searchTerm.Text);
|
|
writer.Close();
|
|
|
|
// now open reader & set norm for doc 0
|
|
reader = IndexReader.Open(dir, false);
|
|
reader.SetNorm(0, "content", (float) 2.0);
|
|
|
|
// we should be holding the write lock now:
|
|
Assert.IsTrue(IndexWriter.IsLocked(dir), "locked");
|
|
|
|
reader.Commit();
|
|
|
|
// we should not be holding the write lock now:
|
|
Assert.IsTrue(!IndexWriter.IsLocked(dir), "not locked");
|
|
|
|
// open a 2nd reader:
|
|
IndexReader reader2 = IndexReader.Open(dir, false);
|
|
|
|
// set norm again for doc 0
|
|
reader.SetNorm(0, "content", (float) 3.0);
|
|
Assert.IsTrue(IndexWriter.IsLocked(dir), "locked");
|
|
|
|
reader.Close();
|
|
|
|
// we should not be holding the write lock now:
|
|
Assert.IsTrue(!IndexWriter.IsLocked(dir), "not locked");
|
|
|
|
reader2.Close();
|
|
dir.Close();
|
|
|
|
RmDir(indexDir);
|
|
}
|
|
|
|
|
|
// Make sure you can set norms & commit, and there are
|
|
// no extra norms files left:
|
|
[Test]
|
|
public virtual void TestWritingNormsNoReader()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = null;
|
|
IndexReader reader = null;
|
|
Term searchTerm = new Term("content", "aaa");
|
|
|
|
// add 1 documents with term : aaa
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.UseCompoundFile = false;
|
|
AddDoc(writer, searchTerm.Text);
|
|
writer.Close();
|
|
|
|
// now open reader & set norm for doc 0 (writes to
|
|
// _0_1.s0)
|
|
reader = IndexReader.Open(dir, false);
|
|
reader.SetNorm(0, "content", (float) 2.0);
|
|
reader.Close();
|
|
|
|
// now open reader again & set norm for doc 0 (writes to _0_2.s0)
|
|
reader = IndexReader.Open(dir, false);
|
|
reader.SetNorm(0, "content", (float) 2.0);
|
|
reader.Close();
|
|
Assert.IsFalse(dir.FileExists("_0_1.s0"), "failed to remove first generation norms file on writing second generation");
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
|
|
[Test]
|
|
public virtual void TestDeleteReaderWriterConflictUnoptimized()
|
|
{
|
|
DeleteReaderWriterConflict(false);
|
|
}
|
|
|
|
//[Test]
|
|
//public virtual void TestOpenEmptyDirectory()
|
|
//{
|
|
// System.String dirName = "test.empty";
|
|
// System.IO.FileInfo fileDirName = new System.IO.FileInfo(dirName);
|
|
// bool tmpBool;
|
|
// if (System.IO.File.Exists(fileDirName.FullName))
|
|
// tmpBool = true;
|
|
// else
|
|
// tmpBool = System.IO.Directory.Exists(fileDirName.FullName);
|
|
// if (!tmpBool)
|
|
// {
|
|
// System.IO.Directory.CreateDirectory(fileDirName.FullName);
|
|
// }
|
|
// try
|
|
// {
|
|
// IndexReader.Open(fileDirName);
|
|
// Assert.Fail("opening IndexReader on empty directory failed to produce FileNotFoundException");
|
|
// }
|
|
// catch (System.IO.FileNotFoundException e)
|
|
// {
|
|
// // GOOD
|
|
// }
|
|
// RmDir(fileDirName);
|
|
//}
|
|
|
|
[Test]
|
|
public virtual void TestDeleteReaderWriterConflictOptimized()
|
|
{
|
|
DeleteReaderWriterConflict(true);
|
|
}
|
|
|
|
private void DeleteReaderWriterConflict(bool optimize)
|
|
{
|
|
//Directory dir = new RAMDirectory();
|
|
Directory dir = GetDirectory();
|
|
|
|
Term searchTerm = new Term("content", "aaa");
|
|
Term searchTerm2 = new Term("content", "bbb");
|
|
|
|
// add 100 documents with term : aaa
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
AddDoc(writer, searchTerm.Text);
|
|
}
|
|
writer.Close();
|
|
|
|
// OPEN READER AT THIS POINT - this should fix the view of the
|
|
// index at the point of having 100 "aaa" documents and 0 "bbb"
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "first docFreq");
|
|
Assert.AreEqual(0, reader.DocFreq(searchTerm2), "first docFreq");
|
|
AssertTermDocsCount("first reader", reader, searchTerm, 100);
|
|
AssertTermDocsCount("first reader", reader, searchTerm2, 0);
|
|
|
|
// add 100 documents with term : bbb
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
AddDoc(writer, searchTerm2.Text);
|
|
}
|
|
|
|
// REQUEST OPTIMIZATION
|
|
// This causes a new segment to become current for all subsequent
|
|
// searchers. Because of this, deletions made via a previously open
|
|
// reader, which would be applied to that reader's segment, are lost
|
|
// for subsequent searchers/readers
|
|
if (optimize)
|
|
writer.Optimize();
|
|
writer.Close();
|
|
|
|
// The reader should not see the new data
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "first docFreq");
|
|
Assert.AreEqual(0, reader.DocFreq(searchTerm2), "first docFreq");
|
|
AssertTermDocsCount("first reader", reader, searchTerm, 100);
|
|
AssertTermDocsCount("first reader", reader, searchTerm2, 0);
|
|
|
|
|
|
// DELETE DOCUMENTS CONTAINING TERM: aaa
|
|
// NOTE: the reader was created when only "aaa" documents were in
|
|
int deleted = 0;
|
|
Assert.Throws<StaleReaderException>(() => reader.DeleteDocuments(searchTerm),
|
|
"Delete allowed on an index reader with stale segment information");
|
|
|
|
// Re-open index reader and try again. This time it should see
|
|
// the new data.
|
|
reader.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "first docFreq");
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm2), "first docFreq");
|
|
AssertTermDocsCount("first reader", reader, searchTerm, 100);
|
|
AssertTermDocsCount("first reader", reader, searchTerm2, 100);
|
|
|
|
deleted = reader.DeleteDocuments(searchTerm);
|
|
Assert.AreEqual(100, deleted, "deleted count");
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "deleted docFreq");
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm2), "deleted docFreq");
|
|
AssertTermDocsCount("deleted termDocs", reader, searchTerm, 0);
|
|
AssertTermDocsCount("deleted termDocs", reader, searchTerm2, 100);
|
|
reader.Close();
|
|
|
|
// CREATE A NEW READER and re-test
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm), "deleted docFreq");
|
|
Assert.AreEqual(100, reader.DocFreq(searchTerm2), "deleted docFreq");
|
|
AssertTermDocsCount("deleted termDocs", reader, searchTerm, 0);
|
|
AssertTermDocsCount("deleted termDocs", reader, searchTerm2, 100);
|
|
reader.Close();
|
|
}
|
|
|
|
private Directory GetDirectory()
|
|
{
|
|
return FSDirectory.Open(new System.IO.DirectoryInfo(System.IO.Path.Combine(AppSettings.Get("tempDir", ""), "testIndex")));
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestFilesOpenClose()
|
|
{
|
|
// Create initial data set
|
|
System.IO.DirectoryInfo dirFile = new System.IO.DirectoryInfo(System.IO.Path.Combine(AppSettings.Get("tempDir", ""), "testIndex"));
|
|
Directory dir = GetDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDoc(writer, "test");
|
|
writer.Close();
|
|
dir.Close();
|
|
|
|
// Try to erase the data - this ensures that the writer closed all files
|
|
_TestUtil.RmDir(dirFile);
|
|
dir = GetDirectory();
|
|
|
|
// Now create the data set again, just as before
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDoc(writer, "test");
|
|
writer.Close();
|
|
dir.Close();
|
|
|
|
// Now open existing directory and test that reader closes all files
|
|
dir = GetDirectory();
|
|
IndexReader reader1 = IndexReader.Open(dir, false);
|
|
reader1.Close();
|
|
dir.Close();
|
|
|
|
// The following will fail if reader did not close
|
|
// all files
|
|
_TestUtil.RmDir(dirFile);
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestLastModified()
|
|
{
|
|
System.IO.DirectoryInfo fileDir = new System.IO.DirectoryInfo(System.IO.Path.Combine(AppSettings.Get("tempDir", ""), "testIndex"));
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
try
|
|
{
|
|
Directory dir;
|
|
if (0 == i)
|
|
dir = new MockRAMDirectory();
|
|
else
|
|
dir = GetDirectory();
|
|
Assert.IsFalse(IndexReader.IndexExists(dir));
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
Assert.IsTrue(IndexWriter.IsLocked(dir)); // writer open, so dir is locked
|
|
writer.Close();
|
|
Assert.IsTrue(IndexReader.IndexExists(dir));
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
Assert.IsFalse(IndexWriter.IsLocked(dir)); // reader only, no lock
|
|
long version = IndexReader.LastModified(dir);
|
|
if (i == 1)
|
|
{
|
|
long version2 = IndexReader.LastModified(dir);
|
|
Assert.AreEqual(version, version2);
|
|
}
|
|
reader.Close();
|
|
// modify index and check version has been
|
|
// incremented:
|
|
System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * 1000));
|
|
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.IsTrue(version <= IndexReader.LastModified(dir), "old lastModified is " + version + "; new lastModified is " + IndexReader.LastModified(dir));
|
|
reader.Close();
|
|
dir.Close();
|
|
}
|
|
finally
|
|
{
|
|
if (i == 1)
|
|
_TestUtil.RmDir(fileDir);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestVersion()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
Assert.IsFalse(IndexReader.IndexExists(dir));
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
Assert.IsTrue(IndexWriter.IsLocked(dir)); // writer open, so dir is locked
|
|
writer.Close();
|
|
Assert.IsTrue(IndexReader.IndexExists(dir));
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
Assert.IsFalse(IndexWriter.IsLocked(dir)); // reader only, no lock
|
|
long version = IndexReader.GetCurrentVersion(dir);
|
|
reader.Close();
|
|
// modify index and check version has been
|
|
// incremented:
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.IsTrue(version < IndexReader.GetCurrentVersion(dir), "old version is " + version + "; new version is " + IndexReader.GetCurrentVersion(dir));
|
|
reader.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestLock()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
|
|
Assert.Throws<LockObtainFailedException>(() => reader.DeleteDocument(0), "expected lock");
|
|
|
|
IndexWriter.Unlock(dir); // this should not be done in the real world!
|
|
reader.DeleteDocument(0);
|
|
reader.Close();
|
|
writer.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestUndeleteAll()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
reader.DeleteDocument(0);
|
|
reader.DeleteDocument(1);
|
|
reader.UndeleteAll();
|
|
reader.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(2, reader.NumDocs()); // nothing has really been deleted thanks to undeleteAll()
|
|
reader.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestUndeleteAllAfterClose()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
reader.DeleteDocument(0);
|
|
reader.DeleteDocument(1);
|
|
reader.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
reader.UndeleteAll();
|
|
Assert.AreEqual(2, reader.NumDocs()); // nothing has really been deleted thanks to undeleteAll()
|
|
reader.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestUndeleteAllAfterCloseThenReopen()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
reader.DeleteDocument(0);
|
|
reader.DeleteDocument(1);
|
|
reader.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
reader.UndeleteAll();
|
|
reader.Close();
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(2, reader.NumDocs()); // nothing has really been deleted thanks to undeleteAll()
|
|
reader.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestDeleteReaderReaderConflictUnoptimized()
|
|
{
|
|
DeleteReaderReaderConflict(false);
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestDeleteReaderReaderConflictOptimized()
|
|
{
|
|
DeleteReaderReaderConflict(true);
|
|
}
|
|
|
|
/// <summary> Make sure if reader tries to commit but hits disk
|
|
/// full that reader remains consistent and usable.
|
|
/// </summary>
|
|
[Test]
|
|
public virtual void TestDiskFull()
|
|
{
|
|
|
|
bool debug = false;
|
|
Term searchTerm = new Term("content", "aaa");
|
|
int START_COUNT = 157;
|
|
int END_COUNT = 144;
|
|
|
|
// First build up a starting index:
|
|
RAMDirectory startDir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(startDir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 157; i++)
|
|
{
|
|
Document d = new Document();
|
|
d.Add(new Field("id", System.Convert.ToString(i), Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|
d.Add(new Field("content", "aaa " + i, Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(d);
|
|
}
|
|
writer.Close();
|
|
|
|
long diskUsage = startDir.SizeInBytes();
|
|
long diskFree = diskUsage + 100;
|
|
|
|
System.IO.IOException err = null;
|
|
|
|
bool done = false;
|
|
|
|
// Iterate w/ ever increasing free disk space:
|
|
while (!done)
|
|
{
|
|
MockRAMDirectory dir = new MockRAMDirectory(startDir);
|
|
|
|
// If IndexReader hits disk full, it can write to
|
|
// the same files again.
|
|
dir.SetPreventDoubleWrite(false);
|
|
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
|
|
// For each disk size, first try to commit against
|
|
// dir that will hit random IOExceptions & disk
|
|
// full; after, give it infinite disk space & turn
|
|
// off random IOExceptions & retry w/ same reader:
|
|
bool success = false;
|
|
|
|
for (int x = 0; x < 2; x++)
|
|
{
|
|
|
|
double rate = 0.05;
|
|
double diskRatio = ((double) diskFree) / diskUsage;
|
|
long thisDiskFree;
|
|
System.String testName;
|
|
|
|
if (0 == x)
|
|
{
|
|
thisDiskFree = diskFree;
|
|
if (diskRatio >= 2.0)
|
|
{
|
|
rate /= 2;
|
|
}
|
|
if (diskRatio >= 4.0)
|
|
{
|
|
rate /= 2;
|
|
}
|
|
if (diskRatio >= 6.0)
|
|
{
|
|
rate = 0.0;
|
|
}
|
|
if (debug)
|
|
{
|
|
System.Console.Out.WriteLine("\ncycle: " + diskFree + " bytes");
|
|
}
|
|
testName = "disk full during reader.close() @ " + thisDiskFree + " bytes";
|
|
}
|
|
else
|
|
{
|
|
thisDiskFree = 0;
|
|
rate = 0.0;
|
|
if (debug)
|
|
{
|
|
System.Console.Out.WriteLine("\ncycle: same writer: unlimited disk space");
|
|
}
|
|
testName = "reader re-use after disk full";
|
|
}
|
|
|
|
dir.SetMaxSizeInBytes(thisDiskFree);
|
|
dir.SetRandomIOExceptionRate(rate, diskFree);
|
|
|
|
try
|
|
{
|
|
if (0 == x)
|
|
{
|
|
int docId = 12;
|
|
for (int i = 0; i < 13; i++)
|
|
{
|
|
reader.DeleteDocument(docId);
|
|
reader.SetNorm(docId, "contents", (float) 2.0);
|
|
docId += 12;
|
|
}
|
|
}
|
|
reader.Close();
|
|
success = true;
|
|
if (0 == x)
|
|
{
|
|
done = true;
|
|
}
|
|
}
|
|
catch (System.IO.IOException e)
|
|
{
|
|
if (debug)
|
|
{
|
|
System.Console.Out.WriteLine(" hit IOException: " + e);
|
|
System.Console.Out.WriteLine(e.StackTrace);
|
|
}
|
|
err = e;
|
|
if (1 == x)
|
|
{
|
|
System.Console.Error.WriteLine(e.StackTrace);
|
|
Assert.Fail(testName + " hit IOException after disk space was freed up");
|
|
}
|
|
}
|
|
|
|
// Whether we succeeded or failed, check that all
|
|
// un-referenced files were in fact deleted (ie,
|
|
// we did not create garbage). Just create a
|
|
// new IndexFileDeleter, have it delete
|
|
// unreferenced files, then verify that in fact
|
|
// no files were deleted:
|
|
System.String[] startFiles = dir.ListAll();
|
|
SegmentInfos infos = new SegmentInfos();
|
|
infos.Read(dir);
|
|
new IndexFileDeleter(dir, new KeepOnlyLastCommitDeletionPolicy(), infos, null, null,null);
|
|
System.String[] endFiles = dir.ListAll();
|
|
|
|
System.Array.Sort(startFiles);
|
|
System.Array.Sort(endFiles);
|
|
|
|
//for(int i=0;i<startFiles.length;i++) {
|
|
// System.out.println(" startFiles: " + i + ": " + startFiles[i]);
|
|
//}
|
|
|
|
if (!CollectionsHelper.Equals(startFiles, endFiles))
|
|
{
|
|
System.String successStr;
|
|
if (success)
|
|
{
|
|
successStr = "success";
|
|
}
|
|
else
|
|
{
|
|
successStr = "IOException";
|
|
System.Console.Error.WriteLine(err.StackTrace);
|
|
}
|
|
Assert.Fail("reader.close() failed to delete unreferenced files after " + successStr + " (" + diskFree + " bytes): before delete:\n " + ArrayToString(startFiles) + "\n after delete:\n " + ArrayToString(endFiles));
|
|
}
|
|
|
|
// Finally, verify index is not corrupt, and, if
|
|
// we succeeded, we see all docs changed, and if
|
|
// we failed, we see either all docs or no docs
|
|
// changed (transactional semantics):
|
|
IndexReader newReader = null;
|
|
try
|
|
{
|
|
newReader = IndexReader.Open(dir, false);
|
|
}
|
|
catch (System.IO.IOException e)
|
|
{
|
|
System.Console.Error.WriteLine(e.StackTrace);
|
|
Assert.Fail(testName + ":exception when creating IndexReader after disk full during close: " + e);
|
|
}
|
|
/*
|
|
int result = newReader.docFreq(searchTerm);
|
|
if (success) {
|
|
if (result != END_COUNT) {
|
|
fail(testName + ": method did not throw exception but docFreq('aaa') is " + result + " instead of expected " + END_COUNT);
|
|
}
|
|
} else {
|
|
// On hitting exception we still may have added
|
|
// all docs:
|
|
if (result != START_COUNT && result != END_COUNT) {
|
|
err.printStackTrace();
|
|
fail(testName + ": method did throw exception but docFreq('aaa') is " + result + " instead of expected " + START_COUNT + " or " + END_COUNT);
|
|
}
|
|
}
|
|
*/
|
|
|
|
IndexSearcher searcher = new IndexSearcher(newReader);
|
|
ScoreDoc[] hits = null;
|
|
try
|
|
{
|
|
hits = searcher.Search(new TermQuery(searchTerm), null, 1000).ScoreDocs;
|
|
}
|
|
catch (System.IO.IOException e)
|
|
{
|
|
System.Console.Error.WriteLine(e.StackTrace);
|
|
Assert.Fail(testName + ": exception when searching: " + e);
|
|
}
|
|
int result2 = hits.Length;
|
|
if (success)
|
|
{
|
|
if (result2 != END_COUNT)
|
|
{
|
|
Assert.Fail(testName + ": method did not throw exception but hits.length for search on term 'aaa' is " + result2 + " instead of expected " + END_COUNT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// On hitting exception we still may have added
|
|
// all docs:
|
|
if (result2 != START_COUNT && result2 != END_COUNT)
|
|
{
|
|
System.Console.Error.WriteLine(err.StackTrace);
|
|
Assert.Fail(testName + ": method did throw exception but hits.length for search on term 'aaa' is " + result2 + " instead of expected " + START_COUNT);
|
|
}
|
|
}
|
|
|
|
searcher.Close();
|
|
newReader.Close();
|
|
|
|
if (result2 == END_COUNT)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
dir.Close();
|
|
|
|
// Try again with 10 more bytes of free space:
|
|
diskFree += 10;
|
|
}
|
|
|
|
startDir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestDocsOutOfOrderJIRA140()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 11; i++)
|
|
{
|
|
AddDoc(writer, "aaa");
|
|
}
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
|
|
// Try to delete an invalid docId, yet, within range
|
|
// of the final bits of the BitVector:
|
|
|
|
bool gotException = false;
|
|
try
|
|
{
|
|
reader.DeleteDocument(11);
|
|
}
|
|
catch (System.IndexOutOfRangeException e)
|
|
{
|
|
gotException = true;
|
|
}
|
|
reader.Close();
|
|
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
|
|
// We must add more docs to get a new segment written
|
|
for (int i = 0; i < 11; i++)
|
|
{
|
|
AddDoc(writer, "aaa");
|
|
}
|
|
|
|
// Without the fix for LUCENE-140 this call will
|
|
// [incorrectly] hit a "docs out of order"
|
|
// IllegalStateException because above out-of-bounds
|
|
// deleteDocument corrupted the index:
|
|
writer.Optimize();
|
|
writer.Close();
|
|
if (!gotException)
|
|
{
|
|
Assert.Fail("delete of out-of-bounds doc number failed to hit exception");
|
|
}
|
|
dir.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestExceptionReleaseWriteLockJIRA768()
|
|
{
|
|
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDoc(writer, "aaa");
|
|
writer.Close();
|
|
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
Assert.Throws<IndexOutOfRangeException>(() => reader.DeleteDocument(1),
|
|
"did not hit exception when deleting an invalid doc number");
|
|
|
|
reader.Close();
|
|
Assert.IsFalse(IndexWriter.IsLocked(dir), "write lock is still held after close");
|
|
|
|
reader = IndexReader.Open(dir, false);
|
|
Assert.Throws<IndexOutOfRangeException>(() => reader.SetNorm(1, "content", (float) 2.0),
|
|
"did not hit exception when calling setNorm on an invalid doc number");
|
|
|
|
reader.Close();
|
|
Assert.IsFalse(IndexWriter.IsLocked(dir), "write lock is still held after close");
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
private System.String ArrayToString(System.String[] l)
|
|
{
|
|
System.String s = "";
|
|
for (int i = 0; i < l.Length; i++)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
s += "\n ";
|
|
}
|
|
s += l[i];
|
|
}
|
|
return s;
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestOpenReaderAfterDelete()
|
|
{
|
|
System.IO.DirectoryInfo dirFile = new System.IO.DirectoryInfo(System.IO.Path.Combine(AppSettings.Get("tempDir", ""), "deletetest"));
|
|
Directory dir = FSDirectory.Open(dirFile);
|
|
|
|
Assert.Throws<NoSuchDirectoryException>(() => IndexReader.Open(dir, false), "expected FileNotFoundException");
|
|
|
|
bool tmpBool;
|
|
if (System.IO.File.Exists(dirFile.FullName))
|
|
{
|
|
System.IO.File.Delete(dirFile.FullName);
|
|
tmpBool = true;
|
|
}
|
|
else if (System.IO.Directory.Exists(dirFile.FullName))
|
|
{
|
|
System.IO.Directory.Delete(dirFile.FullName);
|
|
tmpBool = true;
|
|
}
|
|
else
|
|
tmpBool = false;
|
|
bool generatedAux = tmpBool;
|
|
|
|
// Make sure we still get a CorruptIndexException (not NPE):
|
|
Assert.Throws<NoSuchDirectoryException>(() => IndexReader.Open(dir, false), "expected FileNotFoundException");
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
private void DeleteReaderReaderConflict(bool optimize)
|
|
{
|
|
Directory dir = GetDirectory();
|
|
|
|
Term searchTerm1 = new Term("content", "aaa");
|
|
Term searchTerm2 = new Term("content", "bbb");
|
|
Term searchTerm3 = new Term("content", "ccc");
|
|
|
|
// add 100 documents with term : aaa
|
|
// add 100 documents with term : bbb
|
|
// add 100 documents with term : ccc
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
for (int i = 0; i < 100; i++)
|
|
{
|
|
AddDoc(writer, searchTerm1.Text);
|
|
AddDoc(writer, searchTerm2.Text);
|
|
AddDoc(writer, searchTerm3.Text);
|
|
}
|
|
if (optimize)
|
|
writer.Optimize();
|
|
writer.Close();
|
|
|
|
// OPEN TWO READERS
|
|
// Both readers get segment info as exists at this time
|
|
IndexReader reader1 = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm1), "first opened");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm2), "first opened");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm3), "first opened");
|
|
AssertTermDocsCount("first opened", reader1, searchTerm1, 100);
|
|
AssertTermDocsCount("first opened", reader1, searchTerm2, 100);
|
|
AssertTermDocsCount("first opened", reader1, searchTerm3, 100);
|
|
|
|
IndexReader reader2 = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm1), "first opened");
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm2), "first opened");
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm3), "first opened");
|
|
AssertTermDocsCount("first opened", reader2, searchTerm1, 100);
|
|
AssertTermDocsCount("first opened", reader2, searchTerm2, 100);
|
|
AssertTermDocsCount("first opened", reader2, searchTerm3, 100);
|
|
|
|
// DELETE DOCS FROM READER 2 and CLOSE IT
|
|
// delete documents containing term: aaa
|
|
// when the reader is closed, the segment info is updated and
|
|
// the first reader is now stale
|
|
reader2.DeleteDocuments(searchTerm1);
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm1), "after delete 1");
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm2), "after delete 1");
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm3), "after delete 1");
|
|
AssertTermDocsCount("after delete 1", reader2, searchTerm1, 0);
|
|
AssertTermDocsCount("after delete 1", reader2, searchTerm2, 100);
|
|
AssertTermDocsCount("after delete 1", reader2, searchTerm3, 100);
|
|
reader2.Close();
|
|
|
|
// Make sure reader 1 is unchanged since it was open earlier
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm1), "after delete 1");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm2), "after delete 1");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm3), "after delete 1");
|
|
AssertTermDocsCount("after delete 1", reader1, searchTerm1, 100);
|
|
AssertTermDocsCount("after delete 1", reader1, searchTerm2, 100);
|
|
AssertTermDocsCount("after delete 1", reader1, searchTerm3, 100);
|
|
|
|
|
|
// ATTEMPT TO DELETE FROM STALE READER
|
|
// delete documents containing term: bbb
|
|
Assert.Throws<StaleReaderException>(() => reader1.DeleteDocuments(searchTerm2),
|
|
"Delete allowed from a stale index reader");
|
|
|
|
// RECREATE READER AND TRY AGAIN
|
|
reader1.Close();
|
|
reader1 = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm1), "reopened");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm2), "reopened");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm3), "reopened");
|
|
AssertTermDocsCount("reopened", reader1, searchTerm1, 0);
|
|
AssertTermDocsCount("reopened", reader1, searchTerm2, 100);
|
|
AssertTermDocsCount("reopened", reader1, searchTerm3, 100);
|
|
|
|
reader1.DeleteDocuments(searchTerm2);
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm1), "deleted 2");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm2), "deleted 2");
|
|
Assert.AreEqual(100, reader1.DocFreq(searchTerm3), "deleted 2");
|
|
AssertTermDocsCount("deleted 2", reader1, searchTerm1, 0);
|
|
AssertTermDocsCount("deleted 2", reader1, searchTerm2, 0);
|
|
AssertTermDocsCount("deleted 2", reader1, searchTerm3, 100);
|
|
reader1.Close();
|
|
|
|
// Open another reader to confirm that everything is deleted
|
|
reader2 = IndexReader.Open(dir, false);
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm1), "reopened 2");
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm2), "reopened 2");
|
|
Assert.AreEqual(100, reader2.DocFreq(searchTerm3), "reopened 2");
|
|
AssertTermDocsCount("reopened 2", reader2, searchTerm1, 0);
|
|
AssertTermDocsCount("reopened 2", reader2, searchTerm2, 0);
|
|
AssertTermDocsCount("reopened 2", reader2, searchTerm3, 100);
|
|
reader2.Close();
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
|
|
private void AddDocumentWithFields(IndexWriter writer)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field("keyword", "test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|
doc.Add(new Field("text", "test1", Field.Store.YES, Field.Index.ANALYZED));
|
|
doc.Add(new Field("unindexed", "test1", Field.Store.YES, Field.Index.NO));
|
|
doc.Add(new Field("unstored", "test1", Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(doc);
|
|
}
|
|
|
|
private void AddDocumentWithDifferentFields(IndexWriter writer)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field("keyword2", "test1", Field.Store.YES, Field.Index.NOT_ANALYZED));
|
|
doc.Add(new Field("text2", "test1", Field.Store.YES, Field.Index.ANALYZED));
|
|
doc.Add(new Field("unindexed2", "test1", Field.Store.YES, Field.Index.NO));
|
|
doc.Add(new Field("unstored2", "test1", Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(doc);
|
|
}
|
|
|
|
private void AddDocumentWithTermVectorFields(IndexWriter writer)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field("tvnot", "tvnot", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.NO));
|
|
doc.Add(new Field("termvector", "termvector", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
|
|
doc.Add(new Field("tvoffset", "tvoffset", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_OFFSETS));
|
|
doc.Add(new Field("tvposition", "tvposition", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS));
|
|
doc.Add(new Field("tvpositionoffset", "tvpositionoffset", Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS));
|
|
|
|
writer.AddDocument(doc);
|
|
}
|
|
|
|
private void AddDoc(IndexWriter writer, System.String value_Renamed)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field("content", value_Renamed, Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(doc);
|
|
}
|
|
private void RmDir(System.IO.DirectoryInfo dir)
|
|
{
|
|
System.IO.FileInfo[] files = FileSupport.GetFiles(dir);
|
|
for (int i = 0; i < files.Length; i++)
|
|
{
|
|
bool tmpBool;
|
|
if (System.IO.File.Exists(files[i].FullName))
|
|
{
|
|
System.IO.File.Delete(files[i].FullName);
|
|
tmpBool = true;
|
|
}
|
|
else if (System.IO.Directory.Exists(files[i].FullName))
|
|
{
|
|
System.IO.Directory.Delete(files[i].FullName);
|
|
tmpBool = true;
|
|
}
|
|
else
|
|
tmpBool = false;
|
|
bool generatedAux = tmpBool;
|
|
}
|
|
bool tmpBool2;
|
|
if (System.IO.File.Exists(dir.FullName))
|
|
{
|
|
System.IO.File.Delete(dir.FullName);
|
|
tmpBool2 = true;
|
|
}
|
|
else if (System.IO.Directory.Exists(dir.FullName))
|
|
{
|
|
System.IO.Directory.Delete(dir.FullName);
|
|
tmpBool2 = true;
|
|
}
|
|
else
|
|
tmpBool2 = false;
|
|
bool generatedAux2 = tmpBool2;
|
|
}
|
|
|
|
public static void AssertIndexEquals(IndexReader index1, IndexReader index2)
|
|
{
|
|
Assert.AreEqual(index1.NumDocs(), index2.NumDocs(), "IndexReaders have different values for numDocs.");
|
|
Assert.AreEqual(index1.MaxDoc, index2.MaxDoc, "IndexReaders have different values for maxDoc.");
|
|
Assert.AreEqual(index1.HasDeletions, index2.HasDeletions, "Only one IndexReader has deletions.");
|
|
Assert.AreEqual(index1.IsOptimized(), index2.IsOptimized(), "Only one index is optimized.");
|
|
|
|
// check field names
|
|
System.Collections.Generic.ICollection<string> fieldsNames1 = index1.GetFieldNames(FieldOption.ALL);
|
|
System.Collections.Generic.ICollection<string> fieldsNames2 = index1.GetFieldNames(FieldOption.ALL);
|
|
|
|
System.Collections.Generic.ICollection<IFieldable> fields1 = null;
|
|
System.Collections.Generic.ICollection<IFieldable> fields2 = null;
|
|
|
|
Assert.AreEqual(fieldsNames1.Count, fieldsNames2.Count, "IndexReaders have different numbers of fields.");
|
|
System.Collections.IEnumerator it1 = fieldsNames1.GetEnumerator();
|
|
System.Collections.IEnumerator it2 = fieldsNames2.GetEnumerator();
|
|
while (it1.MoveNext() && it2.MoveNext())
|
|
{
|
|
Assert.AreEqual((System.String) it1.Current, (System.String) it2.Current, "Different field names.");
|
|
}
|
|
|
|
// check norms
|
|
it1 = fieldsNames1.GetEnumerator();
|
|
while (it1.MoveNext())
|
|
{
|
|
System.String curField = (System.String) it1.Current;
|
|
byte[] norms1 = index1.Norms(curField);
|
|
byte[] norms2 = index2.Norms(curField);
|
|
if (norms1 != null && norms2 != null)
|
|
{
|
|
Assert.AreEqual(norms1.Length, norms2.Length);
|
|
for (int i = 0; i < norms1.Length; i++)
|
|
{
|
|
Assert.AreEqual(norms1[i], norms2[i], "Norm different for doc " + i + " and field '" + curField + "'.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Assert.AreSame(norms1, norms2);
|
|
}
|
|
}
|
|
|
|
// check deletions
|
|
for (int i = 0; i < index1.MaxDoc; i++)
|
|
{
|
|
Assert.AreEqual(index1.IsDeleted(i), index2.IsDeleted(i), "Doc " + i + " only deleted in one index.");
|
|
}
|
|
|
|
// check stored fields
|
|
for (int i = 0; i < index1.MaxDoc; i++)
|
|
{
|
|
if (!index1.IsDeleted(i))
|
|
{
|
|
Document doc1 = index1.Document(i);
|
|
Document doc2 = index2.Document(i);
|
|
fields1 = doc1.GetFields();
|
|
fields2 = doc2.GetFields();
|
|
Assert.AreEqual(fields1.Count, fields2.Count, "Different numbers of fields for doc " + i + ".");
|
|
it1 = fields1.GetEnumerator();
|
|
it2 = fields2.GetEnumerator();
|
|
while (it1.MoveNext() && it2.MoveNext())
|
|
{
|
|
Field curField1 = (Field) it1.Current;
|
|
Field curField2 = (Field) it2.Current;
|
|
Assert.AreEqual(curField1.Name, curField2.Name, "Different fields names for doc " + i + ".");
|
|
Assert.AreEqual(curField1.StringValue, curField2.StringValue, "Different field values for doc " + i + ".");
|
|
}
|
|
}
|
|
}
|
|
|
|
// check dictionary and posting lists
|
|
TermEnum enum1 = index1.Terms();
|
|
TermEnum enum2 = index2.Terms();
|
|
TermPositions tp1 = index1.TermPositions();
|
|
TermPositions tp2 = index2.TermPositions();
|
|
while (enum1.Next())
|
|
{
|
|
Assert.IsTrue(enum2.Next());
|
|
Assert.AreEqual(enum1.Term, enum2.Term, "Different term in dictionary.");
|
|
tp1.Seek(enum1.Term);
|
|
tp2.Seek(enum1.Term);
|
|
while (tp1.Next())
|
|
{
|
|
Assert.IsTrue(tp2.Next());
|
|
Assert.AreEqual(tp1.Doc, tp2.Doc, "Different doc id in postinglist of term " + enum1.Term + ".");
|
|
Assert.AreEqual(tp1.Freq, tp2.Freq, "Different term frequence in postinglist of term " + enum1.Term + ".");
|
|
for (int i = 0; i < tp1.Freq; i++)
|
|
{
|
|
Assert.AreEqual(tp1.NextPosition(), tp2.NextPosition(), "Different positions in postinglist of term " + enum1.Term + ".");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestGetIndexCommit()
|
|
{
|
|
RAMDirectory d = new MockRAMDirectory();
|
|
|
|
// set up writer
|
|
IndexWriter writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.SetMaxBufferedDocs(2);
|
|
for (int i = 0; i < 27; i++)
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
|
|
SegmentInfos sis = new SegmentInfos();
|
|
sis.Read(d);
|
|
IndexReader r = IndexReader.Open(d, false);
|
|
IndexCommit c = r.IndexCommit;
|
|
|
|
Assert.AreEqual(sis.GetCurrentSegmentFileName(), c.SegmentsFileName);
|
|
|
|
Assert.IsTrue(c.Equals(r.IndexCommit));
|
|
|
|
// Change the index
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.SetMaxBufferedDocs(2);
|
|
for (int i = 0; i < 7; i++)
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
|
|
IndexReader r2 = r.Reopen();
|
|
Assert.IsFalse(c.Equals(r2.IndexCommit));
|
|
Assert.IsFalse(r2.IndexCommit.IsOptimized);
|
|
r2.Close();
|
|
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.Optimize();
|
|
writer.Close();
|
|
|
|
r2 = r.Reopen();
|
|
Assert.IsTrue(r2.IndexCommit.IsOptimized);
|
|
|
|
r.Close();
|
|
r2.Close();
|
|
d.Close();
|
|
}
|
|
|
|
[Test]
|
|
public virtual void TestReadOnly()
|
|
{
|
|
RAMDirectory d = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), true, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Commit();
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
|
|
IndexReader r = IndexReader.Open(d, true);
|
|
Assert.Throws<System.NotSupportedException>(() => r.DeleteDocument(0));
|
|
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
AddDocumentWithFields(writer);
|
|
writer.Close();
|
|
|
|
// Make sure reopen is still readonly:
|
|
IndexReader r2 = r.Reopen();
|
|
r.Close();
|
|
|
|
Assert.IsFalse(r == r2);
|
|
Assert.Throws<System.NotSupportedException>(() => r2.DeleteDocument(0));
|
|
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.Optimize();
|
|
writer.Close();
|
|
|
|
// Make sure reopen to a single segment is still readonly:
|
|
IndexReader r3 = r2.Reopen();
|
|
r2.Close();
|
|
|
|
Assert.IsFalse(r == r2);
|
|
Assert.Throws<System.NotSupportedException>(() => r3.DeleteDocument(0));
|
|
|
|
// Make sure write lock isn't held
|
|
writer = new IndexWriter(d, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.LIMITED);
|
|
writer.Close();
|
|
|
|
r3.Close();
|
|
}
|
|
|
|
// LUCENE-1474
|
|
[Test]
|
|
public virtual void TestIndexReader_Rename()
|
|
{
|
|
Directory dir = new RAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
writer.AddDocument(CreateDocument("a"));
|
|
writer.AddDocument(CreateDocument("b"));
|
|
writer.AddDocument(CreateDocument("c"));
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
reader.DeleteDocuments(new Term("id", "a"));
|
|
reader.Flush();
|
|
reader.DeleteDocuments(new Term("id", "b"));
|
|
reader.Close();
|
|
IndexReader.Open(dir, true).Close();
|
|
}
|
|
|
|
// LUCENE-1647
|
|
[Test]
|
|
public virtual void TestIndexReaderUnDeleteAll()
|
|
{
|
|
MockRAMDirectory dir = new MockRAMDirectory();
|
|
dir.SetPreventDoubleWrite(false);
|
|
IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
writer.AddDocument(CreateDocument("a"));
|
|
writer.AddDocument(CreateDocument("b"));
|
|
writer.AddDocument(CreateDocument("c"));
|
|
writer.Close();
|
|
IndexReader reader = IndexReader.Open(dir, false);
|
|
reader.DeleteDocuments(new Term("id", "a"));
|
|
reader.Flush();
|
|
reader.DeleteDocuments(new Term("id", "b"));
|
|
reader.UndeleteAll();
|
|
reader.DeleteDocuments(new Term("id", "b"));
|
|
reader.Close();
|
|
IndexReader.Open(dir, false).Close();
|
|
dir.Close();
|
|
}
|
|
|
|
private Document CreateDocument(System.String id)
|
|
{
|
|
Document doc = new Document();
|
|
doc.Add(new Field("id", id, Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
|
|
return doc;
|
|
}
|
|
|
|
// LUCENE-1468 -- make sure on attempting to open an
|
|
// IndexReader on a non-existent directory, you get a
|
|
// good exception
|
|
[Test]
|
|
public virtual void TestNoDir()
|
|
{
|
|
Directory dir = FSDirectory.Open(_TestUtil.GetTempDir("doesnotexist"));
|
|
Assert.Throws<NoSuchDirectoryException>(() => IndexReader.Open(dir, true), "did not hit expected exception");
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-1509
|
|
[Test]
|
|
public virtual void TestNoDupCommitFileNames()
|
|
{
|
|
|
|
Directory dir = new MockRAMDirectory();
|
|
|
|
IndexWriter writer = new IndexWriter(dir, new StandardAnalyzer(Util.Version.LUCENE_CURRENT), IndexWriter.MaxFieldLength.LIMITED);
|
|
|
|
writer.SetMaxBufferedDocs(2);
|
|
writer.AddDocument(CreateDocument("a"));
|
|
writer.AddDocument(CreateDocument("a"));
|
|
writer.AddDocument(CreateDocument("a"));
|
|
writer.Close();
|
|
|
|
var commits = IndexReader.ListCommits(dir);
|
|
var it = commits.GetEnumerator();
|
|
while (it.MoveNext())
|
|
{
|
|
IndexCommit commit = it.Current;
|
|
System.Collections.Generic.ICollection<string> files = commit.FileNames;
|
|
System.Collections.Hashtable seen = new System.Collections.Hashtable();
|
|
System.Collections.IEnumerator it2 = files.GetEnumerator();
|
|
while (it2.MoveNext())
|
|
{
|
|
System.String fileName = (System.String) it2.Current;
|
|
Assert.IsTrue(!seen.Contains(fileName), "file " + fileName + " was duplicated");
|
|
seen.Add(fileName, fileName);
|
|
}
|
|
}
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-1579: Ensure that on a cloned reader, segments
|
|
// reuse the doc values arrays in FieldCache
|
|
[Test]
|
|
public virtual void TestFieldCacheReuseAfterClone()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
Document doc = new Document();
|
|
doc.Add(new Field("number", "17", Field.Store.NO, Field.Index.NOT_ANALYZED));
|
|
writer.AddDocument(doc);
|
|
writer.Close();
|
|
|
|
// Open reader
|
|
IndexReader r = SegmentReader.GetOnlySegmentReader(dir);
|
|
int[] ints = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(r, "number");
|
|
Assert.AreEqual(1, ints.Length);
|
|
Assert.AreEqual(17, ints[0]);
|
|
|
|
// Clone reader
|
|
IndexReader r2 = (IndexReader) r.Clone();
|
|
r.Close();
|
|
Assert.IsTrue(r2 != r);
|
|
int[] ints2 = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(r2, "number");
|
|
r2.Close();
|
|
|
|
Assert.AreEqual(1, ints2.Length);
|
|
Assert.AreEqual(17, ints2[0]);
|
|
Assert.IsTrue(ints == ints2);
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-1579: Ensure that on a reopened reader, that any
|
|
// shared segments reuse the doc values arrays in
|
|
// FieldCache
|
|
[Test]
|
|
public virtual void TestFieldCacheReuseAfterReopen()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
Document doc = new Document();
|
|
doc.Add(new Field("number", "17", Field.Store.NO, Field.Index.NOT_ANALYZED));
|
|
writer.AddDocument(doc);
|
|
writer.Commit();
|
|
|
|
// Open reader1
|
|
IndexReader r = IndexReader.Open(dir, false);
|
|
IndexReader r1 = SegmentReader.GetOnlySegmentReader(r);
|
|
int[] ints = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(r1, "number");
|
|
Assert.AreEqual(1, ints.Length);
|
|
Assert.AreEqual(17, ints[0]);
|
|
|
|
// Add new segment
|
|
writer.AddDocument(doc);
|
|
writer.Commit();
|
|
|
|
// Reopen reader1 --> reader2
|
|
IndexReader r2 = r.Reopen();
|
|
r.Close();
|
|
IndexReader sub0 = r2.GetSequentialSubReaders()[0];
|
|
int[] ints2 = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(sub0, "number");
|
|
r2.Close();
|
|
Assert.IsTrue(ints == ints2);
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-1579: Make sure all SegmentReaders are new when
|
|
// reopen switches readOnly
|
|
[Test]
|
|
public virtual void TestReopenChangeReadonly()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
Document doc = new Document();
|
|
doc.Add(new Field("number", "17", Field.Store.NO, Field.Index.NOT_ANALYZED));
|
|
writer.AddDocument(doc);
|
|
writer.Commit();
|
|
|
|
// Open reader1
|
|
IndexReader r = IndexReader.Open(dir, false);
|
|
Assert.IsTrue(r is DirectoryReader);
|
|
IndexReader r1 = SegmentReader.GetOnlySegmentReader(r);
|
|
int[] ints = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(r1, "number");
|
|
Assert.AreEqual(1, ints.Length);
|
|
Assert.AreEqual(17, ints[0]);
|
|
|
|
// Reopen to readonly w/ no chnages
|
|
IndexReader r3 = r.Reopen(true);
|
|
Assert.IsTrue(r3 is ReadOnlyDirectoryReader);
|
|
r3.Close();
|
|
|
|
// Add new segment
|
|
writer.AddDocument(doc);
|
|
writer.Commit();
|
|
|
|
// Reopen reader1 --> reader2
|
|
IndexReader r2 = r.Reopen(true);
|
|
r.Close();
|
|
Assert.IsTrue(r2 is ReadOnlyDirectoryReader);
|
|
IndexReader[] subs = r2.GetSequentialSubReaders();
|
|
int[] ints2 = Lucene.Net.Search.FieldCache_Fields.DEFAULT.GetInts(subs[0], "number");
|
|
r2.Close();
|
|
|
|
Assert.IsTrue(subs[0] is ReadOnlySegmentReader);
|
|
Assert.IsTrue(subs[1] is ReadOnlySegmentReader);
|
|
Assert.IsTrue(ints == ints2);
|
|
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-1586: getUniqueTermCount
|
|
[Test]
|
|
public virtual void TestUniqueTermCount()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
Document doc = new Document();
|
|
doc.Add(new Field("field", "a b c d e f g h i j k l m n o p q r s t u v w x y z", Field.Store.NO, Field.Index.ANALYZED));
|
|
doc.Add(new Field("number", "0 1 2 3 4 5 6 7 8 9", Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(doc);
|
|
writer.AddDocument(doc);
|
|
writer.Commit();
|
|
|
|
IndexReader r = IndexReader.Open(dir, false);
|
|
IndexReader r1 = SegmentReader.GetOnlySegmentReader(r);
|
|
Assert.AreEqual(36, r1.UniqueTermCount);
|
|
writer.AddDocument(doc);
|
|
writer.Commit();
|
|
IndexReader r2 = r.Reopen();
|
|
r.Close();
|
|
|
|
Assert.Throws<NotSupportedException>(() => { var tc = r2.UniqueTermCount; }, "expected exception");
|
|
|
|
IndexReader[] subs = r2.GetSequentialSubReaders();
|
|
for (int i = 0; i < subs.Length; i++)
|
|
{
|
|
Assert.AreEqual(36, subs[i].UniqueTermCount);
|
|
}
|
|
r2.Close();
|
|
writer.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-1609: don't load terms index
|
|
[Test]
|
|
public virtual void TestNoTermsIndex()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
Document doc = new Document();
|
|
doc.Add(new Field("field", "a b c d e f g h i j k l m n o p q r s t u v w x y z", Field.Store.NO, Field.Index.ANALYZED));
|
|
doc.Add(new Field("number", "0 1 2 3 4 5 6 7 8 9", Field.Store.NO, Field.Index.ANALYZED));
|
|
writer.AddDocument(doc);
|
|
writer.AddDocument(doc);
|
|
writer.Close();
|
|
|
|
IndexReader r = IndexReader.Open(dir, null, true, - 1);
|
|
|
|
Assert.Throws<SystemException>(() => r.DocFreq(new Term("field", "f")), "did not hit expected exception");
|
|
|
|
Assert.IsFalse(((SegmentReader) r.GetSequentialSubReaders()[0]).TermsIndexLoaded());
|
|
|
|
Assert.AreEqual(-1, (r.GetSequentialSubReaders()[0]).TermInfosIndexDivisor);
|
|
writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
writer.AddDocument(doc);
|
|
writer.Close();
|
|
|
|
// LUCENE-1718: ensure re-open carries over no terms index:
|
|
IndexReader r2 = r.Reopen();
|
|
r.Close();
|
|
IndexReader[] subReaders = r2.GetSequentialSubReaders();
|
|
Assert.AreEqual(2, subReaders.Length);
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
Assert.IsFalse(((SegmentReader) subReaders[i]).TermsIndexLoaded());
|
|
}
|
|
r2.Close();
|
|
dir.Close();
|
|
}
|
|
|
|
// LUCENE-2046
|
|
[Test]
|
|
public void TestPrepareCommitIsCurrent()
|
|
{
|
|
Directory dir = new MockRAMDirectory();
|
|
IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), IndexWriter.MaxFieldLength.UNLIMITED);
|
|
Document doc = new Document();
|
|
writer.AddDocument(doc);
|
|
IndexReader r = IndexReader.Open(dir, true);
|
|
Assert.IsTrue(r.IsCurrent());
|
|
writer.AddDocument(doc);
|
|
writer.PrepareCommit();
|
|
Assert.IsTrue(r.IsCurrent());
|
|
IndexReader r2 = r.Reopen();
|
|
Assert.IsTrue(r == r2);
|
|
writer.Commit();
|
|
Assert.IsFalse(r.IsCurrent());
|
|
writer.Close();
|
|
r.Close();
|
|
dir.Close();
|
|
}
|
|
}
|
|
} |