From 33a4bac623aab0fa4ea5e980fbb08b3766c40c98 Mon Sep 17 00:00:00 2001 From: Alessandro Salvatori Date: Fri, 8 Mar 2013 18:16:59 -0800 Subject: [PATCH] allow to dequeue the first IOBuf in an IOBufQueue Summary: allow to dequeue the first IOBuf in an IOBufQueue Test Plan: throughly tested with some dependent code in proxygen Reviewed By: tudorb@fb.com FB internal diff: D732484 --- folly/io/IOBufQueue.cpp | 12 ++++++++++ folly/io/IOBufQueue.h | 7 ++++++ folly/io/test/IOBufQueueTest.cpp | 39 ++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/folly/io/IOBufQueue.cpp b/folly/io/IOBufQueue.cpp index 35751e03..27c5420a 100644 --- a/folly/io/IOBufQueue.cpp +++ b/folly/io/IOBufQueue.cpp @@ -285,4 +285,16 @@ void IOBufQueue::trimEnd(size_t amount) { } } +std::unique_ptr IOBufQueue::pop_front() { + if (!head_) { + return nullptr; + } + if (options_.cacheChainLength) { + chainLength_ -= head_->length(); + } + std::unique_ptr retBuf = std::move(head_); + head_ = retBuf->pop(); + return retBuf; +} + } // folly diff --git a/folly/io/IOBufQueue.h b/folly/io/IOBufQueue.h index a9065a48..7c32875f 100644 --- a/folly/io/IOBufQueue.h +++ b/folly/io/IOBufQueue.h @@ -204,6 +204,13 @@ class IOBufQueue { return head_.get(); } + /** + * returns the first IOBuf in the chain and removes it from the chain + * + * @return first IOBuf in the chain or nullptr if none. + */ + std::unique_ptr pop_front(); + /** * Total chain length, only valid if cacheLength was specified in the * constructor. diff --git a/folly/io/test/IOBufQueueTest.cpp b/folly/io/test/IOBufQueueTest.cpp index f8990149..caf2fb2b 100644 --- a/folly/io/test/IOBufQueueTest.cpp +++ b/folly/io/test/IOBufQueueTest.cpp @@ -324,6 +324,45 @@ TEST(IOBufQueue, Prepend) { out->length())); } +TEST(IOBufQueue, PopFirst) { + IOBufQueue queue(IOBufQueue::cacheChainLength()); + const char * strings[] = { + "Hello", + ",", + " ", + "", + "World" + }; + + const size_t numStrings=sizeof(strings)/sizeof(*strings); + size_t chainLength = 0; + for(ssize_t i=0; i first; + for(ssize_t i=0; icomputeChainDataLength()); + EXPECT_EQ(chainLength, queue.chainLength()); + first = queue.pop_front(); + chainLength-=strlen(strings[i]); + EXPECT_EQ(strlen(strings[i]), first->computeChainDataLength()); + } + checkConsistency(queue); + EXPECT_EQ(chainLength, queue.chainLength()); + + EXPECT_EQ((IOBuf*)NULL, queue.front()); + first = queue.pop_front(); + EXPECT_EQ((IOBuf*)NULL, first.get()); + + checkConsistency(queue); + EXPECT_EQ((IOBuf*)NULL, queue.front()); + EXPECT_EQ(0, queue.chainLength()); +} + int main(int argc, char** argv) { testing::InitGoogleTest(&argc, argv); google::ParseCommandLineFlags(&argc, &argv, true); -- 2.34.1