| Method from org.apache.lucene.index.SegmentReader Detail: |
public final synchronized Object clone() {
try {
return clone(readOnly); // Preserve current readOnly
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
|
public final synchronized IndexReader clone(boolean openReadOnly) throws CorruptIndexException, IOException {
return reopenSegment(si, true, openReadOnly);
}
|
protected BitVector cloneDeletedDocs(BitVector bv) {
return (BitVector)bv.clone();
}
Clones the deleteDocs BitVector. May be overridden by subclasses. New and experimental. |
protected byte[] cloneNormBytes(byte[] bytes) {
byte[] cloneBytes = new byte[bytes.length];
System.arraycopy(bytes, 0, cloneBytes, 0, bytes.length);
return cloneBytes;
}
Clones the norm bytes. May be overridden by subclasses. New and experimental. |
public Directory directory() {
// Don't ensureOpen here -- in certain cases, when a
// cloned/reopened reader needs to commit, it may call
// this method on the closed original reader
return core.dir;
}
Returns the directory this index resides in. |
protected void doClose() throws IOException {
termVectorsLocal.close();
fieldsReaderLocal.close();
if (deletedDocs != null) {
deletedDocsRef.decRef();
// null so if an app hangs on to us we still free most ram
deletedDocs = null;
}
for (final Norm norm : norms.values()) {
norm.decRef();
}
if (core != null) {
core.decRef();
}
}
|
protected void doCommit(Map<String, String> commitUserData) throws IOException {
if (hasChanges) {
if (deletedDocsDirty) { // re-write deleted
si.advanceDelGen();
// We can write directly to the actual name (vs to a
// .tmp & renaming it) because the file is not live
// until segments file is written:
deletedDocs.write(directory(), si.getDelFileName());
si.setDelCount(si.getDelCount()+pendingDeleteCount);
pendingDeleteCount = 0;
assert deletedDocs.count() == si.getDelCount(): "delete count mismatch during commit: info=" + si.getDelCount() + " vs BitVector=" + deletedDocs.count();
} else {
assert pendingDeleteCount == 0;
}
if (normsDirty) { // re-write norms
si.setNumFields(core.fieldInfos.size());
for (final Norm norm : norms.values()) {
if (norm.dirty) {
norm.reWrite(si);
}
}
}
deletedDocsDirty = false;
normsDirty = false;
hasChanges = false;
}
}
|
protected void doDelete(int docNum) {
if (deletedDocs == null) {
deletedDocs = new BitVector(maxDoc());
deletedDocsRef = new Ref();
}
// there is more than 1 SegmentReader with a reference to this
// deletedDocs BitVector so decRef the current deletedDocsRef,
// clone the BitVector, create a new deletedDocsRef
if (deletedDocsRef.refCount() > 1) {
Ref oldRef = deletedDocsRef;
deletedDocs = cloneDeletedDocs(deletedDocs);
deletedDocsRef = new Ref();
oldRef.decRef();
}
deletedDocsDirty = true;
if (!deletedDocs.getAndSet(docNum))
pendingDeleteCount++;
}
|
protected void doSetNorm(int doc,
String field,
byte value) throws IOException {
Norm norm = norms.get(field);
if (norm == null) // not an indexed field
return;
normsDirty = true;
norm.copyOnWrite()[doc] = value; // set the value
}
|
protected void doUndeleteAll() {
deletedDocsDirty = false;
if (deletedDocs != null) {
assert deletedDocsRef != null;
deletedDocsRef.decRef();
deletedDocs = null;
deletedDocsRef = null;
pendingDeleteCount = 0;
si.clearDelGen();
si.setDelCount(0);
} else {
assert deletedDocsRef == null;
assert pendingDeleteCount == 0;
}
}
|
public int docFreq(Term t) throws IOException {
ensureOpen();
TermInfo ti = core.getTermsReader().get(t);
if (ti != null)
return ti.docFreq;
else
return 0;
}
|
public Document document(int n,
FieldSelector fieldSelector) throws CorruptIndexException, IOException {
ensureOpen();
return getFieldsReader().doc(n, fieldSelector);
}
|
FieldInfos fieldInfos() {
return core.fieldInfos;
}
|
List<String> files() throws IOException {
return new ArrayList< String >(si.files());
}
|
public static SegmentReader get(boolean readOnly,
SegmentInfo si,
int termInfosIndexDivisor) throws CorruptIndexException, IOException {
return get(readOnly, si.dir, si, BufferedIndexInput.BUFFER_SIZE, true, termInfosIndexDivisor);
}
|
public static SegmentReader get(boolean readOnly,
Directory dir,
SegmentInfo si,
int readBufferSize,
boolean doOpenStores,
int termInfosIndexDivisor) throws CorruptIndexException, IOException {
SegmentReader instance = readOnly ? new ReadOnlySegmentReader() : new SegmentReader();
instance.readOnly = readOnly;
instance.si = si;
instance.readBufferSize = readBufferSize;
boolean success = false;
try {
instance.core = new CoreReaders(dir, si, readBufferSize, termInfosIndexDivisor);
if (doOpenStores) {
instance.core.openDocStores(si);
}
instance.loadDeletedDocs();
instance.openNorms(instance.core.cfsDir, readBufferSize);
success = true;
} finally {
// With lock-less commits, it's entirely possible (and
// fine) to hit a FileNotFound exception above. In
// this case, we want to explicitly close any subset
// of things that were opened so that we don't have to
// wait for a GC to do so.
if (!success) {
instance.doClose();
}
}
return instance;
}
|
public final Object getFieldCacheKey() {
return core.freqStream;
}
|
public Collection<String> getFieldNames(FieldOption fieldOption) {
ensureOpen();
Set< String > fieldSet = new HashSet< String >();
for (int i = 0; i < core.fieldInfos.size(); i++) {
FieldInfo fi = core.fieldInfos.fieldInfo(i);
if (fieldOption == IndexReader.FieldOption.ALL) {
fieldSet.add(fi.name);
}
else if (!fi.isIndexed && fieldOption == IndexReader.FieldOption.UNINDEXED) {
fieldSet.add(fi.name);
}
else if (fi.omitTermFreqAndPositions && fieldOption == IndexReader.FieldOption.OMIT_TERM_FREQ_AND_POSITIONS) {
fieldSet.add(fi.name);
}
else if (fi.storePayloads && fieldOption == IndexReader.FieldOption.STORES_PAYLOADS) {
fieldSet.add(fi.name);
}
else if (fi.isIndexed && fieldOption == IndexReader.FieldOption.INDEXED) {
fieldSet.add(fi.name);
}
else if (fi.isIndexed && fi.storeTermVector == false && fieldOption == IndexReader.FieldOption.INDEXED_NO_TERMVECTOR) {
fieldSet.add(fi.name);
}
else if (fi.storeTermVector == true &&
fi.storePositionWithTermVector == false &&
fi.storeOffsetWithTermVector == false &&
fieldOption == IndexReader.FieldOption.TERMVECTOR) {
fieldSet.add(fi.name);
}
else if (fi.isIndexed && fi.storeTermVector && fieldOption == IndexReader.FieldOption.INDEXED_WITH_TERMVECTOR) {
fieldSet.add(fi.name);
}
else if (fi.storePositionWithTermVector && fi.storeOffsetWithTermVector == false && fieldOption == IndexReader.FieldOption.TERMVECTOR_WITH_POSITION) {
fieldSet.add(fi.name);
}
else if (fi.storeOffsetWithTermVector && fi.storePositionWithTermVector == false && fieldOption == IndexReader.FieldOption.TERMVECTOR_WITH_OFFSET) {
fieldSet.add(fi.name);
}
else if ((fi.storeOffsetWithTermVector && fi.storePositionWithTermVector) &&
fieldOption == IndexReader.FieldOption.TERMVECTOR_WITH_POSITION_OFFSET) {
fieldSet.add(fi.name);
}
}
return fieldSet;
}
|
FieldsReader getFieldsReader() {
return fieldsReaderLocal.get();
}
|
protected synchronized byte[] getNorms(String field) throws IOException {
Norm norm = norms.get(field);
if (norm == null) return null; // not indexed, or norms not stored
return norm.bytes();
}
|
static SegmentReader getOnlySegmentReader(Directory dir) throws IOException {
return getOnlySegmentReader(IndexReader.open(dir,false));
} Deprecated! Remove - this when tests are fixed!
Lotsa tests did hacks like:
SegmentReader reader = (SegmentReader) IndexReader.open(dir);
They broke. This method serves as a hack to keep hacks working
We do it with R/W access for the tests (BW compatibility) |
static SegmentReader getOnlySegmentReader(IndexReader reader) {
if (reader instanceof SegmentReader)
return (SegmentReader) reader;
if (reader instanceof DirectoryReader) {
IndexReader[] subReaders = reader.getSequentialSubReaders();
if (subReaders.length != 1)
throw new IllegalArgumentException(reader + " has " + subReaders.length + " segments instead of exactly one");
return (SegmentReader) subReaders[0];
}
throw new IllegalArgumentException(reader + " is not a SegmentReader or a single-segment DirectoryReader");
}
|
SegmentInfo getSegmentInfo() {
return si;
}
Return the SegmentInfo of the segment this reader is reading. |
public String getSegmentName() {
return core.segment;
}
Return the name of the segment this reader is reading. |
public TermFreqVector getTermFreqVector(int docNumber,
String field) throws IOException {
// Check if this field is invalid or has no stored term vector
ensureOpen();
FieldInfo fi = core.fieldInfos.fieldInfo(field);
if (fi == null || !fi.storeTermVector)
return null;
TermVectorsReader termVectorsReader = getTermVectorsReader();
if (termVectorsReader == null)
return null;
return termVectorsReader.get(docNumber, field);
}
Return a term frequency vector for the specified document and field. The
vector returned contains term numbers and frequencies for all terms in
the specified field of this document, if the field had storeTermVector
flag set. If the flag was not set, the method returns null. |
public void getTermFreqVector(int docNumber,
TermVectorMapper mapper) throws IOException {
ensureOpen();
TermVectorsReader termVectorsReader = getTermVectorsReader();
if (termVectorsReader == null)
return;
termVectorsReader.get(docNumber, mapper);
}
|
public void getTermFreqVector(int docNumber,
String field,
TermVectorMapper mapper) throws IOException {
ensureOpen();
FieldInfo fi = core.fieldInfos.fieldInfo(field);
if (fi == null || !fi.storeTermVector)
return;
TermVectorsReader termVectorsReader = getTermVectorsReader();
if (termVectorsReader == null) {
return;
}
termVectorsReader.get(docNumber, field, mapper);
}
|
public TermFreqVector[] getTermFreqVectors(int docNumber) throws IOException {
ensureOpen();
TermVectorsReader termVectorsReader = getTermVectorsReader();
if (termVectorsReader == null)
return null;
return termVectorsReader.get(docNumber);
}
Return an array of term frequency vectors for the specified document.
The array contains a vector for each vectorized field in the document.
Each vector vector contains term numbers and frequencies for all terms
in a given vectorized field.
If no such fields existed, the method returns null. |
public int getTermInfosIndexDivisor() {
return core.termsIndexDivisor;
}
|
TermVectorsReader getTermVectorsReader() {
TermVectorsReader tvReader = termVectorsLocal.get();
if (tvReader == null) {
TermVectorsReader orig = core.getTermVectorsReaderOrig();
if (orig == null) {
return null;
} else {
try {
tvReader = (TermVectorsReader) orig.clone();
} catch (CloneNotSupportedException cnse) {
return null;
}
}
termVectorsLocal.set(tvReader);
}
return tvReader;
}
Create a clone from the initial TermVectorsReader and store it in the ThreadLocal. |
TermVectorsReader getTermVectorsReaderOrig() {
return core.getTermVectorsReaderOrig();
}
|
public long getUniqueTermCount() {
return core.getTermsReader().size();
}
|
public boolean hasDeletions() {
// Don't call ensureOpen() here (it could affect performance)
return deletedDocs != null;
}
|
static boolean hasDeletions(SegmentInfo si) throws IOException {
// Don't call ensureOpen() here (it could affect performance)
return si.hasDeletions();
}
|
public synchronized boolean hasNorms(String field) {
ensureOpen();
return norms.containsKey(field);
}
|
static boolean hasSeparateNorms(SegmentInfo si) throws IOException {
return si.hasSeparateNorms();
}
|
public synchronized boolean isDeleted(int n) {
return (deletedDocs != null && deletedDocs.get(n));
}
|
void loadTermsIndex(int termsIndexDivisor) throws IOException {
core.loadTermsIndex(si, termsIndexDivisor);
}
|
public int maxDoc() {
// Don't call ensureOpen() here (it could affect performance)
return si.docCount;
}
|
public synchronized byte[] norms(String field) throws IOException {
ensureOpen();
byte[] bytes = getNorms(field);
return bytes;
}
|
public synchronized void norms(String field,
byte[] bytes,
int offset) throws IOException {
ensureOpen();
Norm norm = norms.get(field);
if (norm == null) {
Arrays.fill(bytes, offset, bytes.length, DefaultSimilarity.encodeNorm(1.0f));
return;
}
norm.bytes(bytes, offset, maxDoc());
}
Read norms into a pre-allocated array. |
boolean normsClosed() {
if (singleNormStream != null) {
return false;
}
for (final Norm norm : norms.values()) {
if (norm.refCount > 0) {
return false;
}
}
return true;
}
|
boolean normsClosed(String field) {
return norms.get(field).refCount == 0;
}
|
public int numDocs() {
// Don't call ensureOpen() here (it could affect performance)
int n = maxDoc();
if (deletedDocs != null)
n -= deletedDocs.count();
return n;
}
|
void openDocStores() throws IOException {
core.openDocStores(si);
}
|
synchronized SegmentReader reopenSegment(SegmentInfo si,
boolean doClone,
boolean openReadOnly) throws CorruptIndexException, IOException {
boolean deletionsUpToDate = (this.si.hasDeletions() == si.hasDeletions())
&& (!si.hasDeletions() || this.si.getDelFileName().equals(si.getDelFileName()));
boolean normsUpToDate = true;
boolean[] fieldNormsChanged = new boolean[core.fieldInfos.size()];
final int fieldCount = core.fieldInfos.size();
for (int i = 0; i < fieldCount; i++) {
if (!this.si.getNormFileName(i).equals(si.getNormFileName(i))) {
normsUpToDate = false;
fieldNormsChanged[i] = true;
}
}
// if we're cloning we need to run through the reopenSegment logic
// also if both old and new readers aren't readonly, we clone to avoid sharing modifications
if (normsUpToDate && deletionsUpToDate && !doClone && openReadOnly && readOnly) {
return this;
}
// When cloning, the incoming SegmentInfos should not
// have any changes in it:
assert !doClone || (normsUpToDate && deletionsUpToDate);
// clone reader
SegmentReader clone = openReadOnly ? new ReadOnlySegmentReader() : new SegmentReader();
boolean success = false;
try {
core.incRef();
clone.core = core;
clone.readOnly = openReadOnly;
clone.si = si;
clone.readBufferSize = readBufferSize;
if (!openReadOnly && hasChanges) {
// My pending changes transfer to the new reader
clone.pendingDeleteCount = pendingDeleteCount;
clone.deletedDocsDirty = deletedDocsDirty;
clone.normsDirty = normsDirty;
clone.hasChanges = hasChanges;
hasChanges = false;
}
if (doClone) {
if (deletedDocs != null) {
deletedDocsRef.incRef();
clone.deletedDocs = deletedDocs;
clone.deletedDocsRef = deletedDocsRef;
}
} else {
if (!deletionsUpToDate) {
// load deleted docs
assert clone.deletedDocs == null;
clone.loadDeletedDocs();
} else if (deletedDocs != null) {
deletedDocsRef.incRef();
clone.deletedDocs = deletedDocs;
clone.deletedDocsRef = deletedDocsRef;
}
}
clone.norms = new HashMap< String,Norm >();
// Clone norms
for (int i = 0; i < fieldNormsChanged.length; i++) {
// Clone unchanged norms to the cloned reader
if (doClone || !fieldNormsChanged[i]) {
final String curField = core.fieldInfos.fieldInfo(i).name;
Norm norm = this.norms.get(curField);
if (norm != null)
clone.norms.put(curField, (Norm) norm.clone());
}
}
// If we are not cloning, then this will open anew
// any norms that have changed:
clone.openNorms(si.getUseCompoundFile() ? core.getCFSReader() : directory(), readBufferSize);
success = true;
} finally {
if (!success) {
// An exception occurred during reopen, we have to decRef the norms
// that we incRef'ed already and close singleNormsStream and FieldsReader
clone.decRef();
}
}
return clone;
}
|
void rollbackCommit() {
hasChanges = rollbackHasChanges;
deletedDocsDirty = rollbackDeletedDocsDirty;
normsDirty = rollbackNormsDirty;
pendingDeleteCount = rollbackPendingDeleteCount;
for (Norm norm : norms.values()) {
norm.dirty = norm.rollbackDirty;
}
}
|
void setSegmentInfo(SegmentInfo info) {
si = info;
}
|
void startCommit() {
rollbackHasChanges = hasChanges;
rollbackDeletedDocsDirty = deletedDocsDirty;
rollbackNormsDirty = normsDirty;
rollbackPendingDeleteCount = pendingDeleteCount;
for (Norm norm : norms.values()) {
norm.rollbackDirty = norm.dirty;
}
}
|
public TermDocs termDocs() throws IOException {
ensureOpen();
return new SegmentTermDocs(this);
}
|
public TermDocs termDocs(Term term) throws IOException {
if (term == null) {
return new AllTermDocs(this);
} else {
return super.termDocs(term);
}
}
|
public TermPositions termPositions() throws IOException {
ensureOpen();
return new SegmentTermPositions(this);
}
|
public TermEnum terms() {
ensureOpen();
return core.getTermsReader().terms();
}
|
public TermEnum terms(Term t) throws IOException {
ensureOpen();
return core.getTermsReader().terms(t);
}
|
boolean termsIndexLoaded() {
return core.termsIndexIsLoaded();
}
|
static boolean usesCompoundFile(SegmentInfo si) throws IOException {
return si.getUseCompoundFile();
}
|