继续上面的分析,主要看提交这下
OperationStatus[] codes = region.put(putsWithLocks.toArray(new Pair[]{}));
仔细看put这个方法
/**
* Perform a batch of puts.
*
* @param putsAndLocks
* the list of puts paired with their requested lock IDs.
* @return an array of OperationStatus which internally contains the
* OperationStatusCode and the exceptionMessage if any.
* @throws IOException
*/
public OperationStatus[] put(
Pair<Put, Integer>[] putsAndLocks) throws IOException {
BatchOperationInProgress<Pair<Put, Integer>> batchOp =
new BatchOperationInProgress<Pair<Put,Integer>>(putsAndLocks);
while (!batchOp.isDone()) {
checkReadOnly();
checkResources();
long newSize;
startRegionOperation();
this.writeRequestsCount.increment();
try {
long addedSize = doMiniBatchPut(batchOp);
newSize = this.addAndGetGlobalMemstoreSize(addedSize);
} finally {
closeRegionOperation();
}
if (isFlushSize(newSize)) {
requestFlush();
}
}
return batchOp.retCodeDetails;
}
循环遍历每个Pair<put,Integer>, 分别进行如下操作。
首先在put 之前先做两项检查
checkReadOnly();
checkResources();
分别检查这个Region块是否只读,并且是否可以进行put操作(memstore需不需要先flush)。
然后执行
/**
* This method needs to be called before any public call that reads or
* modifies data. It has to be called just before a try.
* #closeRegionOperation needs to be called in the try's finally block
* Acquires a read lock and checks if the region is closing or closed.
* @throws NotServingRegionException when the region is closing or closed
*/
private void startRegionOperation() throws NotServingRegionException {
if (this.closing.get()) {
throw new NotServingRegionException(regionInfo.getRegionNameAsString() +
" is closing");
}
lock.readLock().lock();
if (this.closed.get()) {
lock.readLock().unlock();
throw new NotServingRegionException(regionInfo.getRegionNameAsString() +
" is closed");
}
}
获取了读锁之后, 在 writeRequestsCount.increment(); 这里再次证明是一个put一个writeRequest ,而且不是一次RPC一个writeRequest
紧接着就调用了doMiniBatchPut(后面再介绍这个函数)
提交完毕之后,调用这个这个函数
newSize = this.addAndGetGlobalMemstoreSize(addedSize);
用来更新memstore大小
最后在finally里关闭读锁
/**
* Closes the lock. This needs to be called in the finally block corresponding
* to the try block of #startRegionOperation
*/
private void closeRegionOperation(){
lock.readLock().unlock();
}
如果memstore达到flush的条件,就进行flush
if (isFlushSize(newSize)) {
requestFlush();
}
这个方法就执行完了.......
最为重要的doMiniBatchPut ,我们下一讲再说......