Method from org.apache.lucene.index.IndexWriter Detail: |
synchronized void acquireRead() {
final Thread current = Thread.currentThread();
while(writeThread != null && writeThread != current)
doWait();
readCount++;
}
|
synchronized void acquireWrite() {
assert writeThread != Thread.currentThread();
while(writeThread != null || readCount > 0)
doWait();
// We could have been closed while we were waiting:
ensureOpen();
writeThread = Thread.currentThread();
}
|
public void addDocument(Document doc) throws CorruptIndexException, IOException {
addDocument(doc, analyzer);
}
Adds a document to this index. If the document contains more than
#setMaxFieldLength(int) terms for a given field, the remainder are
discarded.
Note that if an Exception is hit (for example disk full)
then the index will be consistent, but this document
may not have been added. Furthermore, it's possible
the index will have one segment in non-compound format
even when using compound files (when a merge has
partially succeeded).
This method periodically flushes pending documents
to the Directory (see above), and
also periodically triggers segment merges in the index
according to the MergePolicy in use.
Merges temporarily consume space in the
directory. The amount of space required is up to 1X the
size of all segments being merged, when no
readers/searchers are open against the index, and up to
2X the size of all segments being merged when
readers/searchers are open against the index (see
#optimize() for details). The sequence of
primitive merge operations performed is governed by the
merge policy.
Note that each term in the document can be no longer
than 16383 characters, otherwise an
IllegalArgumentException will be thrown.
Note that it's possible to create an invalid Unicode
string in java if a UTF16 surrogate pair is malformed.
In this case, the invalid characters are silently
replaced with the Unicode replacement character
U+FFFD.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void addDocument(Document doc,
Analyzer analyzer) throws CorruptIndexException, IOException {
ensureOpen();
boolean doFlush = false;
boolean success = false;
try {
try {
doFlush = docWriter.addDocument(doc, analyzer);
success = true;
} finally {
if (!success) {
if (infoStream != null)
message("hit exception adding document");
synchronized (this) {
// If docWriter has some aborted files that were
// never incref'd, then we clean them up here
if (docWriter != null) {
final Collection< String > files = docWriter.abortedFiles();
if (files != null)
deleter.deleteNewFiles(files);
}
}
}
}
if (doFlush)
flush(true, false, false);
} catch (OutOfMemoryError oom) {
handleOOM(oom, "addDocument");
}
}
Adds a document to this index, using the provided analyzer instead of the
value of #getAnalyzer() . If the document contains more than
#setMaxFieldLength(int) terms for a given field, the remainder are
discarded.
See #addDocument(Document) for details on
index and IndexWriter state after an Exception, and
flushing/merging temporary free space requirements.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void addIndexes(IndexReader readers) throws CorruptIndexException, IOException {
ensureOpen();
// Do not allow add docs or deletes while we are running:
docWriter.pauseAllThreads();
// We must pre-acquire a read lock here (and upgrade to
// write lock in startTransaction below) so that no
// other addIndexes is allowed to start up after we have
// flushed & optimized but before we then start our
// transaction. This is because the merging below
// requires that only one segment is present in the
// index:
acquireRead();
try {
SegmentInfo info = null;
String mergedName = null;
SegmentMerger merger = null;
boolean success = false;
try {
flush(true, false, true);
optimize(); // start with zero or 1 seg
success = true;
} finally {
// Take care to release the read lock if we hit an
// exception before starting the transaction
if (!success)
releaseRead();
}
// true means we already have a read lock; if this
// call hits an exception it will release the write
// lock:
startTransaction(true);
try {
mergedName = newSegmentName();
merger = new SegmentMerger(this, mergedName, null);
SegmentReader sReader = null;
synchronized(this) {
if (segmentInfos.size() == 1) { // add existing index, if any
sReader = readerPool.get(segmentInfos.info(0), true, BufferedIndexInput.BUFFER_SIZE, -1);
}
}
success = false;
try {
if (sReader != null)
merger.add(sReader);
for (int i = 0; i < readers.length; i++) // add new indexes
merger.add(readers[i]);
int docCount = merger.merge(); // merge 'em
synchronized(this) {
segmentInfos.clear(); // pop old infos & add new
info = new SegmentInfo(mergedName, docCount, directory, false, true,
-1, null, false, merger.hasProx());
setDiagnostics(info, "addIndexes(IndexReader...)");
segmentInfos.add(info);
}
// Notify DocumentsWriter that the flushed count just increased
docWriter.updateFlushedDocCount(docCount);
success = true;
} finally {
if (sReader != null) {
readerPool.release(sReader);
}
}
} finally {
if (!success) {
if (infoStream != null)
message("hit exception in addIndexes during merge");
rollbackTransaction();
} else {
commitTransaction();
}
}
if (mergePolicy instanceof LogMergePolicy && getUseCompoundFile()) {
List< String > files = null;
synchronized(this) {
// Must incRef our files so that if another thread
// is running merge/optimize, it doesn't delete our
// segment's files before we have a change to
// finish making the compound file.
if (segmentInfos.contains(info)) {
files = info.files();
deleter.incRef(files);
}
}
if (files != null) {
success = false;
startTransaction(false);
try {
merger.createCompoundFile(mergedName + ".cfs");
synchronized(this) {
info.setUseCompoundFile(true);
}
success = true;
} finally {
deleter.decRef(files);
if (!success) {
if (infoStream != null)
message("hit exception building compound file in addIndexes during merge");
rollbackTransaction();
} else {
commitTransaction();
}
}
}
}
} catch (OutOfMemoryError oom) {
handleOOM(oom, "addIndexes(IndexReader...)");
} finally {
if (docWriter != null) {
docWriter.resumeAllThreads();
}
}
}
Merges the provided indexes into this index.
After this completes, the index is optimized.
The provided IndexReaders are not closed.
NOTE: while this is running, any attempts to
add or delete documents (with another thread) will be
paused until this method completes.
See #addIndexesNoOptimize for
details on transactional semantics, temporary free
space required in the Directory, and non-CFS segments
on an Exception.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void addIndexesNoOptimize(Directory dirs) throws CorruptIndexException, IOException {
ensureOpen();
noDupDirs(dirs);
// Do not allow add docs or deletes while we are running:
docWriter.pauseAllThreads();
try {
if (infoStream != null)
message("flush at addIndexesNoOptimize");
flush(true, false, true);
boolean success = false;
startTransaction(false);
try {
int docCount = 0;
synchronized(this) {
ensureOpen();
for (int i = 0; i < dirs.length; i++) {
if (directory == dirs[i]) {
// cannot add this index: segments may be deleted in merge before added
throw new IllegalArgumentException("Cannot add this index to itself");
}
SegmentInfos sis = new SegmentInfos(); // read infos from dir
sis.read(dirs[i]);
for (int j = 0; j < sis.size(); j++) {
SegmentInfo info = sis.info(j);
assert !segmentInfos.contains(info): "dup info dir=" + info.dir + " name=" + info.name;
docCount += info.docCount;
segmentInfos.add(info); // add each info
}
}
}
// Notify DocumentsWriter that the flushed count just increased
docWriter.updateFlushedDocCount(docCount);
maybeMerge();
ensureOpen();
// If after merging there remain segments in the index
// that are in a different directory, just copy these
// over into our index. This is necessary (before
// finishing the transaction) to avoid leaving the
// index in an unusable (inconsistent) state.
resolveExternalSegments();
ensureOpen();
success = true;
} finally {
if (success) {
commitTransaction();
} else {
rollbackTransaction();
}
}
} catch (OutOfMemoryError oom) {
handleOOM(oom, "addIndexesNoOptimize");
} finally {
if (docWriter != null) {
docWriter.resumeAllThreads();
}
}
}
Merges all segments from an array of indexes into this
index.
This may be used to parallelize batch indexing. A large document
collection can be broken into sub-collections. Each sub-collection can be
indexed in parallel, on a different thread, process or machine. The
complete index can then be created by merging sub-collection indexes
with this method.
NOTE: the index in each Directory must not be
changed (opened by a writer) while this method is
running. This method does not acquire a write lock in
each input Directory, so it is up to the caller to
enforce this.
NOTE: while this is running, any attempts to
add or delete documents (with another thread) will be
paused until this method completes.
This method is transactional in how Exceptions are
handled: it does not commit a new segments_N file until
all indexes are added. This means if an Exception
occurs (for example disk full), then either no indexes
will have been added or they all will have been.
Note that this requires temporary free space in the
Directory up to 2X the sum of all input indexes
(including the starting index). If readers/searchers
are open against the starting index, then temporary
free space required will be higher by the size of the
starting index (see #optimize() for details).
Once this completes, the final size of the index
will be less than the sum of all input index sizes
(including the starting index). It could be quite a
bit smaller (if there were many pending deletes) or
just slightly smaller.
This requires this index not be among those to be added.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
synchronized void addMergeException(OneMerge merge) {
assert merge.getException() != null;
if (!mergeExceptions.contains(merge) && mergeGen == merge.mergeGen)
mergeExceptions.add(merge);
}
|
public void close() throws CorruptIndexException, IOException {
close(true);
}
Commits all changes to an index and closes all
associated files. Note that this may be a costly
operation, so, try to re-use a single writer instead of
closing and opening a new one. See #commit() for
caveats about write caching done by some IO devices.
If an Exception is hit during close, eg due to disk
full or some other reason, then both the on-disk index
and the internal state of the IndexWriter instance will
be consistent. However, the close will not be complete
even though part of it (flushing buffered documents)
may have succeeded, so the write lock will still be
held.
If you can correct the underlying cause (eg free up
some disk space) then you can call close() again.
Failing that, if you want to force the write lock to be
released (dangerous, because you may then lose buffered
docs in the IndexWriter instance) then you can do
something like this:
try {
writer.close();
} finally {
if (IndexWriter.isLocked(directory)) {
IndexWriter.unlock(directory);
}
}
after which, you must be certain not to use the writer
instance anymore.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer, again. See above for details. |
public void close(boolean waitForMerges) throws CorruptIndexException, IOException {
// Ensure that only one thread actually gets to do the closing:
if (shouldClose()) {
// If any methods have hit OutOfMemoryError, then abort
// on close, in case the internal state of IndexWriter
// or DocumentsWriter is corrupt
if (hitOOM)
rollbackInternal();
else
closeInternal(waitForMerges);
}
}
Closes the index with or without waiting for currently
running merges to finish. This is only meaningful when
using a MergeScheduler that runs merges in background
threads.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer, again. See above for details.
NOTE: it is dangerous to always call
close(false), especially when IndexWriter is not open
for very long, because this can result in "merge
starvation" whereby long merges will never have a
chance to finish. This will cause too many segments in
your index over time. |
public final void commit() throws CorruptIndexException, IOException {
commit(null);
}
Commits all pending changes (added & deleted
documents, optimizations, segment merges, added
indexes, etc.) to the index, and syncs all referenced
index files, such that a reader will see the changes
and the index updates will survive an OS or machine
crash or power loss. Note that this does not wait for
any running background merges to finish. This may be a
costly operation, so you should test the cost in your
application and do it only when really necessary.
Note that this operation calls Directory.sync on
the index files. That call should not return until the
file contents & metadata are on stable storage. For
FSDirectory, this calls the OS's fsync. But, beware:
some hardware devices may in fact cache writes even
during fsync, and return before the bits are actually
on stable storage, to give the appearance of faster
performance. If you have such a device, and it does
not have a battery backup (for example) then on power
loss it may still lose data. Lucene cannot guarantee
consistency on such devices.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details.
|
public final void commit(Map<String, String> commitUserData) throws CorruptIndexException, IOException {
ensureOpen();
if (infoStream != null) {
message("commit: start");
}
synchronized(commitLock) {
if (infoStream != null) {
message("commit: enter lock");
}
if (pendingCommit == null) {
if (infoStream != null) {
message("commit: now prepare");
}
prepareCommit(commitUserData);
} else if (infoStream != null) {
message("commit: already prepared");
}
finishCommit();
}
}
Commits all changes to the index, specifying a
commitUserData Map (String -> String). This just
calls #prepareCommit(Map) (if you didn't
already call it) and then #finishCommit .
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public synchronized void deleteAll() throws IOException {
docWriter.pauseAllThreads();
try {
// Abort any running merges
finishMerges(false);
// Remove any buffered docs
docWriter.abort();
docWriter.setFlushedDocCount(0);
// Remove all segments
segmentInfos.clear();
// Ask deleter to locate unreferenced files & remove them:
deleter.checkpoint(segmentInfos, false);
deleter.refresh();
// Don't bother saving any changes in our segmentInfos
readerPool.clear(null);
// Mark that the index has changed
++changeCount;
} catch (OutOfMemoryError oom) {
handleOOM(oom, "deleteAll");
} finally {
docWriter.resumeAllThreads();
if (infoStream != null) {
message("hit exception during deleteAll");
}
}
}
Delete all documents in the index.
This method will drop all buffered documents and will
remove all segments from the index. This change will not be
visible until a #commit() has been called. This method
can be rolled back using #rollback() .
NOTE: this method is much faster than using deleteDocuments( new MatchAllDocsQuery() ).
NOTE: this method will forcefully abort all merges
in progress. If other threads are running #optimize() or any of the addIndexes methods, they
will receive MergePolicy.MergeAbortedException s. |
public void deleteDocuments(Term term) throws CorruptIndexException, IOException {
ensureOpen();
try {
boolean doFlush = docWriter.bufferDeleteTerm(term);
if (doFlush)
flush(true, false, false);
} catch (OutOfMemoryError oom) {
handleOOM(oom, "deleteDocuments(Term)");
}
}
Deletes the document(s) containing term .
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void deleteDocuments(Term terms) throws CorruptIndexException, IOException {
ensureOpen();
try {
boolean doFlush = docWriter.bufferDeleteTerms(terms);
if (doFlush)
flush(true, false, false);
} catch (OutOfMemoryError oom) {
handleOOM(oom, "deleteDocuments(Term..)");
}
}
Deletes the document(s) containing any of the
terms. All deletes are flushed at the same time.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void deleteDocuments(Query query) throws CorruptIndexException, IOException {
ensureOpen();
boolean doFlush = docWriter.bufferDeleteQuery(query);
if (doFlush)
flush(true, false, false);
}
Deletes the document(s) matching the provided query.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void deleteDocuments(Query queries) throws CorruptIndexException, IOException {
ensureOpen();
boolean doFlush = docWriter.bufferDeleteQueries(queries);
if (doFlush)
flush(true, false, false);
}
Deletes the document(s) matching any of the provided queries.
All deletes are flushed at the same time.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
void doAfterFlush() throws IOException {
}
|
protected final synchronized void ensureOpen() throws AlreadyClosedException {
ensureOpen(true);
}
|
protected final synchronized void ensureOpen(boolean includePendingClose) throws AlreadyClosedException {
if (!isOpen(includePendingClose)) {
throw new AlreadyClosedException("this IndexWriter is closed");
}
}
|
public void expungeDeletes() throws CorruptIndexException, IOException {
expungeDeletes(true);
}
Expunges all deletes from the index. When an index
has many document deletions (or updates to existing
documents), it's best to either call optimize or
expungeDeletes to remove all unused data in the index
associated with the deleted documents. To see how
many deletions you have pending in your index, call
IndexReader#numDeletedDocs
This saves disk space and memory usage while
searching. expungeDeletes should be somewhat faster
than optimize since it does not insist on reducing the
index to a single segment (though, this depends on the
MergePolicy ; see MergePolicy#findMergesToExpungeDeletes .). Note that
this call does not first commit any buffered
documents, so you must do so yourself if necessary.
See also #expungeDeletes(boolean)
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void expungeDeletes(boolean doWait) throws CorruptIndexException, IOException {
ensureOpen();
if (infoStream != null)
message("expungeDeletes: index now " + segString());
MergePolicy.MergeSpecification spec;
synchronized(this) {
spec = mergePolicy.findMergesToExpungeDeletes(segmentInfos);
if (spec != null) {
final int numMerges = spec.merges.size();
for(int i=0;i< numMerges;i++)
registerMerge(spec.merges.get(i));
}
}
mergeScheduler.merge(this);
if (spec != null && doWait) {
final int numMerges = spec.merges.size();
synchronized(this) {
boolean running = true;
while(running) {
if (hitOOM) {
throw new IllegalStateException("this writer hit an OutOfMemoryError; cannot complete expungeDeletes");
}
// Check each merge that MergePolicy asked us to
// do, to see if any of them are still running and
// if any of them have hit an exception.
running = false;
for(int i=0;i< numMerges;i++) {
final MergePolicy.OneMerge merge = spec.merges.get(i);
if (pendingMerges.contains(merge) || runningMerges.contains(merge))
running = true;
Throwable t = merge.getException();
if (t != null) {
IOException ioe = new IOException("background merge hit exception: " + merge.segString(directory));
ioe.initCause(t);
throw ioe;
}
}
// If any of our merges are still running, wait:
if (running)
doWait();
}
}
}
// NOTE: in the ConcurrentMergeScheduler case, when
// doWait is false, we can return immediately while
// background threads accomplish the optimization
}
Just like #expungeDeletes() , except you can
specify whether the call should block until the
operation completes. This is only meaningful with a
MergeScheduler that is able to run merges in
background threads.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
protected final void flush(boolean triggerMerge,
boolean flushDocStores,
boolean flushDeletes) throws CorruptIndexException, IOException {
// We can be called during close, when closing==true, so we must pass false to ensureOpen:
ensureOpen(false);
if (doFlush(flushDocStores, flushDeletes) && triggerMerge)
maybeMerge();
}
Flush all in-memory buffered udpates (adds and deletes)
to the Directory. |
public Analyzer getAnalyzer() {
ensureOpen();
return analyzer;
}
Returns the analyzer used by this index. |
final synchronized int getBufferedDeleteTermsSize() {
return docWriter.getBufferedDeleteTerms().size();
}
|
public static PrintStream getDefaultInfoStream() {
return IndexWriter.defaultInfoStream;
}
Returns the current default infoStream for newly
instantiated IndexWriters. |
public static long getDefaultWriteLockTimeout() {
return IndexWriter.WRITE_LOCK_TIMEOUT;
}
Returns default write lock timeout for newly
instantiated IndexWriters. |
public Directory getDirectory() {
// Pass false because the flush during closing calls getDirectory
ensureOpen(false);
return directory;
}
Returns the Directory used by this index. |
final synchronized int getDocCount(int i) {
if (i >= 0 && i < segmentInfos.size()) {
return segmentInfos.info(i).docCount;
} else {
return -1;
}
}
|
final synchronized int getFlushCount() {
return flushCount;
}
|
final synchronized int getFlushDeletesCount() {
return flushDeletesCount;
}
|
public PrintStream getInfoStream() {
ensureOpen();
return infoStream;
}
Returns the current infoStream in use by this writer. |
public int getMaxBufferedDeleteTerms() {
ensureOpen();
return docWriter.getMaxBufferedDeleteTerms();
}
Returns the number of buffered deleted terms that will
trigger a flush if enabled. |
public int getMaxBufferedDocs() {
ensureOpen();
return docWriter.getMaxBufferedDocs();
}
Returns the number of buffered added documents that will
trigger a flush if enabled. |
public int getMaxFieldLength() {
ensureOpen();
return maxFieldLength;
}
Returns the maximum number of terms that will be
indexed for a single field in a document. |
public int getMaxMergeDocs() {
return getLogMergePolicy().getMaxMergeDocs();
}
Returns the largest segment (measured by document
count) that may be merged with other segments.
Note that this method is a convenience method: it
just calls mergePolicy.getMaxMergeDocs as long as
mergePolicy is an instance of LogMergePolicy .
Otherwise an IllegalArgumentException is thrown.
|
public int getMergeFactor() {
return getLogMergePolicy().getMergeFactor();
}
Returns the number of segments that are merged at
once and also controls the total number of segments
allowed to accumulate in the index.
Note that this method is a convenience method: it
just calls mergePolicy.getMergeFactor as long as
mergePolicy is an instance of LogMergePolicy .
Otherwise an IllegalArgumentException is thrown.
|
public MergePolicy getMergePolicy() {
ensureOpen();
return mergePolicy;
}
Expert: returns the current MergePolicy in use by this writer. |
public MergeScheduler getMergeScheduler() {
ensureOpen();
return mergeScheduler;
}
Expert: returns the current MergePolicy in use by this
writer. |
public IndexReaderWarmer getMergedSegmentWarmer() {
return mergedSegmentWarmer;
}
|
synchronized OneMerge getNextMerge() {
if (pendingMerges.size() == 0)
return null;
else {
// Advance the merge from pending to running
MergePolicy.OneMerge merge = pendingMerges.removeFirst();
runningMerges.add(merge);
return merge;
}
}
Expert: the MergeScheduler calls this method
to retrieve the next merge requested by the
MergePolicy |
final synchronized int getNumBufferedDeleteTerms() {
return docWriter.getNumBufferedDeleteTerms();
}
|
final synchronized int getNumBufferedDocuments() {
return docWriter.getNumDocsInRAM();
}
|
public double getRAMBufferSizeMB() {
return docWriter.getRAMBufferSizeMB();
}
|
public IndexReader getReader() throws IOException {
return getReader(IndexReader.DEFAULT_TERMS_INDEX_DIVISOR);
}
Expert: returns a readonly reader, covering all
committed as well as un-committed changes to the index.
This provides "near real-time" searching, in that
changes made during an IndexWriter session can be
quickly made available for searching without closing
the writer nor calling #commit .
Note that this is functionally equivalent to calling
{#commit} and then using IndexReader#open to
open a new reader. But the turarnound time of this
method should be faster since it avoids the potentially
costly #commit .
You must close the IndexReader returned by
this method once you are done using it.
It's near real-time because there is no hard
guarantee on how quickly you can get a new reader after
making changes with IndexWriter. You'll have to
experiment in your situation to determine if it's
fast enough. As this is a new and experimental
feature, please report back on your findings so we can
learn, improve and iterate.
The resulting reader supports IndexReader#reopen , but that call will simply forward
back to this method (though this may change in the
future).
The very first time this method is called, this
writer instance will make every effort to pool the
readers that it opens for doing merges, applying
deletes, etc. This means additional resources (RAM,
file descriptors, CPU time) will be consumed.
For lower latency on reopening a reader, you should
call #setMergedSegmentWarmer to
pre-warm a newly merged segment before it's committed
to the index. This is important for minimizing
index-to-search delay after a large merge.
If an addIndexes* call is running in another thread,
then this reader will only search those segments from
the foreign index that have been successfully copied
over, so far .
NOTE: Once the writer is closed, any
outstanding readers may continue to be used. However,
if you attempt to reopen any of those readers, you'll
hit an AlreadyClosedException .
NOTE: This API is experimental and might
change in incompatible ways in the next release. |
public IndexReader getReader(int termInfosIndexDivisor) throws IOException {
if (infoStream != null) {
message("flush at getReader");
}
// Do this up front before flushing so that the readers
// obtained during this flush are pooled, the first time
// this method is called:
poolReaders = true;
flush(true, true, false);
// Prevent segmentInfos from changing while opening the
// reader; in theory we could do similar retry logic,
// just like we do when loading segments_N
synchronized(this) {
applyDeletes();
return new ReadOnlyDirectoryReader(this, segmentInfos, termInfosIndexDivisor);
}
}
Expert: like #getReader , except you can
specify which termInfosIndexDivisor should be used for
any newly opened readers. |
final synchronized int getSegmentCount() {
return segmentInfos.size();
}
|
public Similarity getSimilarity() {
ensureOpen();
return this.similarity;
}
|
public int getTermIndexInterval() {
// We pass false because this method is called by SegmentMerger while we are in the process of closing
ensureOpen(false);
return termIndexInterval;
}
Expert: Return the interval between indexed terms. |
public boolean getUseCompoundFile() {
return getLogMergePolicy().getUseCompoundFile();
}
Get the current setting of whether newly flushed
segments will use the compound file format. Note that
this just returns the value previously set with
setUseCompoundFile(boolean), or the default value
(true). You cannot use this to query the status of
previously flushed segments.
Note that this method is a convenience method: it
just calls mergePolicy.getUseCompoundFile as long as
mergePolicy is an instance of LogMergePolicy .
Otherwise an IllegalArgumentException is thrown.
|
public long getWriteLockTimeout() {
ensureOpen();
return writeLockTimeout;
}
Returns allowed timeout when acquiring the write lock. |
public synchronized boolean hasDeletions() throws IOException {
ensureOpen();
if (docWriter.hasDeletes())
return true;
for (int i = 0; i < segmentInfos.size(); i++)
if (segmentInfos.info(i).hasDeletions())
return true;
return false;
}
|
synchronized boolean isClosed() {
return closed;
}
|
public static boolean isLocked(Directory directory) throws IOException {
return directory.makeLock(WRITE_LOCK_NAME).isLocked();
}
Returns true iff the index in the named directory is
currently locked. |
final synchronized boolean isOpen(boolean includePendingClose) {
return !(closed || (includePendingClose && closing));
}
|
public synchronized int maxDoc() {
int count;
if (docWriter != null)
count = docWriter.getNumDocsInRAM();
else
count = 0;
for (int i = 0; i < segmentInfos.size(); i++)
count += segmentInfos.info(i).docCount;
return count;
}
Returns total number of docs in this index, including
docs not yet flushed (still in the RAM buffer),
not counting deletions. |
public final void maybeMerge() throws CorruptIndexException, IOException {
maybeMerge(false);
}
Expert: asks the mergePolicy whether any merges are
necessary now and if so, runs the requested merges and
then iterate (test again if merges are needed) until no
more merges are returned by the mergePolicy.
Explicit calls to maybeMerge() are usually not
necessary. The most common case is when merge policy
parameters have changed.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
final void merge(OneMerge merge) throws CorruptIndexException, IOException {
boolean success = false;
try {
try {
try {
mergeInit(merge);
if (infoStream != null)
message("now merge\n merge=" + merge.segString(directory) + "\n merge=" + merge + "\n index=" + segString());
mergeMiddle(merge);
mergeSuccess(merge);
success = true;
} catch (Throwable t) {
handleMergeException(t, merge);
}
} finally {
synchronized(this) {
mergeFinish(merge);
if (!success) {
if (infoStream != null)
message("hit exception during merge");
if (merge.info != null && !segmentInfos.contains(merge.info))
deleter.refresh(merge.info.name);
}
// This merge (and, generally, any change to the
// segments) may now enable new merges, so we call
// merge policy & update pending merges.
if (success && !merge.isAborted() && !closed && !closing)
updatePendingMerges(merge.maxNumSegmentsOptimize, merge.optimize);
}
}
} catch (OutOfMemoryError oom) {
handleOOM(oom, "merge");
}
}
Merges the indicated segments, replacing them in the stack with a
single segment. |
final synchronized void mergeFinish(OneMerge merge) throws IOException {
// Optimize, addIndexes or finishMerges may be waiting
// on merges to finish.
notifyAll();
if (merge.increfDone)
decrefMergeSegments(merge);
// It's possible we are called twice, eg if there was an
// exception inside mergeInit
if (merge.registerDone) {
final SegmentInfos sourceSegments = merge.segments;
final int end = sourceSegments.size();
for(int i=0;i< end;i++)
mergingSegments.remove(sourceSegments.info(i));
mergingSegments.remove(merge.info);
merge.registerDone = false;
}
runningMerges.remove(merge);
}
Does fininishing for a merge, which is fast but holds
the synchronized lock on IndexWriter instance. |
final synchronized void mergeInit(OneMerge merge) throws IOException {
boolean success = false;
try {
_mergeInit(merge);
success = true;
} finally {
if (!success) {
mergeFinish(merge);
}
}
}
Does initial setup for a merge, which is fast but holds
the synchronized lock on IndexWriter instance. |
void mergeSuccess(OneMerge merge) {
}
Hook that's called when the specified merge is complete. |
public void message(String message) {
if (infoStream != null)
infoStream.println("IW " + messageID + " [" + Thread.currentThread().getName() + "]: " + message);
}
Prints a message to the infoStream (if non-null),
prefixed with the identifying information for this
writer and the thread that's calling it. |
final String newSegmentName() {
// Cannot synchronize on IndexWriter because that causes
// deadlock
synchronized(segmentInfos) {
// Important to increment changeCount so that the
// segmentInfos is written on close. Otherwise we
// could close, re-open and re-return the same segment
// name that was previously returned which can cause
// problems at least with ConcurrentMergeScheduler.
changeCount++;
return "_" + Integer.toString(segmentInfos.counter++, Character.MAX_RADIX);
}
}
|
SegmentInfo newestSegment() {
return segmentInfos.info(segmentInfos.size()-1);
}
|
synchronized boolean nrtIsCurrent(SegmentInfos infos) {
if (!infos.equals(segmentInfos)) {
// if any structural changes (new segments), we are
// stale
return false;
} else {
return !docWriter.anyChanges();
}
}
|
public int numDeletedDocs(SegmentInfo info) throws IOException {
SegmentReader reader = readerPool.getIfExists(info);
try {
if (reader != null) {
return reader.numDeletedDocs();
} else {
return info.getDelCount();
}
} finally {
if (reader != null) {
readerPool.release(reader);
}
}
}
Obtain the number of deleted docs for a pooled reader.
If the reader isn't being pooled, the segmentInfo's
delCount is returned. |
public synchronized int numDocs() throws IOException {
int count;
if (docWriter != null)
count = docWriter.getNumDocsInRAM();
else
count = 0;
for (int i = 0; i < segmentInfos.size(); i++) {
final SegmentInfo info = segmentInfos.info(i);
count += info.docCount - info.getDelCount();
}
return count;
}
Returns total number of docs in this index, including
docs not yet flushed (still in the RAM buffer), and
including deletions. NOTE: buffered deletions
are not counted. If you really need these to be
counted you should call #commit() first. |
public final synchronized int numRamDocs() {
ensureOpen();
return docWriter.getNumDocsInRAM();
}
Expert: Return the number of documents currently
buffered in RAM. |
public void optimize() throws CorruptIndexException, IOException {
optimize(true);
}
Requests an "optimize" operation on an index, priming the index
for the fastest available search. Traditionally this has meant
merging all segments into a single segment as is done in the
default merge policy, but individual merge policies may implement
optimize in different ways.
It is recommended that this method be called upon completion of indexing. In
environments with frequent updates, optimize is best done during low volume times, if at all.
See http://www.gossamer-threads.com/lists/lucene/java-dev/47895 for more discussion.
Note that optimize requires 2X the index size free
space in your Directory. For example, if your index
size is 10 MB then you need 20 MB free for optimize to
complete.
If some but not all readers re-open while an
optimize is underway, this will cause > 2X temporary
space to be consumed as those new readers will then
hold open the partially optimized segments at that
time. It is best not to re-open readers while optimize
is running.
The actual temporary usage could be much less than
these figures (it depends on many factors).
In general, once the optimize completes, the total size of the
index will be less than the size of the starting index.
It could be quite a bit smaller (if there were many
pending deletes) or just slightly smaller.
If an Exception is hit during optimize(), for example
due to disk full, the index will not be corrupt and no
documents will have been lost. However, it may have
been partially optimized (some segments were merged but
not all), and it's possible that one of the segments in
the index will be in non-compound format even when
using compound file format. This will occur when the
Exception is hit during conversion of the segment into
compound format.
This call will optimize those segments present in
the index when the call started. If other threads are
still adding documents and flushing segments, those
newly created segments will not be optimized unless you
call optimize again.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void optimize(int maxNumSegments) throws CorruptIndexException, IOException {
optimize(maxNumSegments, true);
}
Optimize the index down to <= maxNumSegments. If
maxNumSegments==1 then this is the same as #optimize() .
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void optimize(boolean doWait) throws CorruptIndexException, IOException {
optimize(1, doWait);
}
Just like #optimize() , except you can specify
whether the call should block until the optimize
completes. This is only meaningful with a
MergeScheduler that is able to run merges in
background threads.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void optimize(int maxNumSegments,
boolean doWait) throws CorruptIndexException, IOException {
ensureOpen();
if (maxNumSegments < 1)
throw new IllegalArgumentException("maxNumSegments must be >= 1; got " + maxNumSegments);
if (infoStream != null)
message("optimize: index now " + segString());
flush(true, false, true);
synchronized(this) {
resetMergeExceptions();
segmentsToOptimize = new HashSet< SegmentInfo >();
final int numSegments = segmentInfos.size();
for(int i=0;i< numSegments;i++)
segmentsToOptimize.add(segmentInfos.info(i));
// Now mark all pending & running merges as optimize
// merge:
for(final MergePolicy.OneMerge merge : pendingMerges) {
merge.optimize = true;
merge.maxNumSegmentsOptimize = maxNumSegments;
}
for ( final MergePolicy.OneMerge merge: runningMerges ) {
merge.optimize = true;
merge.maxNumSegmentsOptimize = maxNumSegments;
}
}
maybeMerge(maxNumSegments, true);
if (doWait) {
synchronized(this) {
while(true) {
if (hitOOM) {
throw new IllegalStateException("this writer hit an OutOfMemoryError; cannot complete optimize");
}
if (mergeExceptions.size() > 0) {
// Forward any exceptions in background merge
// threads to the current thread:
final int size = mergeExceptions.size();
for(int i=0;i< size;i++) {
final MergePolicy.OneMerge merge = mergeExceptions.get(i);
if (merge.optimize) {
IOException err = new IOException("background merge hit exception: " + merge.segString(directory));
final Throwable t = merge.getException();
if (t != null)
err.initCause(t);
throw err;
}
}
}
if (optimizeMergesPending())
doWait();
else
break;
}
}
// If close is called while we are still
// running, throw an exception so the calling
// thread will know the optimize did not
// complete
ensureOpen();
}
// NOTE: in the ConcurrentMergeScheduler case, when
// doWait is false, we can return immediately while
// background threads accomplish the optimization
}
Just like #optimize(int) , except you can
specify whether the call should block until the
optimize completes. This is only meaningful with a
MergeScheduler that is able to run merges in
background threads.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public final void prepareCommit() throws CorruptIndexException, IOException {
ensureOpen();
prepareCommit(null);
}
Expert: prepare for commit.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public final void prepareCommit(Map<String, String> commitUserData) throws CorruptIndexException, IOException {
if (hitOOM) {
throw new IllegalStateException("this writer hit an OutOfMemoryError; cannot commit");
}
if (pendingCommit != null)
throw new IllegalStateException("prepareCommit was already called with no corresponding call to commit");
if (infoStream != null)
message("prepareCommit: flush");
flush(true, true, true);
startCommit(0, commitUserData);
}
Expert: prepare for commit, specifying
commitUserData Map (String -> String). This does the
first phase of 2-phase commit. This method does all
steps necessary to commit changes since this writer
was opened: flushes pending added and deleted docs,
syncs the index files, writes most of next segments_N
file. After calling this you must call either #commit() to finish the commit, or #rollback() to revert the commit and undo all changes
done since the writer was opened.
You can also just call #commit(Map) directly
without prepareCommit first in which case that method
will internally call prepareCommit.
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details.
|
public final long ramSizeInBytes() {
ensureOpen();
return docWriter.getRAMUsed();
}
Expert: Return the total size of all index files currently cached in memory.
Useful for size management with flushRamDocs() |
final synchronized boolean registerMerge(OneMerge merge) throws MergeAbortedException {
if (merge.registerDone)
return true;
if (stopMerges) {
merge.abort();
throw new MergePolicy.MergeAbortedException("merge is aborted: " + merge.segString(directory));
}
final int count = merge.segments.size();
boolean isExternal = false;
for(int i=0;i< count;i++) {
final SegmentInfo info = merge.segments.info(i);
if (mergingSegments.contains(info))
return false;
if (segmentInfos.indexOf(info) == -1)
return false;
if (info.dir != directory)
isExternal = true;
}
ensureContiguousMerge(merge);
pendingMerges.add(merge);
if (infoStream != null)
message("add merge to pendingMerges: " + merge.segString(directory) + " [total " + pendingMerges.size() + " pending]");
merge.mergeGen = mergeGen;
merge.isExternal = isExternal;
// OK it does not conflict; now record that this merge
// is running (while synchronized) to avoid race
// condition where two conflicting merges from different
// threads, start
for(int i=0;i< count;i++)
mergingSegments.add(merge.segments.info(i));
// Merge is now registered
merge.registerDone = true;
return true;
}
Checks whether this merge involves any segments
already participating in a merge. If not, this merge
is "registered", meaning we record that its segments
are now participating in a merge, and true is
returned. Else (the merge conflicts) false is
returned. |
synchronized void releaseRead() {
readCount--;
assert readCount >= 0;
notifyAll();
}
|
synchronized void releaseWrite() {
assert Thread.currentThread() == writeThread;
writeThread = null;
notifyAll();
}
|
public void rollback() throws IOException {
ensureOpen();
// Ensure that only one thread actually gets to do the closing:
if (shouldClose())
rollbackInternal();
}
Close the IndexWriter without committing
any changes that have occurred since the last commit
(or since it was opened, if commit hasn't been called).
This removes any temporary files that had been created,
after which the state of the index will be the same as
it was when commit() was last called or when this
writer was first opened. This also clears a previous
call to #prepareCommit . |
public synchronized String segString() {
return segString(segmentInfos);
}
|
public static void setDefaultInfoStream(PrintStream infoStream) {
IndexWriter.defaultInfoStream = infoStream;
}
If non-null, this will be the default infoStream used
by a newly instantiated IndexWriter. |
public static void setDefaultWriteLockTimeout(long writeLockTimeout) {
IndexWriter.WRITE_LOCK_TIMEOUT = writeLockTimeout;
}
Sets the default (for any instance of IndexWriter) maximum time to wait for a write lock (in
milliseconds). |
public void setInfoStream(PrintStream infoStream) {
ensureOpen();
setMessageID(infoStream);
docWriter.setInfoStream(infoStream);
deleter.setInfoStream(infoStream);
if (infoStream != null)
messageState();
}
If non-null, information about merges, deletes and a
message when maxFieldLength is reached will be printed
to this. |
public void setMaxBufferedDeleteTerms(int maxBufferedDeleteTerms) {
ensureOpen();
if (maxBufferedDeleteTerms != DISABLE_AUTO_FLUSH
&& maxBufferedDeleteTerms < 1)
throw new IllegalArgumentException(
"maxBufferedDeleteTerms must at least be 1 when enabled");
docWriter.setMaxBufferedDeleteTerms(maxBufferedDeleteTerms);
if (infoStream != null)
message("setMaxBufferedDeleteTerms " + maxBufferedDeleteTerms);
}
Determines the minimal number of delete terms required before the buffered
in-memory delete terms are applied and flushed. If there are documents
buffered in memory at the time, they are merged and a new segment is
created.
Disabled by default (writer flushes by RAM usage).
|
public void setMaxBufferedDocs(int maxBufferedDocs) {
ensureOpen();
if (maxBufferedDocs != DISABLE_AUTO_FLUSH && maxBufferedDocs < 2)
throw new IllegalArgumentException(
"maxBufferedDocs must at least be 2 when enabled");
if (maxBufferedDocs == DISABLE_AUTO_FLUSH
&& getRAMBufferSizeMB() == DISABLE_AUTO_FLUSH)
throw new IllegalArgumentException(
"at least one of ramBufferSize and maxBufferedDocs must be enabled");
docWriter.setMaxBufferedDocs(maxBufferedDocs);
pushMaxBufferedDocs();
if (infoStream != null)
message("setMaxBufferedDocs " + maxBufferedDocs);
}
Determines the minimal number of documents required
before the buffered in-memory documents are flushed as
a new Segment. Large values generally gives faster
indexing.
When this is set, the writer will flush every
maxBufferedDocs added documents. Pass in #DISABLE_AUTO_FLUSH to prevent triggering a flush due
to number of buffered documents. Note that if flushing
by RAM usage is also enabled, then the flush will be
triggered by whichever comes first.
Disabled by default (writer flushes by RAM usage). |
public void setMaxFieldLength(int maxFieldLength) {
ensureOpen();
this.maxFieldLength = maxFieldLength;
docWriter.setMaxFieldLength(maxFieldLength);
if (infoStream != null)
message("setMaxFieldLength " + maxFieldLength);
}
The maximum number of terms that will be indexed for a single field in a
document. This limits the amount of memory required for indexing, so that
collections with very large files will not crash the indexing process by
running out of memory. This setting refers to the number of running terms,
not to the number of different terms.
Note: this silently truncates large documents, excluding from the
index all terms that occur further in the document. If you know your source
documents are large, be sure to set this value high enough to accomodate
the expected size. If you set it to Integer.MAX_VALUE, then the only limit
is your memory, but you should anticipate an OutOfMemoryError.
By default, no more than #DEFAULT_MAX_FIELD_LENGTH terms
will be indexed for a field. |
public void setMaxMergeDocs(int maxMergeDocs) {
getLogMergePolicy().setMaxMergeDocs(maxMergeDocs);
}
Determines the largest segment (measured by
document count) that may be merged with other segments.
Small values (e.g., less than 10,000) are best for
interactive indexing, as this limits the length of
pauses while indexing to a few seconds. Larger values
are best for batched indexing and speedier
searches.
The default value is Integer#MAX_VALUE .
Note that this method is a convenience method: it
just calls mergePolicy.setMaxMergeDocs as long as
mergePolicy is an instance of LogMergePolicy .
Otherwise an IllegalArgumentException is thrown.
The default merge policy (LogByteSizeMergePolicy ) also allows you to set this
limit by net size (in MB) of the segment, using LogByteSizeMergePolicy#setMaxMergeMB .
|
public void setMergeFactor(int mergeFactor) {
getLogMergePolicy().setMergeFactor(mergeFactor);
}
Determines how often segment indices are merged by addDocument(). With
smaller values, less RAM is used while indexing, and searches on
unoptimized indices are faster, but indexing speed is slower. With larger
values, more RAM is used during indexing, and while searches on unoptimized
indices are slower, indexing is faster. Thus larger values (> 10) are best
for batch index creation, and smaller values (< 10) for indices that are
interactively maintained.
Note that this method is a convenience method: it
just calls mergePolicy.setMergeFactor as long as
mergePolicy is an instance of LogMergePolicy .
Otherwise an IllegalArgumentException is thrown.
This must never be less than 2. The default value is 10. |
public void setMergePolicy(MergePolicy mp) {
ensureOpen();
if (mp == null)
throw new NullPointerException("MergePolicy must be non-null");
if (mergePolicy != mp)
mergePolicy.close();
mergePolicy = mp;
pushMaxBufferedDocs();
if (infoStream != null)
message("setMergePolicy " + mp);
}
Expert: set the merge policy used by this writer. |
public synchronized void setMergeScheduler(MergeScheduler mergeScheduler) throws CorruptIndexException, IOException {
ensureOpen();
if (mergeScheduler == null)
throw new NullPointerException("MergeScheduler must be non-null");
if (this.mergeScheduler != mergeScheduler) {
finishMerges(true);
this.mergeScheduler.close();
}
this.mergeScheduler = mergeScheduler;
if (infoStream != null)
message("setMergeScheduler " + mergeScheduler);
}
Expert: set the merge scheduler used by this writer. |
public void setMergedSegmentWarmer(IndexReaderWarmer warmer) {
mergedSegmentWarmer = warmer;
}
|
public void setRAMBufferSizeMB(double mb) {
if (mb > 2048.0) {
throw new IllegalArgumentException("ramBufferSize " + mb + " is too large; should be comfortably less than 2048");
}
if (mb != DISABLE_AUTO_FLUSH && mb < = 0.0)
throw new IllegalArgumentException(
"ramBufferSize should be > 0.0 MB when enabled");
if (mb == DISABLE_AUTO_FLUSH && getMaxBufferedDocs() == DISABLE_AUTO_FLUSH)
throw new IllegalArgumentException(
"at least one of ramBufferSize and maxBufferedDocs must be enabled");
docWriter.setRAMBufferSizeMB(mb);
if (infoStream != null)
message("setRAMBufferSizeMB " + mb);
}
Determines the amount of RAM that may be used for
buffering added documents and deletions before they are
flushed to the Directory. Generally for faster
indexing performance it's best to flush by RAM usage
instead of document count and use as large a RAM buffer
as you can.
When this is set, the writer will flush whenever
buffered documents and deletions use this much RAM.
Pass in #DISABLE_AUTO_FLUSH to prevent
triggering a flush due to RAM usage. Note that if
flushing by document count is also enabled, then the
flush will be triggered by whichever comes first.
NOTE: the account of RAM usage for pending
deletions is only approximate. Specifically, if you
delete by Query, Lucene currently has no way to measure
the RAM usage if individual Queries so the accounting
will under-estimate and you should compensate by either
calling commit() periodically yourself, or by using
#setMaxBufferedDeleteTerms to flush by count
instead of RAM usage (each buffered delete Query counts
as one).
NOTE: because IndexWriter uses
int s when managing its internal storage,
the absolute maximum value for this setting is somewhat
less than 2048 MB. The precise limit depends on
various factors, such as how large your documents are,
how many fields have norms, etc., so it's best to set
this value comfortably under 2048.
The default value is #DEFAULT_RAM_BUFFER_SIZE_MB . |
public void setSimilarity(Similarity similarity) {
ensureOpen();
this.similarity = similarity;
docWriter.setSimilarity(similarity);
}
Expert: Set the Similarity implementation used by this IndexWriter. |
public void setTermIndexInterval(int interval) {
ensureOpen();
this.termIndexInterval = interval;
}
Expert: Set the interval between indexed terms. Large values cause less
memory to be used by IndexReader, but slow random-access to terms. Small
values cause more memory to be used by an IndexReader, and speed
random-access to terms.
This parameter determines the amount of computation required per query
term, regardless of the number of documents that contain that term. In
particular, it is the maximum number of other terms that must be
scanned before a term is located and its frequency and position information
may be processed. In a large index with user-entered query terms, query
processing time is likely to be dominated not by term lookup but rather
by the processing of frequency and positional data. In a small index
or when many uncommon query terms are generated (e.g., by wildcard
queries) term lookup may become a dominant cost.
In particular, numUniqueTerms/interval terms are read into
memory by an IndexReader, and, on average, interval/2 terms
must be scanned for each random term access. |
public void setUseCompoundFile(boolean value) {
getLogMergePolicy().setUseCompoundFile(value);
getLogMergePolicy().setUseCompoundDocStore(value);
}
Setting to turn on usage of a compound file. When on,
multiple files for each segment are merged into a
single file when a new segment is flushed.
Note that this method is a convenience method: it
just calls mergePolicy.setUseCompoundFile as long as
mergePolicy is an instance of LogMergePolicy .
Otherwise an IllegalArgumentException is thrown.
|
public void setWriteLockTimeout(long writeLockTimeout) {
ensureOpen();
this.writeLockTimeout = writeLockTimeout;
}
Sets the maximum time to wait for a write lock (in milliseconds) for this instance of IndexWriter. @see |
boolean testPoint(String name) {
return true;
}
|
public static void unlock(Directory directory) throws IOException {
directory.makeLock(IndexWriter.WRITE_LOCK_NAME).release();
}
Forcibly unlocks the index in the named directory.
Caution: this should only be used by failure recovery code,
when it is known that no other process nor thread is in fact
currently accessing this index. |
public void updateDocument(Term term,
Document doc) throws CorruptIndexException, IOException {
ensureOpen();
updateDocument(term, doc, getAnalyzer());
}
Updates a document by first deleting the document(s)
containing term and then adding the new
document. The delete and then add are atomic as seen
by a reader on the same index (flush may happen only after
the add).
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
public void updateDocument(Term term,
Document doc,
Analyzer analyzer) throws CorruptIndexException, IOException {
ensureOpen();
try {
boolean doFlush = false;
boolean success = false;
try {
doFlush = docWriter.updateDocument(term, doc, analyzer);
success = true;
} finally {
if (!success) {
if (infoStream != null)
message("hit exception updating document");
synchronized (this) {
// If docWriter has some aborted files that were
// never incref'd, then we clean them up here
final Collection< String > files = docWriter.abortedFiles();
if (files != null)
deleter.deleteNewFiles(files);
}
}
}
if (doFlush)
flush(true, false, false);
} catch (OutOfMemoryError oom) {
handleOOM(oom, "updateDocument");
}
}
Updates a document by first deleting the document(s)
containing term and then adding the new
document. The delete and then add are atomic as seen
by a reader on the same index (flush may happen only after
the add).
NOTE: if this method hits an OutOfMemoryError
you should immediately close the writer. See above for details. |
synchronized void upgradeReadToWrite() {
assert readCount > 0;
upgradeCount++;
while(readCount > upgradeCount || writeThread != null) {
doWait();
}
writeThread = Thread.currentThread();
readCount--;
upgradeCount--;
}
|
public boolean verbose() {
return infoStream != null;
}
Returns true if verbosing is enabled (i.e., infoStream != null). |
public synchronized void waitForMerges() {
// Ensure any running addIndexes finishes.
acquireRead();
releaseRead();
while(pendingMerges.size() > 0 || runningMerges.size() > 0) {
doWait();
}
// sanity check
assert 0 == mergingSegments.size();
}
Wait for any currently outstanding merges to finish.
It is guaranteed that any merges started prior to calling this method
will have completed once this method completes. |