private void addCuratedData(long sizeToWrite, boolean addTtlUpdates) throws StoreException {
    Set<MockId> idsInLogSegment = new HashSet<>();
    idsByLogSegment.add(idsInLogSegment);
    List<Set<MockId>> idsGroupedByIndexSegment = new ArrayList<>();
    int deletedKeyCount = 0;
    int ttlUpdatedKeyCount = 0;

    Set<MockId> idsInIndexSegment = new HashSet<>();
    // First Index Segment
    // 1 PUT
    idsInIndexSegment.addAll(put(1, PUT_RECORD_SIZE, Utils.Infinite_Time));
    assertFalse("Expected nonempty store", store.isEmpty());

    // 2 more PUT
    idsInIndexSegment.addAll(put(2, PUT_RECORD_SIZE, Utils.Infinite_Time));
    // 2 PUT EXPIRED
    idsInIndexSegment.addAll(put(2, PUT_RECORD_SIZE, 0));
    idsGroupedByIndexSegment.add(idsInIndexSegment);
    idsInLogSegment.addAll(idsInIndexSegment);

    idsInIndexSegment = new HashSet<>();
    // Second Index Segment
    // 3 PUT
    idsInIndexSegment.addAll(put(3, PUT_RECORD_SIZE, Utils.Infinite_Time));
    // 1 DELETE for a PUT in the same index segment
    delete(getIdToDelete(idsInIndexSegment, false));
    deletedKeyCount++;
    // 1 DELETE for a PUT in the first index segment
    delete(getIdToDelete(idsGroupedByIndexSegment.get(0), false));
    deletedKeyCount++;
    idsGroupedByIndexSegment.add(idsInIndexSegment);
    idsInLogSegment.addAll(idsInIndexSegment);

    // Third and Fourth Index Segment
    for (int seg = 0; seg < 2; seg++) {
      idsInIndexSegment = new HashSet<>();
      // 3 PUT
      idsInIndexSegment.addAll(put(3, PUT_RECORD_SIZE, Utils.Infinite_Time));
      // 1 PUT for an expired blob
      MockId id = put(1, PUT_RECORD_SIZE, 0).get(0);
      idsInIndexSegment.add(id);
      // 1 DELETE for the expired PUT
      delete(id);
      deletedKeyCount++;
      deletedKeys.add(id);
      expiredKeys.remove(id);
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);
    }

    idsInIndexSegment = new HashSet<>();
    // Fifth Index Segment
    // 1 PUT entry
    idsInIndexSegment.addAll(put(1, PUT_RECORD_SIZE, Utils.Infinite_Time));
    // 1 DELETE for a PUT in each of the third and fourth segments
    delete(getIdToDelete(idsGroupedByIndexSegment.get(2), false));
    deletedKeyCount++;
    delete(getIdToDelete(idsGroupedByIndexSegment.get(3), false));
    deletedKeyCount++;
    // 1 DELETE for the PUT in the same segment
    delete(getIdToDelete(idsInIndexSegment, false));
    deletedKeyCount++;

    if (addTtlUpdates) {
      // 1 PUT entry with a non zero expiry time
      idsInIndexSegment.addAll(put(1, PUT_RECORD_SIZE, expiresAtMs));
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);

      List<MockId> idsToDelete = new ArrayList<>();

      idsInIndexSegment = new HashSet<>();
      // sixth index segment
      // 3 PUT with non zero expire time
      idsInIndexSegment.addAll(put(3, PUT_RECORD_SIZE, expiresAtMs));
      // 2 TTL updates for PUTs in the same segment
      MockId idToUpdate = getIdToTtlUpdate(idsInIndexSegment);
      updateTtl(idToUpdate);
      ttlUpdatedKeyCount++;
      idsToDelete.add(idToUpdate);
      updateTtl(getIdToTtlUpdate(idsInIndexSegment));
      ttlUpdatedKeyCount++;
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);

      idsInIndexSegment = new HashSet<>();
      // seventh index segment
      // 1 TTL update for a PUT in the previous segment
      idToUpdate = getIdToTtlUpdate(idsGroupedByIndexSegment.get(5));
      updateTtl(idToUpdate);
      ttlUpdatedKeyCount++;
      idsToDelete.add(idToUpdate);
      // 4 more PUTs with non zero expire time
      idsInIndexSegment.addAll(put(4, PUT_RECORD_SIZE, expiresAtMs));
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);

      idsInIndexSegment = new HashSet<>();
      // eighth index segment
      // 1 PUT, TTL update, DELETE in the same segment
      idToUpdate = put(1, PUT_RECORD_SIZE, expiresAtMs).get(0);
      idsInIndexSegment.add(idToUpdate);
      updateTtl(idToUpdate);
      ttlUpdatedKeyCount++;
      delete(idToUpdate);
      deletedKeyCount++;
      // 1 TTL update for a PUT in the prev segment
      updateTtl(getIdToTtlUpdate(idsGroupedByIndexSegment.get(6)));
      ttlUpdatedKeyCount++;
      // 1 more PUT with non zero expire time
      idsInIndexSegment.addAll(put(1, PUT_RECORD_SIZE, expiresAtMs));
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);

      idsInIndexSegment = new HashSet<>();
      // ninth index segment
      // 1 TTL update for a PUT in prev segment
      idToUpdate = getIdToTtlUpdate(idsGroupedByIndexSegment.get(6));
      updateTtl(idToUpdate);
      ttlUpdatedKeyCount++;
      idsToDelete.add(idToUpdate);
      // 3 DELETES from idsToDelete
      assertEquals("Number of IDs to delete has changed", 3, idsToDelete.size());
      for (MockId id : idsToDelete) {
        delete(id);
        deletedKeyCount++;
      }
      // 1 more PUT with non zero expire time
      idsInIndexSegment.addAll(put(1, PUT_RECORD_SIZE, expiresAtMs));
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);

      idsInIndexSegment = new HashSet<>();
      // tenth index segment
      // 3 PUT with finite TTLs
      idsInIndexSegment.addAll(put(3, PUT_RECORD_SIZE, expiresAtMs));
      // 2 PUT with infinite TTLs
      idsInIndexSegment.addAll(put(2, PUT_RECORD_SIZE, Utils.Infinite_Time));
      idsGroupedByIndexSegment.add(idsInIndexSegment);
      idsInLogSegment.addAll(idsInIndexSegment);

      idsInIndexSegment = new HashSet<>();
      // twelfth index segment (setting up for cross log segment)
      // 3 PUTs
      idsInIndexSegment.addAll(put(3, PUT_RECORD_SIZE, expiresAtMs));
      // 1 TTL update for a key in this segment
      updateTtl(getIdToTtlUpdate(idsInIndexSegment));
      ttlUpdatedKeyCount++;
    }

    idsInLogSegment.addAll(idsInIndexSegment);

    // 1 PUT entry that spans the rest of the data in the segment
    long sizeWritten = isLogSegmented ? LogSegment.HEADER_SIZE : 0;
    sizeWritten += idsInLogSegment.size() * PUT_RECORD_SIZE + deletedKeyCount * DELETE_RECORD_SIZE
        + ttlUpdatedKeyCount * TTL_UPDATE_RECORD_SIZE;
    MockId id = put(1, sizeToWrite - sizeWritten, Utils.Infinite_Time).get(0);
    idsInIndexSegment.add(id);
    idsGroupedByIndexSegment.add(idsInIndexSegment);
    idsInLogSegment.add(id);
  }
Adds some curated data into the store in order to ensure a good mix for testing. For understanding the created
store, please read the source code which is annotated with comments.
@param sizeToWrite the size to add for.
@param addTtlUpdates if {@code true}, adds ttl update entries (temporary until all components can handle TTL
                     updates)
@throws StoreException
ambry-store/src/test/java/com/github/ambry/store/BlobStoreTest.java