uint64_t OwnedImpl::reserve(uint64_t length, RawSlice* iovecs, uint64_t num_iovecs) {
  if (num_iovecs == 0 || length == 0) {
    return 0;
  }
  // Check whether there are any empty slices with reservable space at the end of the buffer.
  size_t first_reservable_slice = slices_.size();
  while (first_reservable_slice > 0) {
    if (slices_[first_reservable_slice - 1]->reservableSize() == 0) {
      break;
    }
    first_reservable_slice--;
    if (slices_[first_reservable_slice]->dataSize() != 0) {
      // There is some content in this slice, so anything in front of it is non-reservable.
      break;
    }
  }

  // Having found the sequence of reservable slices at the back of the buffer, reserve
  // as much space as possible from each one.
  uint64_t num_slices_used = 0;
  uint64_t bytes_remaining = length;
  size_t slice_index = first_reservable_slice;
  while (slice_index < slices_.size() && bytes_remaining != 0 && num_slices_used < num_iovecs) {
    auto& slice = slices_[slice_index];
    const uint64_t reservation_size = std::min(slice->reservableSize(), bytes_remaining);
    if (num_slices_used + 1 == num_iovecs && reservation_size < bytes_remaining) {
      // There is only one iovec left, and this next slice does not have enough space to
      // complete the reservation. Stop iterating, with last one iovec still unpopulated,
      // so the code following this loop can allocate a new slice to hold the rest of the
      // reservation.
      break;
    }
    iovecs[num_slices_used] = slice->reserve(reservation_size);
    bytes_remaining -= iovecs[num_slices_used].len_;
    num_slices_used++;
    slice_index++;
  }

  // If needed, allocate one more slice at the end to provide the remainder of the reservation.
  if (bytes_remaining != 0) {
    slices_.emplace_back(OwnedSlice::create(bytes_remaining));
    iovecs[num_slices_used] = slices_.back()->reserve(bytes_remaining);
    bytes_remaining -= iovecs[num_slices_used].len_;
    num_slices_used++;
  }

  ASSERT(num_slices_used <= num_iovecs);
  ASSERT(bytes_remaining == 0);
  return num_slices_used;
}
uint64_t OwnedImpl::reserve(uint64_t length, RawSlice* iovecs, uint64_t num_iovecs) {
  if (num_iovecs == 0 || length == 0) {
    return 0;
  }
   
  size_t first_reservable_slice = slices_.size();
  while (first_reservable_slice > 0) {
    if (slices_[first_reservable_slice - 1]->reservableSize() == 0) {
      break;
    }
    first_reservable_slice--;
    if (slices_[first_reservable_slice]->dataSize() != 0) {
       
      break;
    }
  }

   
   
  uint64_t num_slices_used = 0;
  uint64_t bytes_remaining = length;
  size_t slice_index = first_reservable_slice;
  while (slice_index < slices_.size() && bytes_remaining != 0 && num_slices_used < num_iovecs) {
    auto& slice = slices_[slice_index];
    const uint64_t reservation_size = std::min(slice->reservableSize(), bytes_remaining);
    if (num_slices_used + 1 == num_iovecs && reservation_size < bytes_remaining) {
       
       
       
       
      break;
    }
    iovecs[num_slices_used] = slice->reserve(reservation_size);
    bytes_remaining -= iovecs[num_slices_used].len_;
    num_slices_used++;
    slice_index++;
  }

   
  if (bytes_remaining != 0) {
    slices_.emplace_back(OwnedSlice::create(bytes_remaining));
    iovecs[num_slices_used] = slices_.back()->reserve(bytes_remaining);
    bytes_remaining -= iovecs[num_slices_used].len_;
    num_slices_used++;
  }

  ASSERT(num_slices_used <= num_iovecs);
  ASSERT(bytes_remaining == 0);
  return num_slices_used;
}