Skip to content

buffer: add method to extract front slice without copying#12439

Merged
mattklein123 merged 12 commits intoenvoyproxy:masterfrom
roelfdutoit:master
Aug 10, 2020
Merged

buffer: add method to extract front slice without copying#12439
mattklein123 merged 12 commits intoenvoyproxy:masterfrom
roelfdutoit:master

Conversation

@roelfdutoit
Copy link
Contributor

Add a method to Envoy::Buffer::Instance that may be used to extract the front slice of the implementation's queue (SliceDeque in the case of Buffer::OwnedImpl) without copying the actual payload. A SliceData class is defined to facilitate the extraction process.

Risk Level: Low
Testing: Additional unit tests
Docs Changes: n/a
Release Notes: n/a
Fixes #12373

Roelof DuToit added 2 commits August 3, 2020 15:16
extractFrontSlice() method

Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Roelof DuToit added 2 commits August 3, 2020 16:23
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting together a PR that satisfies your feature request. Some API questions and comments regarding interaction of the new method with existing buffer constructs.

Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
/**
* @return absl::Span<uint8_t> a span of the slice data.
*/
virtual absl::Span<uint8_t> getData() PURE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be something like absl::Span<const uint8_t>

I had not considered const issues in the existing buffer API which was a fairly direct translation of an earlier API built on top of libevent buffers. IIRC data in Unowned slices should be considered immutable. It is technically possible for multiple unowned slices to share the same underlying storage although I think we don't rely on that yet, but in-progress enhancements including the HTTP/1.1 cache extension would benefit from the ability to provide const access to data blocks that are referenced by buffers so multiple requests can reference the same data blocks in the in-memory cache.

Is use of const data blocks compatible with your use case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My use case requires a mutable slice, but I agree that the more common case would be an immutable view of the slice. Commit df19673 attempts to provide both, with immutable as default.

Roelof DuToit added 2 commits August 5, 2020 14:08
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
absl::Span<const uint8_t> getData() const override {
return {base_ + data_, reservable_ - data_};
};
absl::Span<uint8_t> getMutableData() override { return {nullptr, 0}; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calls to this method should crash.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, move this implementation to UnownedSlice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Crash as in ASSERT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had it in UnownedSlice, but decided to move to Slice because:

  1. It is the default pre-override behavior.
  2. DummySlice in buffer_test.cc would have to change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will use the following:

  absl::Span<uint8_t> getMutableData() override {
    RELEASE_ASSERT(isMutable(), "Not allowed to call getMutableData if slice is immutable");
    return {base_ + data_, reservable_ - data_};
  }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed in commit adde208

Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
* a mutable slice that has a copy of the immutable data.
* @return pointer to SliceData object that wraps the front slice
*/
virtual SliceDataPtr extractMutableFrontSlice() PURE;
Copy link
Contributor

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.

Roelof DuToit added 2 commits August 6, 2020 17:52
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
antoniovicente
antoniovicente previously approved these changes Aug 7, 2020
Copy link
Contributor

@antoniovicente antoniovicente left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good. Some minor test issues remain, the bigger one is related to testing of drain trackers on unowned slices.

Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
Signed-off-by: Roelof DuToit <roelof.dutoit@broadcom.com>
@mattklein123 mattklein123 self-assigned this Aug 7, 2020
@mattklein123 mattklein123 merged commit 0d74a8b into envoyproxy:master Aug 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend Envoy::Buffer to allow for transfer of ownership of buffer slices without copying

3 participants