/**
* Returns a free (idle) ThreadState that may be used for indexing this one
* document. This call also pauses if a flush is pending. If delTerm is
* non-null then we buffer this deleted term after the thread state has been
* acquired. 返回一个空闲的ThreadState,它用于索引的当前document。当刷新正在等待时,调用将会暂停
*/
synchronized DocumentsWriterThreadState getThreadState(Document doc,
Term delTerm) throws IOException {
// First, find a thread state. If this thread already
// has affinity to a specific ThreadState, use that one
// again.
/** 通过HashMap将DocumentsWriterThreadState绑定本地线程,用于多线程的支持 */
DocumentsWriterThreadState state = threadBindings.get(Thread
.currentThread());
if (state == null) {
// First time this thread has called us since last
// flush. Find the least loaded thread state:
/** ts.numThreads,numThreads是分享当前实例的线程数 */
DocumentsWriterThreadState minThreadState = null;
for (int i = 0; i < threadStates.length; i++) {
DocumentsWriterThreadState ts = threadStates[i];
/**
* 得到threadStates数组中一个线程数最少的DocumentsWriterThreadState
* 第一次添加docment时threadStates数组是null
**/
if (minThreadState == null
|| ts.numThreads < minThreadState.numThreads)
minThreadState = ts;
}
if (minThreadState != null
&& (minThreadState.numThreads == 0 || threadStates.length >= MAX_THREAD_STATE)) {
state = minThreadState;
state.numThreads++;
} else {
// Just create a new "private" thread state(创建一个“私有”thread
// state)
/**
* 当threadStates是null时,调用此处。
* threadStates是一个DocumentsWriterThreadState数组。
*/
DocumentsWriterThreadState[] newArray = new DocumentsWriterThreadState[1 + threadStates.length];
if (threadStates.length > 0)
System.arraycopy(threadStates, 0, newArray, 0,
threadStates.length);
state = newArray[threadStates.length] = new DocumentsWriterThreadState(
this);
threadStates = newArray;
}
threadBindings.put(Thread.currentThread(), state);
}
// Next, wait until my thread state is idle (in case
// it's shared with other threads) and for threads to
// not be paused nor a flush pending:
/** 等到state空闲 ,暂停程序 */
waitReady(state);
// Allocate segment name if this is the first doc since
// last flush:
initSegmentName(false);
state.isIdle = false;
boolean success = false;
try {
state.docState.docID = nextDocID;
assert writer.testPoint("DocumentsWriter.ThreadState.init start");
if (delTerm != null) {
addDeleteTerm(delTerm, state.docState.docID);
state.doFlushAfter = timeToFlushDeletes();
}
assert writer
.testPoint("DocumentsWriter.ThreadState.init after delTerm");
/** 反复添加document时docid的增加,所以不同的docid对应相应的document */
nextDocID++;
numDocsInRAM++;// numDocsInRAM---docs buffered in RAM
// We must at this point commit to flushing to ensure we
// always get N docs when we flush by doc count, even if
// > 1 thread is adding documents:
if (!flushPending
&& maxBufferedDocs != IndexWriter.DISABLE_AUTO_FLUSH
&& numDocsInRAM >= maxBufferedDocs) {
flushPending = true;
state.doFlushAfter = true;
}
success = true;
} finally {
if (!success) {
// Forcefully idle this ThreadState:
state.isIdle = true;
notifyAll();
if (state.doFlushAfter) {
state.doFlushAfter = false;
flushPending = false;
}
}
}
return state;
}