cachingindexreader.java
来自「jsr170接口的java实现。是个apache的开源项目。」· Java 代码 · 共 252 行
JAVA
252 行
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.jackrabbit.core.query.lucene;import org.apache.lucene.document.Document;import org.apache.lucene.index.FilterIndexReader;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.Term;import org.apache.lucene.index.TermDocs;import org.apache.lucene.index.TermEnum;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.util.BitSet;/** * Implements an <code>IndexReader</code> that maintains caches to resolve * {@link #getParent(int, BitSet)} calls efficiently. * <p/> */class CachingIndexReader extends FilterIndexReader { /** * The logger instance for this class. */ private static final Logger log = LoggerFactory.getLogger(CachingIndexReader.class); /** * The current value of the global creation tick counter. */ private static long currentTick; /** * Cache of nodes parent relation. If an entry in the array is not null, * that means the node with the document number = array-index has the node * with <code>DocId</code> as parent. */ private final DocId[] parents; /** * Tick when this index reader was created. */ private final long creationTick = getNextCreationTick(); /** * Document number cache if available. May be <code>null</code>. */ private final DocNumberCache cache; /** * Creates a new <code>CachingIndexReader</code> based on * <code>delegatee</code> * * @param delegatee the base <code>IndexReader</code>. * @param cache a document number cache, or <code>null</code> if not * available to this reader. */ CachingIndexReader(IndexReader delegatee, DocNumberCache cache) { super(delegatee); this.cache = cache; parents = new DocId[delegatee.maxDoc()]; } /** * Returns the <code>DocId</code> of the parent of <code>n</code> or * {@link DocId#NULL} if <code>n</code> does not have a parent * (<code>n</code> is the root node). * * @param n the document number. * @param deleted the documents that should be regarded as deleted. * @return the <code>DocId</code> of <code>n</code>'s parent. * @throws IOException if an error occurs while reading from the index. */ DocId getParent(int n, BitSet deleted) throws IOException { DocId parent; boolean existing = false; parent = parents[n]; if (parent != null) { existing = true; // check if valid and reset if necessary if (!parent.isValid(deleted)) { if (log.isDebugEnabled()) { log.debug(parent + " not valid anymore."); } parent = null; } } if (parent == null) { Document doc = document(n); String parentUUID = doc.get(FieldNames.PARENT); if (parentUUID == null || parentUUID.length() == 0) { parent = DocId.NULL; } else { // only create a DocId from document number if there is no // existing DocId if (!existing) { Term id = new Term(FieldNames.UUID, parentUUID); TermDocs docs = termDocs(id); try { while (docs.next()) { if (!deleted.get(docs.doc())) { parent = DocId.create(docs.doc()); break; } } } finally { docs.close(); } } // if still null, then parent is not in this index, or existing // DocId was invalid. thus, only allowed to create DocId from uuid if (parent == null) { parent = DocId.create(parentUUID); } } // finally put to cache parents[n] = parent; } return parent; } /** * Returns the tick value when this reader was created. * * @return the creation tick for this reader. */ public long getCreationTick() { return creationTick; } //--------------------< FilterIndexReader overwrites >---------------------- /** * If the field of <code>term</code> is {@link FieldNames#UUID} this * <code>CachingIndexReader</code> returns a <code>TermDocs</code> instance * with a cached document id. If <code>term</code> has any other field * the call is delegated to the base <code>IndexReader</code>.<br/> * If <code>term</code> is for a {@link FieldNames#UUID} field and this * <code>CachingIndexReader</code> does not have such a document, * {@link #EMPTY} is returned. * * @param term the term to start the <code>TermDocs</code> enumeration. * @return a TermDocs instance. * @throws IOException if an error occurs while reading from the index. */ public TermDocs termDocs(Term term) throws IOException { if (term.field() == FieldNames.UUID) { // check cache if we have one if (cache != null) { DocNumberCache.Entry e = cache.get(term.text()); if (e != null) { // check if valid // the cache may contain entries from a different reader // with the same uuid. that happens when a node is updated // and is reindexed. the node 'travels' from an older index // to a newer one. the cache will still contain a cache // entry from the old until it is overwritten by the // newer index. if (e.reader == this && !isDeleted(e.doc)) { return new SingleTermDocs(e.doc); } } // not in cache or invalid TermDocs docs = in.termDocs(term); try { if (docs.next()) { // put to cache cache.put(term.text(), this, docs.doc()); // and return return new SingleTermDocs(docs.doc()); } else { return EMPTY; } } finally { docs.close(); } } } return super.termDocs(term); } //----------------------< internal >---------------------------------------- /** * Returns the next creation tick value. * * @return the next creation tick value. */ private static long getNextCreationTick() { synchronized (CachingIndexReader.class) { return currentTick++; } } /** * Implements an empty TermDocs. */ static final TermDocs EMPTY = new TermDocs() { public void seek(Term term) { } public void seek(TermEnum termEnum) { } public int doc() { return -1; } public int freq() { return -1; } public boolean next() { return false; } public int read(int[] docs, int[] freqs) { return 0; } public boolean skipTo(int target) { return false; } public void close() { } };}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?