2013-05-01 28 views
10

Theo this hoặc this, tôi đã sử dụng cùng một trình tìm kiếm chỉ mục theo nhiều chuỗi. Nhưng khi tôi chuyển từ FsDirectory sang MMapDirectory, tôi có ngoại lệ thú vị.Ngoại lệ Lucene.net thú vị

Công việc này tốt:

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)); 
     } 
    } 
} 

Nhưng với điều này:

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)); 
     } 
    } 
} 

tôi nhận được ngoại lệ khác nhau như:

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() 

Hoặc

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() 

Mã cuối cùng hoạt động tốt, với việc đặt biến concurrentTaskCount thành 1.

Tôi có thiếu gì đó không? Tôi không thể hiểu được đó là gì.

Thực ra, tôi không có con đường

d: \ Lucene.Net \ FullRepo \ trunk \ src \ core \ Store \ BufferedIndexInput.cs

tôi thậm chí không có một lái xe có chữ "d"

+1

Đường dẫn được đề cập trong stacktrace ngoại lệ xuất phát từ máy xây dựng các nhị phân, không máy tính của bạn. – sisve

+0

Nếu bạn nghĩ rằng bạn đã tìm thấy một lỗi đồng thời trong việc thực hiện MMapDirectory .Net, bạn nên báo cáo nó với hệ thống báo lỗi chính tả của Lucene.net projet –

+0

@JfBeaulac Ông ấy không biết đó có phải là lỗi hay không. Danh sách gửi thư .NET), do đó đăng bài ở đây. – casperOne

Trả lời

3

source for MMapDirectory cho thấy lớp này không sử dụng memory-mapped files, như mong đợi. Nó tải tất cả các tệp chỉ mục vào bộ nhớ bằng cách sử dụng các đối tượng MemoryStream, và tôi đoán rằng các luồng đó là nguyên nhân của vấn đề khi các luồng khác nhau tìm kiếm và đọc.

Bạn có thể lấy chỉ mục dựa trên bộ nhớ bằng cách tải chỉ mục đó vào thư mục RAMDirectory. Điều này vượt qua bài kiểm tra của bạn. (Nhưng nó làm những gì MMapDirectory hiện có, không nhất thiết những gì bạn mong đợi nó để làm ...)

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

Tất nhiên là không. Một cổng của nó từ Java, trong đó mmapfiles thậm chí không tồn tại như một kiểu. Nếu bạn nhìn vào nguồn Java, điều đó cũng giống như thời gian. FsDirectory thực hiện chậm cho các chỉ số lớn hơn, RAMDirectory sẽ là tuyệt vời, nhưng chỉ số của tôi là lớn hơn nhiều so với kích thước của bộ nhớ có sẵn. Thậm chí nó sẽ nhỏ hơn, bạn vẫn sẽ bị GC dừng lại. –

+0

Java có FileChannel.map mà "ánh xạ vùng của tệp của kênh này trực tiếp vào bộ nhớ". Bạn có thể tìm thấy cuộc gọi trong hàm tạo MMapIndexInput. Điều này phù hợp với phương pháp MemoryMappedFile.CreateViewStream có sẵn trong .NET 4, nhưng cổng không sử dụng các tệp ánh xạ bộ nhớ (mà tôi dự kiến ​​nó sẽ làm, dựa trên tên). – sisve

+0

Ah. Tôi hiểu rồi. cảm ơn rất nhiều. T –

Các vấn đề liên quan