allow to dequeue the first IOBuf in an IOBufQueue
authorAlessandro Salvatori <alessandros@fb.com>
Sat, 9 Mar 2013 02:16:59 +0000 (18:16 -0800)
committerOwen Yamauchi <oyamauchi@fb.com>
Wed, 27 Mar 2013 21:39:07 +0000 (14:39 -0700)
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
folly/io/IOBufQueue.h
folly/io/test/IOBufQueueTest.cpp

index 35751e03822835df33240869f03f8b870b788c0d..27c5420ae50a13d0377bf7c085a4675099462b9d 100644 (file)
@@ -285,4 +285,16 @@ void IOBufQueue::trimEnd(size_t amount) {
   }
 }
 
+std::unique_ptr<folly::IOBuf> IOBufQueue::pop_front() {
+  if (!head_) {
+    return nullptr;
+  }
+  if (options_.cacheChainLength) {
+    chainLength_ -= head_->length();
+  }
+  std::unique_ptr<folly::IOBuf> retBuf = std::move(head_);
+  head_ = retBuf->pop();
+  return retBuf;
+}
+
 } // folly
index a9065a486842d9e964252743dcd89b94c54863fb..7c32875f2c9068bcdd579a20dd217957d1b639de 100644 (file)
@@ -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<folly::IOBuf> pop_front();
+
   /**
    * Total chain length, only valid if cacheLength was specified in the
    * constructor.
index f8990149d2a603efa41062ea58ad9f2fac860a91..caf2fb2b2b8ed611ac6b3f6acbfae61b42e5c989 100644 (file)
@@ -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<numStrings; ++i) {
+    queue.append(stringToIOBuf(strings[i], strlen(strings[i])));
+    checkConsistency(queue);
+    chainLength += strlen(strings[i]);
+  }
+
+  unique_ptr<IOBuf> first;
+  for(ssize_t i=0; i<numStrings; ++i) {
+    checkConsistency(queue);
+    EXPECT_EQ(chainLength, queue.front()->computeChainDataLength());
+    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);