@Test
  public void populateBloomFilterWithUuidTest() throws Exception {
    assumeTrue(formatVersion > PersistentIndex.VERSION_1);
    // with default config, bloom filter will be populated by whole blob id bytes array
    LogSegmentName logSegmentName1 = LogSegmentName.fromPositionAndGeneration(0, 0);
    int indexValueSize =
        PersistentIndex.CURRENT_VERSION >= PersistentIndex.VERSION_3 ? IndexValue.INDEX_VALUE_SIZE_IN_BYTES_V3_V4
            : IndexValue.INDEX_VALUE_SIZE_IN_BYTES_V1_V2;
    IndexSegment indexSegment1 =
        new IndexSegment(tempDir.getAbsolutePath(), new Offset(logSegmentName1, 0), STORE_KEY_FACTORY,
            KEY_SIZE + indexValueSize, indexValueSize, config, metrics, time);
    Random random = new Random();
    short accountId1 = getRandomShort(random);
    short containerId1 = getRandomShort(random);
    short accountId2, containerId2;
    do {
      accountId2 = getRandomShort(random);
    } while (accountId2 == accountId1);
    do {
      containerId2 = getRandomShort(random);
    } while (containerId2 == containerId1);
    String idStr = TestUtils.getRandomString(CUSTOM_ID_SIZE);
    // generate two ids with same id string but different account/container.
    MockId id1 = new MockId(idStr, accountId1, containerId1);
    MockId id2 = new MockId(idStr, accountId2, containerId2);
    IndexValue value1 =
        IndexValueTest.getIndexValue(1000, new Offset(logSegmentName1, 0), Utils.Infinite_Time, time.milliseconds(),
            accountId1, containerId1, (short) 0, formatVersion);
    indexSegment1.addEntry(new IndexEntry(id1, value1), new Offset(logSegmentName1, 1000));
    // deliberately add one more entry for later bloom rebuilding test
    indexSegment1.addEntry(new IndexEntry(id2, value1), new Offset(logSegmentName1, 2000));
    indexSegment1.writeIndexSegmentToFile(new Offset(logSegmentName1, 2000));
    indexSegment1.seal();
    // test that id1 can be found in index segment but id2 should be non-existent because bloom filter considers it not present
    Set<IndexValue> findResult = indexSegment1.find(id1);
    assertNotNull("Should have found the added key", findResult);
    assertEquals(accountId1, findResult.iterator().next().getAccountId());
    assertNull("Should have failed to find non existent key", indexSegment1.find(id2));

    // create second index segment whose bloom filter is populated with UUID only.
    // We add id1 into indexSegment2 and attempt to get id2 which should succeed.
    Properties properties = new Properties();
    properties.setProperty("store.uuid.based.bloom.filter.enabled", Boolean.toString(true));
    StoreConfig storeConfig = new StoreConfig(new VerifiableProperties(properties));
    LogSegmentName logSegmentName2 = LogSegmentName.fromPositionAndGeneration(1, 0);
    IndexSegment indexSegment2 =
        new IndexSegment(tempDir.getAbsolutePath(), new Offset(logSegmentName2, 0), STORE_KEY_FACTORY,
            KEY_SIZE + indexValueSize, indexValueSize, storeConfig, metrics, time);
    indexSegment2.addEntry(new IndexEntry(id1, value1), new Offset(logSegmentName2, 1000));
    indexSegment2.writeIndexSegmentToFile(new Offset(logSegmentName2, 1000));
    indexSegment2.seal();
    findResult = indexSegment2.find(id1);
    assertNotNull("Should have found the id1", findResult);
    // test that we are able to get id2 from indexSegment2
    findResult = indexSegment2.find(id2);
    assertNotNull("Should have found the id2", findResult);
    // verify that the found entry actually has account/container associated with id1
    IndexValue indexValue = findResult.iterator().next();
    assertTrue("Account or container is not expected",
        indexValue.getAccountId() == accountId1 && indexValue.getContainerId() == containerId1);
    File bloomFile1 =
        new File(tempDir, generateIndexSegmentFilenamePrefix(new Offset(logSegmentName1, 0)) + BLOOM_FILE_NAME_SUFFIX);
    assertTrue("The bloom file should exist", bloomFile1.exists());
    long lengthBeforeRebuild = bloomFile1.length();

    // rebuild bloom filter in indexSegment1
    properties.setProperty("store.index.rebuild.bloom.filter.enabled", Boolean.toString(true));
    storeConfig = new StoreConfig(new VerifiableProperties(properties));
    IndexSegment indexSegmentFromFile =
        new IndexSegment(indexSegment1.getFile(), true, STORE_KEY_FACTORY, storeConfig, metrics, null, time);
    // test that id2 is found in reconstructed index segment (with bloom filter rebuilt based on UUID only)
    findResult = indexSegmentFromFile.find(id2);
    assertNotNull("Should have found the id2", findResult);
    indexValue = findResult.iterator().next();
    assertTrue("Account or container is not expected",
        indexValue.getAccountId() == accountId1 && indexValue.getContainerId() == containerId1);
    // verify that bloom file length didn't change
    assertEquals("Bloom file length has changed", lengthBeforeRebuild, bloomFile1.length());

    // now, change value of storeIndexMaxNumberOfInmemElements to 1
    properties.setProperty("store.index.max.number.of.inmem.elements", Integer.toString(1));
    storeConfig = new StoreConfig(new VerifiableProperties(properties));
    // rebuild bloomFile1 again and file size should be changed
    new IndexSegment(indexSegment1.getFile(), true, STORE_KEY_FACTORY, storeConfig, metrics, null, time);
    assertTrue("Bloom file length has changed", lengthBeforeRebuild > bloomFile1.length());

    // additional test: exception occurs when deleting previous bloom file
    assertTrue("Could not make unwritable", tempDir.setWritable(false));
    try {
      new IndexSegment(indexSegment1.getFile(), true, STORE_KEY_FACTORY, storeConfig, metrics, null, time);
      fail("Deletion on unwritable file should fail");
    } catch (StoreException e) {
      assertEquals("Error code is not expected.", StoreErrorCodes.IndexCreationFailure, e.getErrorCode());
    } finally {
      assertTrue("Could not make writable", tempDir.setWritable(true));
    }
  }
Test populating bloom filter with whole blob id and with UUID respectively.
@throws Exception
ambry-store/src/test/java/com/github/ambry/store/IndexSegmentTest.java