}
pair<void*,uint32_t>
-IOBufQueue::preallocate(uint32_t min, uint32_t maxHint) {
+IOBufQueue::preallocate(uint32_t min, uint32_t newAllocationSize,
+ uint32_t max) {
if (head_ != NULL) {
// If there's enough space left over at the end of the queue, use that.
IOBuf* last = head_->prev();
if (!last->isSharedOne()) {
uint32_t avail = last->tailroom();
if (avail >= min) {
- return make_pair(last->writableTail(), avail);
+ return make_pair(last->writableTail(), std::min(max, avail));
}
}
}
// Allocate a new buffer of the requested max size.
- unique_ptr<IOBuf> newBuf(IOBuf::create(std::max(min, maxHint)));
+ unique_ptr<IOBuf> newBuf(IOBuf::create(std::max(min, newAllocationSize)));
appendToChain(head_, std::move(newBuf));
IOBuf* last = head_->prev();
return make_pair(last->writableTail(),
- last->tailroom() /* may exceed maxHint */);
+ std::min(max, last->tailroom()));
}
void
* Obtain a writable block of contiguous bytes at the end of this
* queue, allocating more space if necessary. The amount of space
* reserved will be at least min. If min contiguous space is not
- * available at the end of the queue, and IOBuf with size maxHint is
- * appended to the chain and returned. The actual available space
- * may be larger than maxHint.
+ * available at the end of the queue, and IOBuf with size newAllocationSize
+ * is appended to the chain and returned. The actual available space
+ * may be larger than newAllocationSize, but will be truncated to max,
+ * if specified.
*
* If the caller subsequently writes anything into the returned space,
* it must call the postallocate() method.
* callback, tell the application how much of the buffer they've
* filled with data.
*/
- std::pair<void*,uint32_t> preallocate(uint32_t min, uint32_t maxHint);
+ std::pair<void*,uint32_t> preallocate(
+ uint32_t min, uint32_t newAllocationSize,
+ uint32_t max = std::numeric_limits<uint32_t>::max());
/**
* Tell the queue that the caller has written data into the first n
TEST(IOBufQueue, Preallocate) {
IOBufQueue queue(clOptions);
queue.append(string("Hello"));
- pair<void*,uint32_t> writable = queue.preallocate(2, 64);
+ pair<void*,uint32_t> writable = queue.preallocate(2, 64, 64);
checkConsistency(queue);
EXPECT_NE((void*)NULL, writable.first);
EXPECT_LE(2, writable.second);
+ EXPECT_GE(64, writable.second);
memcpy(writable.first, SCL(", "));
queue.postallocate(2);
checkConsistency(queue);
queue.append(SCL("World"));
checkConsistency(queue);
EXPECT_EQ(12, queue.front()->computeChainDataLength());
- writable = queue.preallocate(1024, 4096);
+ // There are not 2048 bytes available, this will alloc a new buf
+ writable = queue.preallocate(2048, 4096);
checkConsistency(queue);
- EXPECT_LE(1024, writable.second);
+ EXPECT_LE(2048, writable.second);
+ // IOBuf allocates more than newAllocationSize, and we didn't cap it
+ EXPECT_GE(writable.second, 4096);
queue.postallocate(writable.second);
// queue has no empty space, make sure we allocate at least min, even if
- // maxHint < min
- writable = queue.preallocate(1024, 1);
+ // newAllocationSize < min
+ writable = queue.preallocate(1024, 1, 1024);
checkConsistency(queue);
- EXPECT_LE(1024, writable.second);
+ EXPECT_EQ(1024, writable.second);
}
TEST(IOBufQueue, Wrap) {