docs: @VisibleForTesting
    synchronized void trimToSize(int targetSize) {
      // find how much we need to free
      int bytesToFree = Math.min(mUsed.mNumBytes + mFree.mNumBytes - targetSize, mFree.mNumBytes);
      if (bytesToFree <= 0) {
        return;
      }
      if (FLog.isLoggable(FLog.VERBOSE)) {
        FLog.v(
            TAG,
            "trimToSize: TargetSize = %d; Initial Size = %d; Bytes to free = %d",
            targetSize,
            mUsed.mNumBytes + mFree.mNumBytes,
            bytesToFree);
      }
      logStats();
  
      // now walk through the buckets from the smallest to the largest. Keep freeing things
      // until we've gotten to what we want
      for (int i = 0; i < mBuckets.size(); ++i) {
        if (bytesToFree <= 0) {
          break;
        }
        Bucket<V> bucket = mBuckets.valueAt(i);
        while (bytesToFree > 0) {
          V value = bucket.pop();
          if (value == null) {
            break;
          }
          free(value);
          bytesToFree -= bucket.mItemSize;
          mFree.decrement(bucket.mItemSize);
        }
      }
  
      // dump stats at the end
      logStats();
      if (FLog.isLoggable(FLog.VERBOSE)) {
        FLog.v(
            TAG,
            "trimToSize: TargetSize = %d; Final Size = %d",
            targetSize,
            mUsed.mNumBytes + mFree.mNumBytes);
      }
    }