📄 multisegmentreader.java
字号:
public synchronized byte[] norms(String field) throws IOException { ensureOpen(); byte[] bytes = (byte[])normsCache.get(field); if (bytes != null) return bytes; // cache hit if (!hasNorms(field)) return fakeNorms(); bytes = new byte[maxDoc()]; for (int i = 0; i < subReaders.length; i++) subReaders[i].norms(field, bytes, starts[i]); normsCache.put(field, bytes); // update cache return bytes; } public synchronized void norms(String field, byte[] result, int offset) throws IOException { ensureOpen(); byte[] bytes = (byte[])normsCache.get(field); if (bytes==null && !hasNorms(field)) bytes=fakeNorms(); if (bytes != null) // cache hit System.arraycopy(bytes, 0, result, offset, maxDoc()); for (int i = 0; i < subReaders.length; i++) // read from segments subReaders[i].norms(field, result, offset + starts[i]); } protected void doSetNorm(int n, String field, byte value) throws CorruptIndexException, IOException { synchronized (normsCache) { normsCache.remove(field); // clear cache } int i = readerIndex(n); // find segment num subReaders[i].setNorm(n-starts[i], field, value); // dispatch } public TermEnum terms() throws IOException { ensureOpen(); return new MultiTermEnum(subReaders, starts, null); } public TermEnum terms(Term term) throws IOException { ensureOpen(); return new MultiTermEnum(subReaders, starts, term); } public int docFreq(Term t) throws IOException { ensureOpen(); int total = 0; // sum freqs in segments for (int i = 0; i < subReaders.length; i++) total += subReaders[i].docFreq(t); return total; } public TermDocs termDocs() throws IOException { ensureOpen(); return new MultiTermDocs(subReaders, starts); } public TermPositions termPositions() throws IOException { ensureOpen(); return new MultiTermPositions(subReaders, starts); } protected void commitChanges() throws IOException { for (int i = 0; i < subReaders.length; i++) subReaders[i].commit(); } void startCommit() { super.startCommit(); for (int i = 0; i < subReaders.length; i++) { subReaders[i].startCommit(); } } void rollbackCommit() { super.rollbackCommit(); for (int i = 0; i < subReaders.length; i++) { subReaders[i].rollbackCommit(); } } protected synchronized void doClose() throws IOException { for (int i = 0; i < subReaders.length; i++) subReaders[i].decRef(); // maybe close directory super.doClose(); } public Collection getFieldNames (IndexReader.FieldOption fieldNames) { ensureOpen(); return getFieldNames(fieldNames, this.subReaders); } static Collection getFieldNames (IndexReader.FieldOption fieldNames, IndexReader[] subReaders) { // maintain a unique set of field names Set fieldSet = new HashSet(); for (int i = 0; i < subReaders.length; i++) { IndexReader reader = subReaders[i]; Collection names = reader.getFieldNames(fieldNames); fieldSet.addAll(names); } return fieldSet; } // for testing SegmentReader[] getSubReaders() { return subReaders; } public void setTermInfosIndexDivisor(int indexDivisor) throws IllegalStateException { for (int i = 0; i < subReaders.length; i++) subReaders[i].setTermInfosIndexDivisor(indexDivisor); } public int getTermInfosIndexDivisor() throws IllegalStateException { if (subReaders.length > 0) return subReaders[0].getTermInfosIndexDivisor(); else throw new IllegalStateException("no readers"); } static class MultiTermEnum extends TermEnum { private SegmentMergeQueue queue; private Term term; private int docFreq; public MultiTermEnum(IndexReader[] readers, int[] starts, Term t) throws IOException { queue = new SegmentMergeQueue(readers.length); for (int i = 0; i < readers.length; i++) { IndexReader reader = readers[i]; TermEnum termEnum; if (t != null) { termEnum = reader.terms(t); } else termEnum = reader.terms(); SegmentMergeInfo smi = new SegmentMergeInfo(starts[i], termEnum, reader); if (t == null ? smi.next() : termEnum.term() != null) queue.put(smi); // initialize queue else smi.close(); } if (t != null && queue.size() > 0) { next(); } } public boolean next() throws IOException { SegmentMergeInfo top = (SegmentMergeInfo)queue.top(); if (top == null) { term = null; return false; } term = top.term; docFreq = 0; while (top != null && term.compareTo(top.term) == 0) { queue.pop(); docFreq += top.termEnum.docFreq(); // increment freq if (top.next()) queue.put(top); // restore queue else top.close(); // done with a segment top = (SegmentMergeInfo)queue.top(); } return true; } public Term term() { return term; } public int docFreq() { return docFreq; } public void close() throws IOException { queue.close(); } } static class MultiTermDocs implements TermDocs { protected IndexReader[] readers; protected int[] starts; protected Term term; protected int base = 0; protected int pointer = 0; private TermDocs[] readerTermDocs; protected TermDocs current; // == readerTermDocs[pointer] public MultiTermDocs(IndexReader[] r, int[] s) { readers = r; starts = s; readerTermDocs = new TermDocs[r.length]; } public int doc() { return base + current.doc(); } public int freq() { return current.freq(); } public void seek(Term term) { this.term = term; this.base = 0; this.pointer = 0; this.current = null; } public void seek(TermEnum termEnum) throws IOException { seek(termEnum.term()); } public boolean next() throws IOException { for(;;) { if (current!=null && current.next()) { return true; } else if (pointer < readers.length) { base = starts[pointer]; current = termDocs(pointer++); } else { return false; } } } /** Optimized implementation. */ public int read(final int[] docs, final int[] freqs) throws IOException { while (true) { while (current == null) { if (pointer < readers.length) { // try next segment base = starts[pointer]; current = termDocs(pointer++); } else { return 0; } } int end = current.read(docs, freqs); if (end == 0) { // none left in segment current = null; } else { // got some final int b = base; // adjust doc numbers for (int i = 0; i < end; i++) docs[i] += b; return end; } } } /* A Possible future optimization could skip entire segments */ public boolean skipTo(int target) throws IOException { for(;;) { if (current != null && current.skipTo(target-base)) { return true; } else if (pointer < readers.length) { base = starts[pointer]; current = termDocs(pointer++); } else return false; } } private TermDocs termDocs(int i) throws IOException { if (term == null) return null; TermDocs result = readerTermDocs[i]; if (result == null) result = readerTermDocs[i] = termDocs(readers[i]); result.seek(term); return result; } protected TermDocs termDocs(IndexReader reader) throws IOException { return reader.termDocs(); } public void close() throws IOException { for (int i = 0; i < readerTermDocs.length; i++) { if (readerTermDocs[i] != null) readerTermDocs[i].close(); } } } static class MultiTermPositions extends MultiTermDocs implements TermPositions { public MultiTermPositions(IndexReader[] r, int[] s) { super(r,s); } protected TermDocs termDocs(IndexReader reader) throws IOException { return (TermDocs)reader.termPositions(); } public int nextPosition() throws IOException { return ((TermPositions)current).nextPosition(); } public int getPayloadLength() { return ((TermPositions)current).getPayloadLength(); } public byte[] getPayload(byte[] data, int offset) throws IOException { return ((TermPositions)current).getPayload(data, offset); } // TODO: Remove warning after API has been finalized public boolean isPayloadAvailable() { return ((TermPositions) current).isPayloadAvailable(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -