private double calculateCapacityUnitCost(RestRequest restRequest, RestResponseChannel restResponseChannel,
      BlobInfo blobInfo) {
    RequestPath requestPath = getRequestPath(restRequest);
    switch (restRequest.getRestMethod()) {
      case POST:
        long contentSize;
        if (requestPath.matchesOperation(Operations.STITCH)) {
          contentSize = Long.parseLong((String) restResponseChannel.getHeader(RestUtils.Headers.BLOB_SIZE));
        } else {
          contentSize = restRequest.getBytesReceived();
        }
        double cost = Math.ceil(contentSize / CU_COST_UNIT);
        return Math.max(cost, MIN_CU_COST);
      case GET:
        SubResource subResource = requestPath.getSubResource();
        if (requestPath.matchesOperation(Operations.GET_SIGNED_URL)) {
          return INDEX_ONLY_COST;
        } else if (subResource == SubResource.BlobInfo || subResource == SubResource.UserMetadata) {
          return INDEX_ONLY_COST;
        } else {
          long size;
          if (blobInfo == null) { // Maybe its a GET for a deleted blob
            return MIN_CU_COST;
          }
          if (restRequest.getArgs().containsKey(RestUtils.Headers.RANGE)) { // Range request case
            try {
              size = RestUtils.buildByteRange(restRequest.getArgs().get(RestUtils.Headers.RANGE).toString())
                  .toResolvedByteRange(blobInfo.getBlobProperties().getBlobSize(), true)
                  .getRangeSize();
            } catch (RestServiceException rsEx) {
              // this should never happen.
              logger.error("Exception while calculation CU cost for range request", rsEx);
              size = 0; // this will default to one chunk
            }
          } else { // regular GET blob
            size = blobInfo.getBlobProperties().getBlobSize();
          }
          cost = Math.ceil(size / CU_COST_UNIT);
          return Math.max(cost, MIN_CU_COST);
        }
      default:
        return INDEX_ONLY_COST; // Assuming 1 unit of capacity unit cost for all requests that don't fetch or store a blob's data.
    }
  }
Calculate the cost incurred in terms of capacity unit to serve a request.
For post and get requests it is the number of CU_COST_UNITs determined by blob size.
For all other requests, the default cost is DEFAULT_COST_FOR_HEAD_DELETE_TTL.
@param restRequest {@link RestRequest} to find type of request.
@param restResponseChannel {@link RestResponseChannel} object.
@param blobInfo {@link BlobInfo} object representing the blob being served.
@return cost in terms of capacity units.
ambry-frontend/src/main/java/com/github/ambry/frontend/SimpleAmbryCostModelPolicy.java