其中,Server是http服务器,聚合了Connector(http请求接收器)和请求处理器Hanlder,Server本身是一个handler和一个线程池,Connector使用线程池来调用handle方法。
/** Jetty HTTP Servlet Server.
* This class is the main class for the Jetty HTTP Servlet server.
* It aggregates Connectors (HTTP request receivers) and request Handlers.
* The server is itself a handler and a ThreadPool. Connectors use the ThreadPool methods
* to run jobs that will eventually call the handle method.
*/
其工作流程如下图所示
因其不是本文重点,故略去不述。
7.solr调用lucene过程
上篇文章
8.lucene调用过程
从上图可以看出分两个阶段
8.1 创建Weight
8.1.1 创建BooleanWeight
BooleanWeight.java
BooleanWeight(BooleanQuery query, IndexSearcher searcher,booleanneedsScores,floatboost)throws IOException {
super(query);
this.query = query;
this.needsScores = needsScores;
this.similarity = searcher.getSimilarity(needsScores);
weights =newArrayList ();
for (BooleanClause c : query) {
Query q=c.getQuery(); Weight w = searcher.createWeight(q, needsScores && c.isScoring(), boost);weights.add(w); } }
8.1.2 同义词权重分析
SynonymQuery.java
@Override
publicWeight createWeight(IndexSearcher searcher,booleanneedsScores,floatboost)throws IOException {
if (needsScores) {
returnnewSynonymWeight(this, searcher, boost);
} else {
// if scores are not needed, let BooleanWeight deal with optimizing that case.BooleanQuery.Builder bq =new BooleanQuery.Builder();
for (Term term : terms) {
bq.add(new TermQuery(term), BooleanClause.Occur.SHOULD);
}
return searcher.rewrite(bq.build()).createWeight(searcher, needsScores, boost);} }
8.1.3 TermQuery.java
@Override
publicWeight createWeight(IndexSearcher searcher,booleanneedsScores,floatboost)throws IOException {
finalIndexReaderContext context = searcher.getTopReaderContext();
final TermContext termState;
if(perReaderTermState ==null|| perReaderTermState.wasBuiltFor(context) ==false) {
if (needsScores) {
// make TermQuery single-pass if we don't have a PRTS or if the context
// differs!termState = TermContext.build(context, term);
} else {
// do not compute the term state, this will help save seeks in the terms
// dict on segments that have a cache entry for this querytermState =null;
}
} else {
// PRTS was pre-build for this IStermState =this.perReaderTermState;
}
return new TermWeight(searcher, needsScores, boost, termState);}
调用TermWeight,计算CollectionStatistics和TermStatistics
publicTermWeight(IndexSearcher searcher,boolean needsScores,
floatboost, TermContext termStates)throws IOException {
super(TermQuery.this);
if(needsScores && termStates ==null) {
thrownewIllegalStateException("termStates are required when scores are needed");
}
this.needsScores = needsScores;
this.termStates = termStates;
this.similarity = searcher.getSimilarity(needsScores);
final CollectionStatistics collectionStats;
final TermStatistics termStats;
if (needsScores) {
termStates.setQuery(this.getQuery().getKeyword());
collectionStats = searcher.collectionStatistics(term.field());
termStats = searcher.termStatistics(term, termStates);
} else {
// we do not need the actual stats, use fake stats with docFreq=maxDoc and ttf=-1finalintmaxDoc = searcher.getIndexReader().maxDoc();
collectionStats =newCollectionStatistics(term.field(), maxDoc, -1, -1, -1);
termStats =newTermStatistics(term.bytes(), maxDoc, -1,term.bytes());
}
this.stats = similarity.computeWeight(boost, collectionStats, termStats);}
调用Similarity的computeWeight
BM25Similarity.java
@Override
publicfinalSimWeight computeWeight(float boost, CollectionStatistics collectionStats, TermStatistics... termStats) {
Explanation idf = termStats.length == 1 ? idfExplain(collectionStats, termStats[0]) : idfExplain(collectionStats, termStats);
floatavgdl = avgFieldLength(collectionStats);
float[] oldCache =newfloat[256];
float[] cache =newfloat[256];
for(inti = 0; i < cache.length; i++) {
oldCache[i] = k1 * ((1 - b) + b * OLD_LENGTH_TABLE[i] / avgdl);
cache[i] = k1 * ((1 - b) + b * LENGTH_TABLE[i] / avgdl);
}
returnnew BM25Stats(collectionStats.field(), boost, idf, avgdl, oldCache, cache);
}