-
Notifications
You must be signed in to change notification settings - Fork 5.5k
buffer: add method to extract front slice without copying #12439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
1bd6278
61f3f7e
e8d4d30
bcc8e01
4d54587
df19673
ed3bfda
adde208
e433529
3079924
b24e3c4
0ece066
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,7 +31,7 @@ namespace Buffer { | |
| * | | ||
| * data() | ||
| */ | ||
| class Slice { | ||
| class Slice : public SliceData { | ||
| public: | ||
| using Reservation = RawSlice; | ||
|
|
||
|
|
@@ -41,6 +41,16 @@ class Slice { | |
| } | ||
|
roelfdutoit marked this conversation as resolved.
Outdated
|
||
| } | ||
|
|
||
| // SliceData | ||
| bool isMutable() const override { | ||
| // Extracted slice data is immutable by default. | ||
| return false; | ||
| }; | ||
| absl::Span<const uint8_t> getData() const override { | ||
| return {base_ + data_, reservable_ - data_}; | ||
| }; | ||
| absl::Span<uint8_t> getMutableData() override { return {nullptr, 0}; } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Calls to this method should crash.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, move this implementation to UnownedSlice.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Crash as in ASSERT?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had it in UnownedSlice, but decided to move to Slice because:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will use the following:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed in commit adde208 |
||
|
|
||
| /** | ||
| * @return a pointer to the start of the usable content. | ||
| */ | ||
|
|
@@ -117,10 +127,10 @@ class Slice { | |
| * @param reservation a reservation obtained from a previous call to reserve(). | ||
| * If the reservation is not from this Slice, commit() will return false. | ||
| * If the caller is committing fewer bytes than provided by reserve(), it | ||
| * should change the mem_ field of the reservation before calling commit(). | ||
| * should change the len_ field of the reservation before calling commit(). | ||
| * For example, if a caller reserve()s 4KB to do a nonblocking socket read, | ||
| * and the read only returns two bytes, the caller should set | ||
| * reservation.mem_ = 2 and then call `commit(reservation)`. | ||
| * reservation.len_ = 2 and then call `commit(reservation)`. | ||
| * @return whether the Reservation was successfully committed to the Slice. | ||
| */ | ||
| bool commit(const Reservation& reservation) { | ||
|
|
@@ -258,6 +268,10 @@ class OwnedSlice final : public Slice, public InlineStorage { | |
| return slice; | ||
| } | ||
|
|
||
| // SliceData | ||
| bool isMutable() const override { return true; }; | ||
| absl::Span<uint8_t> getMutableData() override { return {base_ + data_, reservable_ - data_}; } | ||
|
|
||
| private: | ||
| OwnedSlice(uint64_t size) : Slice(0, 0, size) { base_ = storage_; } | ||
|
|
||
|
|
@@ -539,6 +553,8 @@ class OwnedImpl : public LibEventInstance { | |
| void copyOut(size_t start, uint64_t size, void* data) const override; | ||
| void drain(uint64_t size) override; | ||
| RawSliceVector getRawSlices(absl::optional<uint64_t> max_slices = absl::nullopt) const override; | ||
| SliceDataPtr extractFrontSlice() override; | ||
| SliceDataPtr extractMutableFrontSlice() override; | ||
| uint64_t length() const override; | ||
| void* linearize(uint32_t size) override; | ||
| void move(Instance& rhs) override; | ||
|
|
@@ -558,13 +574,13 @@ class OwnedImpl : public LibEventInstance { | |
| * @param data start of the content to copy. | ||
| * | ||
| */ | ||
| void appendSliceForTest(const void* data, uint64_t size); | ||
| virtual void appendSliceForTest(const void* data, uint64_t size); | ||
|
|
||
| /** | ||
| * Create a new slice at the end of the buffer, and copy the supplied string into it. | ||
| * @param data the string to append to the buffer. | ||
| */ | ||
| void appendSliceForTest(absl::string_view data); | ||
| virtual void appendSliceForTest(absl::string_view data); | ||
|
|
||
| /** | ||
| * Describe the in-memory representation of the slices in the buffer. For use | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sorry for the back and forth about APIs, but I'ld like your opinion on the following:
Should we focus on the mutable slice case and avoid the non mutable case entirely. For OwnedSlices, the extraction method can just return the slice, but in the case of UnownedSlice it would force copy on extraction. Effectively, keep extractMutableFrontSlice and getMutableData methods from the APIs added in this PR, but remove extractFrontSlice, getData and isMutable.
For consistency between these two cases, I think that drain trackers should be cleared from OwnedSlices as part of the extraction process.