@@ -208,7 +208,7 @@ public MemStoreSnapshot snapshot() {
208208 stopCompaction ();
209209 // region level lock ensures pushing active to pipeline is done in isolation
210210 // no concurrent update operations trying to flush the active segment
211- pushActiveToPipeline (getActive ());
211+ pushActiveToPipeline (getActive (), true );
212212 resetTimeOfOldestEdit ();
213213 snapshotId = EnvironmentEdgeManager .currentTime ();
214214 // in both cases whatever is pushed to snapshot is cleared from the pipeline
@@ -413,33 +413,61 @@ protected List<KeyValueScanner> createList(int capacity) {
413413 }
414414
415415 /**
416- * Check whether anything need to be done based on the current active set size.
417- * The method is invoked upon every addition to the active set.
418- * For CompactingMemStore, flush the active set to the read-only memory if it's
419- * size is above threshold
416+ * Check whether anything need to be done based on the current active set size. The method is
417+ * invoked upon every addition to the active set. For CompactingMemStore, flush the active set to
418+ * the read-only memory if it's size is above threshold
420419 * @param currActive intended segment to update
421420 * @param cellToAdd cell to be added to the segment
422421 * @param memstoreSizing object to accumulate changed size
423- * @return true if the cell can be added to the
422+ * @return true if the cell can be added to the currActive
424423 */
425- private boolean checkAndAddToActiveSize (MutableSegment currActive , Cell cellToAdd ,
424+ protected boolean checkAndAddToActiveSize (MutableSegment currActive , Cell cellToAdd ,
426425 MemStoreSizing memstoreSizing ) {
427- if (shouldFlushInMemory (currActive , cellToAdd , memstoreSizing )) {
428- if (currActive .setInMemoryFlushed ()) {
429- flushInMemory (currActive );
430- if (setInMemoryCompactionFlag ()) {
431- // The thread is dispatched to do in-memory compaction in the background
432- InMemoryCompactionRunnable runnable = new InMemoryCompactionRunnable ();
433- if (LOG .isTraceEnabled ()) {
434- LOG .trace ("Dispatching the MemStore in-memory flush for store " + store
435- .getColumnFamilyName ());
436- }
437- getPool ().execute (runnable );
426+ long cellSize = MutableSegment .getCellLength (cellToAdd );
427+ boolean successAdd = false ;
428+ while (true ) {
429+ long segmentDataSize = currActive .getDataSize ();
430+ if (!inWalReplay && segmentDataSize > inmemoryFlushSize ) {
431+ // when replaying edits from WAL there is no need in in-memory flush regardless the size
432+ // otherwise size below flush threshold try to update atomically
433+ break ;
434+ }
435+ if (currActive .compareAndSetDataSize (segmentDataSize , segmentDataSize + cellSize )) {
436+ if (memstoreSizing != null ) {
437+ memstoreSizing .incMemStoreSize (cellSize , 0 , 0 , 0 );
438438 }
439+ successAdd = true ;
440+ break ;
441+ }
442+ }
443+
444+ if (!inWalReplay && currActive .getDataSize () > inmemoryFlushSize ) {
445+ // size above flush threshold so we flush in memory
446+ this .tryFlushInMemoryAndCompactingAsync (currActive );
447+ }
448+ return successAdd ;
449+ }
450+
451+ /**
452+ * Try to flush the currActive in memory and submit the background
453+ * {@link InMemoryCompactionRunnable} to
454+ * {@link RegionServicesForStores#getInMemoryCompactionPool()}. Just one thread can do the actual
455+ * flushing in memory.
456+ * @param currActive current Active Segment to be flush in memory.
457+ */
458+ private void tryFlushInMemoryAndCompactingAsync (MutableSegment currActive ) {
459+ if (currActive .setInMemoryFlushed ()) {
460+ flushInMemory (currActive );
461+ if (setInMemoryCompactionFlag ()) {
462+ // The thread is dispatched to do in-memory compaction in the background
463+ InMemoryCompactionRunnable runnable = new InMemoryCompactionRunnable ();
464+ if (LOG .isTraceEnabled ()) {
465+ LOG .trace (
466+ "Dispatching the MemStore in-memory flush for store " + store .getColumnFamilyName ());
467+ }
468+ getPool ().execute (runnable );
439469 }
440- return false ;
441470 }
442- return true ;
443471 }
444472
445473 // externally visible only for tests
@@ -497,26 +525,6 @@ private ThreadPoolExecutor getPool() {
497525 return getRegionServices ().getInMemoryCompactionPool ();
498526 }
499527
500- protected boolean shouldFlushInMemory (MutableSegment currActive , Cell cellToAdd ,
501- MemStoreSizing memstoreSizing ) {
502- long cellSize = MutableSegment .getCellLength (cellToAdd );
503- long segmentDataSize = currActive .getDataSize ();
504- while (segmentDataSize + cellSize < inmemoryFlushSize || inWalReplay ) {
505- // when replaying edits from WAL there is no need in in-memory flush regardless the size
506- // otherwise size below flush threshold try to update atomically
507- if (currActive .compareAndSetDataSize (segmentDataSize , segmentDataSize + cellSize )) {
508- if (memstoreSizing != null ) {
509- memstoreSizing .incMemStoreSize (cellSize , 0 , 0 , 0 );
510- }
511- // enough space for cell - no need to flush
512- return false ;
513- }
514- segmentDataSize = currActive .getDataSize ();
515- }
516- // size above flush threshold
517- return true ;
518- }
519-
520528 /**
521529 * The request to cancel the compaction asynchronous task (caused by in-memory flush)
522530 * The compaction may still happen if the request was sent too late
@@ -528,10 +536,6 @@ private void stopCompaction() {
528536 }
529537 }
530538
531- protected void pushActiveToPipeline (MutableSegment currActive ) {
532- pushActiveToPipeline (currActive , true );
533- }
534-
535539 /**
536540 * NOTE: When {@link CompactingMemStore#flushInMemory(MutableSegment)} calls this method, due to
537541 * concurrent writes and because we first add cell size to currActive.getDataSize and then
0 commit comments