public void initializePool(Collection<DiskSpaceRequirements> requirementsList) throws StoreException {
    long startTime = System.currentTimeMillis();
    try {
      if (enablePooling) {
        if (poolState == PoolState.NOT_INVENTORIED) {
          throw inventoryException;
        }
        // The requirements for each store and swap segments pool
        Map<String, Map<Long, Long>> overallRequirements = getOverallRequirements(requirementsList);
        deleteExtraSegments(overallRequirements);
        addRequiredSegments(overallRequirements, true);
        // TODO fill the disk with additional swap segments
        poolState = PoolState.INITIALIZED;
      } else {
        logger.info("Disk segment pooling disabled; pool will not be initialized.");
      }
    } catch (Exception e) {
      metrics.diskSpaceAllocatorInitFailureCount.inc();
      poolState = PoolState.NOT_INVENTORIED;
      throw new StoreException("Exception while initializing DiskSpaceAllocator pool", e,
          StoreErrorCodes.InitializationError);
    } finally {
      long elapsedTime = System.currentTimeMillis() - startTime;
      logger.info("initializePool took {} ms", elapsedTime);
      metrics.diskSpaceAllocatorStartTimeMs.update(elapsedTime);
    }
  }
This method will initialize the pool such that it matches the {@link DiskSpaceRequirements} passed in.
The following steps are performed:
<ol>
  <li>
    The requirements list is aggregated into an overall requirements map. This stage will ensure that the swap
    segments requirements per each segment size described in a DiskSpaceRequirements struct (even if a blob store
    needs 0 additional non-swap segments). The number of swap segments needed is calculated by counting the total
    number of swap segments allocated to the stores (as described by the disk space requirements). If the number
    of swap segments allocated is less than the required swap segment count (passed in via configuration) for a
    certain segment size, the difference is added into the overall requirements map. This ensures that the total
    (allocated and pooled) swap segment count equals the required count.
  </li>
  <li>
    Unneeded segments are deleted. These are segments that were present in the pool on disk, but are not needed
    according to the overall requirements.
  </li>
  <li>
    Any additional required segments are added. For each segment size, additional files will be preallocated to
    until the number of files at that size match the overall requirements map. If fallocate is supported on the
    system, and the call fails, pool initialization will fail.
  </li>
</ol>
WARNING: No calls to {@link #allocate(File, long, String, boolean)} and {@link #free(File, long, String, boolean)} may occur while this method is
         being executed.
@param requirementsList a collection of {@link DiskSpaceRequirements}s objects that describe the number and
                        segment size needed by each store.
@throws StoreException if the pool could not be allocated to meet the provided requirements
ambry-store/src/main/java/com/github/ambry/store/DiskSpaceAllocator.java