Commit fb645211 authored by TJ Yin's avatar TJ Yin Committed by Facebook GitHub Bot

Make RWCursor constructible from IOBufQueue

Summary: This diff added conversion from `IOBufQueue` and `QueueAppender` to `RWCursor`. It's safe to use `RWCursor` to mutate the their underlying `IOBuf` since the structure of `IOBuf` won't changed. It's worth noting appending data to `IOBufQueue` will invalidate RWCursor (just like iterator).

Reviewed By: yfeldblum

Differential Revision: D27257697

fbshipit-source-id: 17887d656a6095afe1c6882426457b9e75a66c84
parent 7df2d7e5
......@@ -897,6 +897,9 @@ class RWCursor : public detail::CursorBase<RWCursor<access>, IOBuf>,
explicit RWCursor(IOBuf* buf)
: detail::CursorBase<RWCursor<access>, IOBuf>(buf), maybeShared_(true) {}
explicit RWCursor(IOBufQueue& queue)
: RWCursor((queue.flushCache(), queue.head_.get())) {}
template <class OtherDerived, class OtherBuf>
explicit RWCursor(const detail::CursorBase<OtherDerived, OtherBuf>& cursor)
: detail::CursorBase<RWCursor<access>, IOBuf>(cursor),
......@@ -1240,6 +1243,11 @@ class QueueAppender : public detail::Writable<QueueAppender> {
queueCache_.queue()->append(buf, true);
}
template <CursorAccess access>
explicit operator RWCursor<access>() {
return RWCursor<access>(*queueCache_.queue());
}
private:
folly::IOBufQueue::WritableRangeCache queueCache_{nullptr};
size_t growth_{0};
......
......@@ -24,6 +24,12 @@
namespace folly {
namespace io {
enum class CursorAccess;
template <CursorAccess>
class RWCursor;
} // namespace io
/**
* An IOBufQueue encapsulates a chain of IOBufs and provides
* convenience functions to append data to the back of the chain
......@@ -34,6 +40,9 @@ namespace folly {
*/
class IOBufQueue {
private:
template <io::CursorAccess>
friend class io::RWCursor;
/**
* This guard should be taken by any method that intends to do any changes
* to in data_ (e.g. appending to it).
......
......@@ -615,6 +615,33 @@ TEST(IOBuf, QueueAppenderInsertClone) {
EXPECT_EQ(x, queue.front()->next()->data()[0]);
}
TEST(IOBuf, QueueAppenderRWCursor) {
folly::IOBufQueue queue;
QueueAppender app(&queue, 100);
const size_t n = 1024 / sizeof(uint32_t);
for (size_t m = 0; m < n; m++) {
for (uint32_t i = 0; i < n; ++i) {
app.writeBE<uint32_t>(0);
}
RWPrivateCursor rw(app);
// Advance cursor to skip data that's already overwritten
rw += m * n * sizeof(uint32_t);
// Overwrite the data
for (uint32_t i = 0; i < n; ++i) {
rw.writeBE<uint32_t>(i + m * n);
}
}
Cursor cursor(queue.front());
for (uint32_t i = 0; i < n * n; ++i) {
EXPECT_EQ(i, cursor.readBE<uint32_t>());
}
}
TEST(IOBuf, CursorOperators) {
// Test operators on a single-item chain
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment