@Test
  public void testSwitchingPreadtoStreamParallelyWithCompactionDischarger() throws Exception {
    Configuration conf = HBaseConfiguration.create();
    conf.set("hbase.hstore.engine.class", DummyStoreEngine.class.getName());
    conf.setLong(StoreScanner.STORESCANNER_PREAD_MAX_BYTES, 0);
    // Set the lower threshold to invoke the "MERGE" policy
    MyStore store = initMyStore(name.getMethodName(), conf, new MyStoreHook() {
    });
    MemStoreSizing memStoreSizing = new NonThreadSafeMemStoreSizing();
    long ts = EnvironmentEdgeManager.currentTime();
    long seqID = 1L;
    // Add some data to the region and do some flushes
    for (int i = 1; i < 10; i++) {
      store.add(createCell(Bytes.toBytes("row" + i), qf1, ts, seqID++, Bytes.toBytes("")),
        memStoreSizing);
    }
    // flush them
    flushStore(store, seqID);
    for (int i = 11; i < 20; i++) {
      store.add(createCell(Bytes.toBytes("row" + i), qf1, ts, seqID++, Bytes.toBytes("")),
        memStoreSizing);
    }
    // flush them
    flushStore(store, seqID);
    for (int i = 21; i < 30; i++) {
      store.add(createCell(Bytes.toBytes("row" + i), qf1, ts, seqID++, Bytes.toBytes("")),
        memStoreSizing);
    }
    // flush them
    flushStore(store, seqID);

    assertEquals(3, store.getStorefilesCount());
    Scan scan = new Scan();
    scan.addFamily(family);
    Collection<HStoreFile> storefiles2 = store.getStorefiles();
    ArrayList<HStoreFile> actualStorefiles = Lists.newArrayList(storefiles2);
    StoreScanner storeScanner =
      (StoreScanner) store.getScanner(scan, scan.getFamilyMap().get(family), Long.MAX_VALUE);
    // get the current heap
    KeyValueHeap heap = storeScanner.heap;
    // create more store files
    for (int i = 31; i < 40; i++) {
      store.add(createCell(Bytes.toBytes("row" + i), qf1, ts, seqID++, Bytes.toBytes("")),
        memStoreSizing);
    }
    // flush them
    flushStore(store, seqID);

    for (int i = 41; i < 50; i++) {
      store.add(createCell(Bytes.toBytes("row" + i), qf1, ts, seqID++, Bytes.toBytes("")),
        memStoreSizing);
    }
    // flush them
    flushStore(store, seqID);
    storefiles2 = store.getStorefiles();
    ArrayList<HStoreFile> actualStorefiles1 = Lists.newArrayList(storefiles2);
    actualStorefiles1.removeAll(actualStorefiles);
    // Do compaction
    MyThread thread = new MyThread(storeScanner);
    thread.start();
    store.replaceStoreFiles(actualStorefiles, actualStorefiles1, false);
    thread.join();
    KeyValueHeap heap2 = thread.getHeap();
    assertFalse(heap.equals(heap2));
  }
If there are two running InMemoryFlushRunnable, the later InMemoryFlushRunnable may change the
versionedList. And the first InMemoryFlushRunnable will use the chagned versionedList to remove
the corresponding segments. In short, there will be some segements which isn't in merge are
removed.
hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHStore.java