@Test
  public void getAbsoluteEndPositionOfLastPutTest() throws Exception {
    File testDir = StoreTestUtils.createTempDirectory("indexDirTest-" + TestUtils.getRandomString(10));
    CuratedLogIndexState indexState =
        new CuratedLogIndexState(isLogSegmented, testDir, false, false, true, true, false, false);
    assertEquals("There should be no PUT record since index is empty", -1,
        indexState.index.getAbsoluteEndPositionOfLastPut());
    long expiresAtMs = indexState.time.milliseconds() + TimeUnit.HOURS.toMillis(1);
    // DEFAULT_MAX_IN_MEM_ELEMENTS = 5, here we put 5 entries into the log
    List<IndexEntry> indexEntries = indexState.addPutEntries(5, PUT_RECORD_SIZE, expiresAtMs);
    assertEquals("Number of index segments should be 1", 1, indexState.index.getIndexSegments().size());
    // update ttl for above 5 entries and the ttl entries fall in second index segment.
    for (IndexEntry entry : indexEntries) {
      indexState.makePermanent((MockId) entry.getKey(), false);
    }
    assertEquals("Number of index segments (after ttl update) should be 2", 2,
        indexState.index.getIndexSegments().size());
    // default journal size should be 2 * DEFAULT_MAX_IN_MEM_ELEMENTS = 10
    assertEquals("Journal size not expected", 2 * DEFAULT_MAX_IN_MEM_ELEMENTS,
        indexState.index.journal.getAllEntries().size());
    // delete above 5 entries, these delete entries should fall in third index segment
    for (IndexEntry entry : indexEntries) {
      indexState.addDeleteEntry((MockId) entry.getKey());
    }
    assertEquals("Number of index segments (after deletion) should be 3", 3,
        indexState.index.getIndexSegments().size());
    // although there are now 15 entries in total, journal size is still 10 (old entries are removed from journal)
    assertEquals("Journal size (after deletion) shouldn't change", 2 * DEFAULT_MAX_IN_MEM_ELEMENTS,
        indexState.index.journal.getAllEntries().size());
    // after deletion, the last PUT record falls in first segment (out of journal)
    // for segmented log, there is a header size = 18
    assertEquals("Absolute end position of last PUT record not expected",
        5 * PUT_RECORD_SIZE + (isLogSegmented ? 18 : 0), indexState.index.getAbsoluteEndPositionOfLastPut());
    // close the index to seal all index segments
    indexState.index.close(false);
    // get end position of last PUT again, it should return same result (this is to test getting last PUT in sealed index segment)
    assertEquals("Absolute end position of last PUT record not expected",
        5 * PUT_RECORD_SIZE + (isLogSegmented ? 18 : 0), indexState.index.getAbsoluteEndPositionOfLastPut());

    // calculate current end position in log segment (note that there are 5 PUT, 5 TTL update and 5 DELETE entries)
    long currentEndPosition =
        5 * PUT_RECORD_SIZE + 5 * TTL_UPDATE_RECORD_SIZE + 5 * DELETE_RECORD_SIZE + (isLogSegmented ? 18 : 0);
    // add one more PUT entry and delete it afterwards
    indexEntries = indexState.addPutEntries(1, PUT_RECORD_SIZE, Utils.Infinite_Time);
    indexState.addDeleteEntry((MockId) indexEntries.get(0).getKey());
    assertEquals("Number of index segments after new PUT and delete should be 4", 4,
        indexState.index.getIndexSegments().size());
    // now, the latest PUT entry should be in the journal
    assertEquals("Absolute end position of last PUT record not expected", currentEndPosition + PUT_RECORD_SIZE,
        indexState.index.getAbsoluteEndPositionOfLastPut());
    indexState.destroy();
  }
Test getting absolute end position of last PUT under different circumstances (i.e. last PUT is out of Journal)
@throws Exception
ambry-store/src/test/java/com/github/ambry/store/IndexTest.java