void addRequiredSegments(Map<String, Map<Long, Long>> overallRequirements, boolean isInitialize) throws IOException {
    if (enablePooling) {
      for (Map.Entry<String, Map<Long, Long>> storeOrSwapRequirement : overallRequirements.entrySet()) {
        String storeOrSwapDirName = storeOrSwapRequirement.getKey();
        Map<Long, Long> requirementBySize = storeOrSwapRequirement.getValue();

        if (storeOrSwapDirName.equals(SWAP_DIR_NAME)) {
          // add required segments for swap directory
          for (Map.Entry<Long, Long> sizeAndSegmentsNeeded : requirementBySize.entrySet()) {
            long sizeInBytes = sizeAndSegmentsNeeded.getKey();
            long segmentsNeeded = sizeAndSegmentsNeeded.getValue();
            if (isInitialize) {
              // if this method is called during server start up, there is no race condition when calling getCount() from swapReserveFiles
              // and we still need to check swapReserveFiles.getCount() because there might be some inventoried segments
              while (swapReserveFiles.getCount(sizeInBytes) < segmentsNeeded) {
                swapReserveFiles.add(sizeInBytes, createReserveFile(sizeInBytes, swapReserveDir));
              }
            } else {
              // if this method is called when adding new store, swapReserveFiles.getCount() is not reliable because other
              // threads may concurrently check in and check out swap segments
              for (int i = 0; i < segmentsNeeded; ++i) {
                try {
                  swapReserveFiles.add(sizeInBytes, createReserveFile(sizeInBytes, swapReserveDir));
                } catch (IOException e) {
                  // if fail to create file, decrease number of swap segment with this size in swapSegmentNumBySize map
                  // we don't have to subtract # of swapSegmentsUsed because this exceptions happened when adding new store
                  // and there shouldn't be any swap segment in use.
                  swapSegmentNumBySize.put(sizeInBytes, swapSegmentNumBySize.get(sizeInBytes) - (segmentsNeeded - i));
                  throw e;
                }
              }
            }
          }
        } else {
          // add required segments for each store reserve directory
          File storeReserveDir = new File(reserveDir, STORE_DIR_PREFIX + storeOrSwapDirName);
          // prepare the directory if this is new store
          prepareDirectory(storeReserveDir);
          ReserveFileMap sizeToFilesMap = storeReserveFiles.getOrDefault(storeOrSwapDirName, new ReserveFileMap());
          for (Map.Entry<Long, Long> sizeAndSegmentsNeeded : requirementBySize.entrySet()) {
            long sizeInBytes = sizeAndSegmentsNeeded.getKey();
            long segmentsNeeded = sizeAndSegmentsNeeded.getValue();
            while (sizeToFilesMap.getCount(sizeInBytes) < segmentsNeeded) {
              sizeToFilesMap.add(sizeInBytes, createReserveFile(sizeInBytes, storeReserveDir));
            }
          }
          storeReserveFiles.put(storeOrSwapDirName, sizeToFilesMap);
        }
      }
    } else {
      logger.info("Pooling is turned off. No segments will be generated.");
    }
  }
Add additional reserve files that are required by {@code overallRequirements}.
@param overallRequirements a map between segment sizes in bytes and the number of segments needed for that size.
@param isInitialize whether the addition is called during initialization.
@throws IOException
ambry-store/src/main/java/com/github/ambry/store/DiskSpaceAllocator.java