blob: 680792f4e11a5459683fb3357e51e3ebbdf268e3 [file] [log] [blame]
using J2N.Threading;
using Lucene.Net.Documents;
using Lucene.Net.Index.Extensions;
using Lucene.Net.Search;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using JCG = J2N.Collections.Generic;
using Console = Lucene.Net.Support.SystemConsole;
namespace Lucene.Net.Index
{
using BinaryDocValuesField = BinaryDocValuesField;
using BytesRef = Lucene.Net.Util.BytesRef;
using Directory = Lucene.Net.Store.Directory;
using Document = Documents.Document;
using LuceneTestCase = Lucene.Net.Util.LuceneTestCase;
/*
* 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 MockAnalyzer = Lucene.Net.Analysis.MockAnalyzer;
using NumericDocValuesField = NumericDocValuesField;
using SortedDocValuesField = SortedDocValuesField;
using TestUtil = Lucene.Net.Util.TestUtil;
[SuppressCodecs("Lucene3x")]
[TestFixture]
public class TestDocValuesWithThreads : LuceneTestCase
{
[Test]
public virtual void Test()
{
Directory dir = NewDirectory();
IndexWriter w = new IndexWriter(dir, NewIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(Random)).SetMergePolicy(NewLogMergePolicy()));
IList<long?> numbers = new List<long?>();
IList<BytesRef> binary = new List<BytesRef>();
IList<BytesRef> sorted = new List<BytesRef>();
int numDocs = AtLeast(100);
for (int i = 0; i < numDocs; i++)
{
Document d = new Document();
long number = Random.NextInt64();
d.Add(new NumericDocValuesField("number", number));
BytesRef bytes = new BytesRef(TestUtil.RandomRealisticUnicodeString(Random));
d.Add(new BinaryDocValuesField("bytes", bytes));
binary.Add(bytes);
bytes = new BytesRef(TestUtil.RandomRealisticUnicodeString(Random));
d.Add(new SortedDocValuesField("sorted", bytes));
sorted.Add(bytes);
w.AddDocument(d);
numbers.Add(number);
}
w.ForceMerge(1);
IndexReader r = w.GetReader();
w.Dispose();
Assert.AreEqual(1, r.Leaves.Count);
AtomicReader ar = (AtomicReader)r.Leaves[0].Reader;
int numThreads = TestUtil.NextInt32(Random, 2, 5);
IList<ThreadJob> threads = new List<ThreadJob>();
CountdownEvent startingGun = new CountdownEvent(1);
for (int t = 0; t < numThreads; t++)
{
Random threadRandom = new Random(Random.Next());
ThreadJob thread = new ThreadAnonymousInnerClassHelper(this, numbers, binary, sorted, numDocs, ar, startingGun, threadRandom);
thread.Start();
threads.Add(thread);
}
startingGun.Signal();
foreach (ThreadJob thread in threads)
{
thread.Join();
}
r.Dispose();
dir.Dispose();
}
private class ThreadAnonymousInnerClassHelper : ThreadJob
{
private readonly TestDocValuesWithThreads OuterInstance;
private IList<long?> Numbers;
private IList<BytesRef> Binary;
private IList<BytesRef> Sorted;
private int NumDocs;
private AtomicReader Ar;
private CountdownEvent StartingGun;
private Random ThreadRandom;
public ThreadAnonymousInnerClassHelper(TestDocValuesWithThreads outerInstance, IList<long?> numbers, IList<BytesRef> binary, IList<BytesRef> sorted, int numDocs, AtomicReader ar, CountdownEvent startingGun, Random threadRandom)
{
this.OuterInstance = outerInstance;
this.Numbers = numbers;
this.Binary = binary;
this.Sorted = sorted;
this.NumDocs = numDocs;
this.Ar = ar;
this.StartingGun = startingGun;
this.ThreadRandom = threadRandom;
}
public override void Run()
{
try
{
//NumericDocValues ndv = ar.GetNumericDocValues("number");
FieldCache.Int64s ndv = FieldCache.DEFAULT.GetInt64s(Ar, "number", false);
//BinaryDocValues bdv = ar.GetBinaryDocValues("bytes");
BinaryDocValues bdv = FieldCache.DEFAULT.GetTerms(Ar, "bytes", false);
SortedDocValues sdv = FieldCache.DEFAULT.GetTermsIndex(Ar, "sorted");
StartingGun.Wait();
int iters = AtLeast(1000);
BytesRef scratch = new BytesRef();
BytesRef scratch2 = new BytesRef();
for (int iter = 0; iter < iters; iter++)
{
int docID = ThreadRandom.Next(NumDocs);
switch (ThreadRandom.Next(6))
{
#pragma warning disable 612, 618
case 0:
Assert.AreEqual((long)(sbyte)Numbers[docID], (sbyte)FieldCache.DEFAULT.GetBytes(Ar, "number", false).Get(docID));
break;
case 1:
Assert.AreEqual((long)(short)Numbers[docID], FieldCache.DEFAULT.GetInt16s(Ar, "number", false).Get(docID));
break;
#pragma warning restore 612, 618
case 2:
Assert.AreEqual((long)(int)Numbers[docID], FieldCache.DEFAULT.GetInt32s(Ar, "number", false).Get(docID));
break;
case 3:
Assert.AreEqual((long)Numbers[docID], FieldCache.DEFAULT.GetInt64s(Ar, "number", false).Get(docID));
break;
case 4:
Assert.AreEqual(J2N.BitConversion.Int32BitsToSingle((int)Numbers[docID]), FieldCache.DEFAULT.GetSingles(Ar, "number", false).Get(docID), 0.0f);
break;
case 5:
Assert.AreEqual(J2N.BitConversion.Int64BitsToDouble((long)Numbers[docID]), FieldCache.DEFAULT.GetDoubles(Ar, "number", false).Get(docID), 0.0);
break;
}
bdv.Get(docID, scratch);
Assert.AreEqual(Binary[docID], scratch);
// Cannot share a single scratch against two "sources":
sdv.Get(docID, scratch2);
Assert.AreEqual(Sorted[docID], scratch2);
}
}
catch (Exception e)
{
throw new Exception(e.Message, e);
}
}
}
[Test]
public virtual void Test2()
{
Random random = Random;
int NUM_DOCS = AtLeast(100);
Directory dir = NewDirectory();
RandomIndexWriter writer = new RandomIndexWriter(
#if FEATURE_INSTANCE_TESTDATA_INITIALIZATION
this,
#endif
random, dir);
bool allowDups = random.NextBoolean();
ISet<string> seen = new JCG.HashSet<string>();
if (VERBOSE)
{
Console.WriteLine("TEST: NUM_DOCS=" + NUM_DOCS + " allowDups=" + allowDups);
}
int numDocs = 0;
IList<BytesRef> docValues = new List<BytesRef>();
// TODO: deletions
while (numDocs < NUM_DOCS)
{
string s;
if (random.NextBoolean())
{
s = TestUtil.RandomSimpleString(random);
}
else
{
s = TestUtil.RandomUnicodeString(random);
}
BytesRef br = new BytesRef(s);
if (!allowDups)
{
if (seen.Contains(s))
{
continue;
}
seen.Add(s);
}
if (VERBOSE)
{
Console.WriteLine(" " + numDocs + ": s=" + s);
}
Document doc = new Document();
doc.Add(new SortedDocValuesField("stringdv", br));
doc.Add(new NumericDocValuesField("id", numDocs));
docValues.Add(br);
writer.AddDocument(doc);
numDocs++;
if (random.Next(40) == 17)
{
// force flush
writer.GetReader().Dispose();
}
}
writer.ForceMerge(1);
DirectoryReader r = writer.GetReader();
writer.Dispose();
AtomicReader sr = GetOnlySegmentReader(r);
long END_TIME = Environment.TickCount + (TEST_NIGHTLY ? 30 : 1);
int NUM_THREADS = TestUtil.NextInt32(LuceneTestCase.Random, 1, 10);
ThreadJob[] threads = new ThreadJob[NUM_THREADS];
for (int thread = 0; thread < NUM_THREADS; thread++)
{
threads[thread] = new ThreadAnonymousInnerClassHelper2(random, docValues, sr, END_TIME);
threads[thread].Start();
}
foreach (ThreadJob thread in threads)
{
thread.Join();
}
r.Dispose();
dir.Dispose();
}
private class ThreadAnonymousInnerClassHelper2 : ThreadJob
{
private Random Random;
private IList<BytesRef> DocValues;
private AtomicReader Sr;
private long END_TIME;
public ThreadAnonymousInnerClassHelper2(Random random, IList<BytesRef> docValues, AtomicReader sr, long END_TIME)
{
this.Random = random;
this.DocValues = docValues;
this.Sr = sr;
this.END_TIME = END_TIME;
}
public override void Run()
{
Random random = Random;
SortedDocValues stringDVDirect;
NumericDocValues docIDToID;
try
{
stringDVDirect = Sr.GetSortedDocValues("stringdv");
docIDToID = Sr.GetNumericDocValues("id");
Assert.IsNotNull(stringDVDirect);
}
catch (IOException ioe)
{
throw new Exception(ioe.ToString(), ioe);
}
while (Environment.TickCount < END_TIME)
{
SortedDocValues source;
source = stringDVDirect;
BytesRef scratch = new BytesRef();
for (int iter = 0; iter < 100; iter++)
{
int docID = random.Next(Sr.MaxDoc);
source.Get(docID, scratch);
Assert.AreEqual(DocValues[(int)docIDToID.Get(docID)], scratch);
}
}
}
}
}
}