HitS内部的缓存实现源代码

//Hits的缓冲机制的源代码
package hits;


import java.io.IOException;


import org.apache.lucene.document.Document;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.Weight;


public class Hits {
Weight weight =null;
Searcher searcher = null;
Filter filter = null;
Sort sort = null;
HitDoc hitDoc =null;
//不带排序的构造函数
Hits(Searcher s, Query q, Filter f) throws IOException{
weight = q.weight(s);
searcher = s;
filter = f;

//首先向缓存中添加一定数量的文档
getMoreDocs(50); //retrieve 100 initially 从一百开始
}

//带有排序方式的构造函数
Hits(Searcher s, Query q, Filter f, Sort o) throws IOException{
weight = q.weight(s);
searcher = s;
filter = f;
sort = o;

//首先向缓存中添加一定数量的文档
getMoreDocs(50); //retrieve 100 initially 从一百开始
}

//取得Document的主要方法,参数n代表要取出Hits集合中的第几个Document
public final Document doc(int n) throws IOException{

//从缓冲区中需要的HitDoc类型,这是Document的一个包装类型
HitDoc hitDOc = hitDoc(n);

//Lucene持有一个最近访问的记录,这是一个双向链表记录着
//最近所有访问过的Document。这里的两个操作是将该文档加
//如链表中并且放置在链表的最前端
remove(hitDoc);
addToFront(hitDoc);


//如果当前链表的文档数量大于规定的数量(默认200个), 则从中删除最后一个。
//也就是最不尝试用的一个,这种算法应该为LRU算法
if(numDocs > maxDocs){
HitDoc oldLast = last;
remove(last); //flush last
oldLast.doc = null;
}

//如果不慎发生缓存丢失的情况,则从searcher中重新取回Document
if(hitDoc.doc == null){
hitDoc.doc = searcher.doc(hitDoc.id);
}

//将Document返回
return hitDoc.doc;
}

//该方法由Hits.doc(int)方法调用,用于从缓冲中取出所需的HitDoc型的对象
private final HitDoc hitDoc(int n) throws IOException{
//假如用户请求访问的文档超过缓存的大小,则需要扩大缓存
if(n >= hitDoc.size()){
getMoreDocs(n);
}

//从缓存中取出用户所需要的文档
return (HitDoc) hitDoc.ElementAt(n);
}


//getMoreDocs是根据一个值来取出一定数量的文档放入缓存中
private final void getMoreDocs(int min) throws IOException{
//如果缓存的数量大于参数min,则令min等于缓存的数量
//这主要是保证缓存的增长速度,即每次最少也要增加一倍数量的文档。
if(hitDoc.size() > min)
min = hitDoc.size();

//双倍或得文档,也就是说如果用户获得第N个文档
//则新缓存中至少需要存在2N数量的文档
int n = min * 2;

//通过IndexSearcher的地城API, 获得索引中与query相匹配的前n个文档
//它们被保存在一个TopDocs类型的对象中
TopDocs topDocs = (sort == null) ? searcher.search(weight, filter, n) : searcher.search(weight, filter, n, sort);

//取得总共Hits的数量
length = topDocs.totalHits;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;

//以下是对TopDocs中的所有文档进行分值的分摊
//即首先取得文档的最高分,然后将所有的文档分值除以这个最高得分
//因此,文档的最高得分为1, 所有其他的文档分值都小于1
float scoreNorm 1.0f;
if(length >0 && topDocs.getMaxScore() > 1.0f){
scoreNorm = 1.0f / topDocs.getMaxScore();
}

int end = scoreDocs.length < length ? scoreDocs.length : length;
for(int i = hitDoc.size(); i<end; i++){
hitDoc.addElement(new HitDoc(scoreDocs[i].score * scoreNorm, scoreDocs[i].doc));
}
}

//这是Hits内部类的一个类,用于表示一个检索得到的文档
final class HitDoc{
float score;
int id;
Document doc =null;

//双向链表的前指针
HitDoc next;

///双线链表的后指针
HitDoc prev;

//通过Id和score来构造对象
HitDoc(float s, int i){
score = s;
id = i;


}
}
}

你可能感兴趣的:(HitS内部的缓存实现源代码)