(原创)《Lucene in Action 2nd Edition》Chapter11.2.2中的工具类SearcherManager翻译为C#版本

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lucene.Net.Search;
using Lucene.Net.Index;
using Lucene.Net.Store;
using System.Runtime.CompilerServices;
using System.Threading;

namespace WheatStudio.Utility.Lucene
{
/// <summary>
/// 《Lucene in Action 2nd Edition》 Jun 2010
/// Chapter 11.2.2中的工具类SearcherManager翻译为C#版本
/// 用于多线程环境下共享IndexSearcher(IndexReader)
/// 金思魁
/// </summary>
public class SearcherManager
{
private IndexSearcher currentSearcher;
private IndexWriter writer;
private AutoResetEvent Tevent = new AutoResetEvent(false);

public SearcherManager(Directory dir)
{
currentSearcher = new IndexSearcher(IndexReader.Open(dir));
warm(currentSearcher);
}

public SearcherManager(IndexWriter writer)
{
this.writer = writer;
currentSearcher = new IndexSearcher(writer.GetReader());
warm(currentSearcher);
writer.SetMergedSegmentWarmer(new MyWarmer(this.warm));
}

public virtual void warm(IndexSearcher searcher)
{
/*******************************************
* 用户定制,做一些初始化IndexSearcher的工作
* 每次生成新IndexSearch实例后都会触发
* **********************************
*/
}

private bool reopening;

[MethodImpl(MethodImplOptions.Synchronized)]
private void startReopen()
{
while (reopening)
{
Tevent.WaitOne();
}
reopening = true;
}

[MethodImpl(MethodImplOptions.Synchronized)]
private void doneReopen()
{
reopening = false;
Tevent.Set();
}

/// <summary>
/// 在检查到Index有更新时创建新的IndexSearcher(IndexReader)
/// 可以在每次IndexWriter更新索引后调用,也可以在执行搜索前调用
/// 如果是用IndexWriter构造本类,即使IndexWriter未commit也能搜索到最新更改
/// 如果使用Directory构造本类,IndexWriter调用commit后方能搜索到最新更改
/// </summary>
public void maybeReopen()
{
startReopen();
try
{
IndexSearcher searcher = get();
try
{
IndexReader newReader = currentSearcher.GetIndexReader().Reopen();
if (newReader != currentSearcher.GetIndexReader())
{
IndexSearcher newSearcher = new IndexSearcher(newReader);
if (writer == null)
{
warm(newSearcher);
}
swapSearcher(newSearcher);
}
}
finally
{
release(searcher);
}
}
finally
{
doneReopen();
}
}

/// <summary>
/// 获取IndexSearcher,必须和release方法配对调用
/// </summary>
/// <returns></returns>
[MethodImpl(MethodImplOptions.Synchronized)]
public IndexSearcher get() {
currentSearcher.GetIndexReader().IncRef();
return currentSearcher;
}

[MethodImpl(MethodImplOptions.Synchronized)]
public void release(IndexSearcher searcher)
{
searcher.GetIndexReader().DecRef();
}

[MethodImpl(MethodImplOptions.Synchronized)]
private void swapSearcher(IndexSearcher newSearcher)
{
release(currentSearcher);
currentSearcher = newSearcher;
}

public void close()
{
swapSearcher(null);
}
}

public delegate void WarmDelegate(IndexSearcher reader);
public class MyWarmer : IndexWriter.IndexReaderWarmer
{
public event WarmDelegate WarmEvent;

public MyWarmer(WarmDelegate WarmEvent)
{
this.WarmEvent = WarmEvent;
}

public override void Warm(IndexReader reader)
{
if (WarmEvent != null)
{
WarmEvent(new IndexSearcher(reader));
}
}
}
}
posted @ 2012-03-10 00:43  JSK  阅读(976)  评论(0编辑  收藏  举报