2013-05-01 35 views
10

this veya this'a göre, birden çok iş parçacığıyla aynı dizin araştırıcısını kullandım. Ama FsDirectory'dan MMapDirectory'ye geçtiğimde, ilginç istisnalar aldım.İlginç Lucene.net İstisnası

Bu çalışma ince:

static void Main(string[] args) 
{ 
    DirectoryInfo directoryInfo = new DirectoryInfo(@"C:\Users\Tams\Desktop\new\"); 
    var directory = FSDirectory.Open(directoryInfo); 
    var indexSearcher = new IndexSearcher(directory); 

    const int times = 100; 
    const int concurrentTaskCount = 5; 
    var task = new Task[concurrentTaskCount]; 
    for (int i = 0; i < concurrentTaskCount; i++) 
    { 
     task[i] = new Task(() => Search(indexSearcher, times)); 
     task[i].Start(); 
    } 

    Task.WaitAll(task); 
} 

static void Search(IndexSearcher reader, int times) 
{ 
    List<Document> docs = new List<Document>(10000); 
    for (int i = 0; i < times; i++) 
    { 
     var q = new TermQuery(new Term("title", "volume")); 
     foreach (var scoreDoc in reader.Search(q, 100).ScoreDocs) 
     { 
      docs.Add(reader.Doc(scoreDoc.Doc)); 
     } 
    } 
} 

Fakat bununla:

System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative 
            and less than the size of the collection. 
Parameter name: index 
at System.ThrowHelper.ThrowArgumentOutOfRangeException() 
at System.Collections.Generic.List`1.get_Item(Int32 index) 
at Lucene.Net.Index.FieldInfos.FieldInfo(Int32 fieldNumber) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\FieldInfos.cs:line 378 
at Lucene.Net.Index.FieldsReader.Doc(Int32 n, FieldSelector fieldSelector) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\FieldsReader.cs:line 234 
at Lucene.Net.Index.SegmentReader.Document(Int32 n, FieldSelector fieldSelector) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\SegmentReader.cs:line 1193 
at Lucene.Net.Index.DirectoryReader.Document(Int32 n, FieldSelector fieldSelector) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\DirectoryReader.cs:line 686 
at Lucene.Net.Index.IndexReader.Document(Int32 n) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\IndexReader.cs:line 732 
at Lucene.Net.Search.IndexSearcher.Doc(Int32 i) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Search\IndexSearcher.cs:line 162 
at PerformanceTest.Program.Search(IndexSearcher reader, Int32 times) 
    in c:\Users\Tams\Documents\Visual Studio 2012\Projects\BookCatalog\PerformanceTest\Program.cs:line 28 
at PerformanceTest.Program.<>c__DisplayClass2.<Main>b__0() 
    in c:\Users\Tams\Documents\Visual Studio 2012\Projects\BookCatalog\PerformanceTest\Program.cs:line 43 
at System.Threading.Tasks.Task.InnerInvoke() 
at System.Threading.Tasks.Task.Execute() 

Ya

System.IO.IOException: read past EOF 
at Lucene.Net.Store.BufferedIndexInput.Refill() 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Store\BufferedIndexInput.cs:line 179 
at Lucene.Net.Store.BufferedIndexInput.ReadByte() 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Store\BufferedIndexInput.cs:line 41 
at Lucene.Net.Store.IndexInput.ReadVInt() 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Store\IndexInput.cs:line 88 
at Lucene.Net.Index.FieldsReader.Doc(Int32 n, FieldSelector fieldSelector) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\FieldsReader.cs:line 230 
at Lucene.Net.Index.SegmentReader.Document(Int32 n, FieldSelector fieldSelector) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\SegmentReader.cs:line 1193 
at Lucene.Net.Index.DirectoryReader.Document(Int32 n, FieldSelector fieldSelector) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\DirectoryReader.cs:line 686 
at Lucene.Net.Index.IndexReader.Document(Int32 n) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Index\IndexReader.cs:line 732 
at Lucene.Net.Search.IndexSearcher.Doc(Int32 i) 
    in d:\Lucene.Net\FullRepo\trunk\src\core\Search\IndexSearcher.cs:line 162 
at PerformanceTest.Program.Search(IndexSearcher reader, Int32 times) 
    in c:\Users\Tams\Documents\Visual Studio 2012\Projects\BookCatalog\PerformanceTest\Program.cs:line 28 
at PerformanceTest.Program.<>c__DisplayClass2.<Main>b__0() 
    in c:\Users\Tams\Documents\Visual Studio 2012\Projects\BookCatalog\PerformanceTest\Program.cs:line 43 
at System.Threading.Tasks.Task.InnerInvoke() 
at System.Threading.Tasks.Task.Execute() 
:

static void Main(string[] args) 
{ 
    DirectoryInfo directoryInfo = new DirectoryInfo(@"C:\Users\Tams\Desktop\new\"); 
    var directory = new MMapDirectory(directoryInfo); // CHANGED 
    var indexSearcher = new IndexSearcher(directory); 

    const int times = 100; 
    const int concurrentTaskCount = 5; 
    var task = new Task[concurrentTaskCount]; 
    for (int i = 0; i < concurrentTaskCount; i++) 
    { 
     task[i] = new Task(() => Search(indexSearcher, times)); 
     task[i].Start(); 
    } 

    Task.WaitAll(task); 
} 

static void Search(IndexSearcher reader, int times) 
{ 
    List<Document> docs = new List<Document>(10000); 
    for (int i = 0; i < times; i++) 
    { 
     var q = new TermQuery(new Term("title", "volume")); 
     foreach (var scoreDoc in reader.Search(q, 100).ScoreDocs) 
     { 
      docs.Add(reader.Doc(scoreDoc.Doc)); 
     } 
    } 
} 

ben gibi çeşitli istisnaları olsun

Son kod çalışması, concurrentTaskCount değişkeninin ayarlanması ile para cezası 1

Bir şey mi eksik? Bunun ne olduğunu anlayamıyorum. Aslında

, ben patikayı yok

d: \ Lucene.Net \ FullRepo gövde \ src \ çekirdek \ Mağaza \ \ BufferedIndexInput.cs

Hatta bir yok "d" harfi ile sürücü "d" ile sürücü

+1

istisna stacktrace belirtilen yol ikili değil, makine inşa makineden gelir (Ama MMapDirectory şu anda ... bunu yapmak beklemeyin mutlaka ne yaptığını yapar). – sisve

+0

MMapDirectory .Net uygulamasında bir eşzamanlılık hatası bulduğunuzu düşünüyorsanız, bunu Lucene.net projesine göre bildirmelisiniz. –

+0

@JfBeaulac Bir hata olup olmadığını bilmiyor (bu durum Lucene'de yayınlanmıştır) .NET posta listesi), dolayısıyla burada gönderme. – casperOne

cevap

3

source for MMapDirectory, bu sınıfın beklendiği gibi memory-mapped files kullanılmadığını gösterir. MemoryStream nesnelerini kullanarak tüm indeks dosyalarını belleğe yükler ve farklı thread'lar aradığında ve okunduğunda bu akışların problemin sebebi olduğunu tahmin ederim.

Bellek tabanlı bir dizini RAMDirectory içine yükleyerek alabilirsiniz. Bu sınavı geçiyor.

var fsDirectory = FSDirectory.Open(directoryInfo); 
var directory = new RAMDirectory(fsDirectory); 
+0

Tabii ki değil. Java'dan bir bağlantı noktası, mmapfiles'ın bir türü olarak bile mevcut değil. Java kaynağına bakarsanız, bu aynı şeyi yapar. FsDirectory uygulaması daha büyük dizinler için yavaştır, RAMDirectory harika olurdu, ancak dizinim kullanılabilir belleğin boyutundan çok daha büyük. Daha küçük olsa bile, hala GC duruşlarından muzdarip olursunuz. –

+0

Java, "bu kanalın bir bölgesini doğrudan belleğe eşleştiren" FileChannel.map dosyasına sahiptir. Aramayı MMapIndexInput yapıcısında bulabilirsiniz. Bu, .NET 4'te kullanılabilen MemoryMappedFile.CreateViewStream yöntemiyle eşleşir, ancak bağlantı noktası eşleştirilen dosyaları kullanmaz (bu adın dayandığını beklerim). – sisve

+0

Ah. Şimdi görüyorum. çok teşekkürler. T –