Extracts SpdyHeaderBlock::Storage as a separate library. This is a continuation of the attempt to simplify SpdyHeaderBlock.
gfe-relnote: Refactoring, no functional change.
PiperOrigin-RevId: 284571559
Change-Id: I8396e585439ec58bcdba6aeb22f44f56352625ba
diff --git a/spdy/core/spdy_header_block.cc b/spdy/core/spdy_header_block.cc
index 91c8494..9ccc627 100644
--- a/spdy/core/spdy_header_block.cc
+++ b/spdy/core/spdy_header_block.cc
@@ -25,9 +25,6 @@
// large header blocks.
const size_t kInitialMapBuckets = 11;
-// SpdyHeaderBlock::Storage allocates blocks of this size by default.
-const size_t kDefaultStorageBlockSize = 2048;
-
const char kCookieKey[] = "cookie";
const char kNullSeparator = 0;
@@ -42,62 +39,7 @@
} // namespace
-// This class provides a backing store for SpdyStringPieces. It previously used
-// custom allocation logic, but now uses an UnsafeArena instead. It has the
-// property that SpdyStringPieces that refer to data in Storage are never
-// invalidated until the Storage is deleted or Clear() is called.
-//
-// Write operations always append to the last block. If there is not enough
-// space to perform the write, a new block is allocated, and any unused space
-// is wasted.
-class SpdyHeaderBlock::Storage {
- public:
- Storage() : arena_(kDefaultStorageBlockSize) {}
- Storage(const Storage&) = delete;
- Storage& operator=(const Storage&) = delete;
-
- SpdyStringPiece Write(const SpdyStringPiece s) {
- return SpdyStringPiece(arena_.Memdup(s.data(), s.size()), s.size());
- }
-
- // If |s| points to the most recent allocation from arena_, the arena will
- // reclaim the memory. Otherwise, this method is a no-op.
- void Rewind(const SpdyStringPiece s) {
- arena_.Free(const_cast<char*>(s.data()), s.size());
- }
-
- void Clear() { arena_.Reset(); }
-
- // Given a list of fragments and a separator, writes the fragments joined by
- // the separator to a contiguous region of memory. Returns a SpdyStringPiece
- // pointing to the region of memory.
- SpdyStringPiece WriteFragments(const std::vector<SpdyStringPiece>& fragments,
- SpdyStringPiece separator) {
- if (fragments.empty()) {
- return SpdyStringPiece();
- }
- size_t total_size = separator.size() * (fragments.size() - 1);
- for (const auto fragment : fragments) {
- total_size += fragment.size();
- }
- char* dst = arena_.Alloc(total_size);
- size_t written = Join(dst, fragments, separator);
- DCHECK_EQ(written, total_size);
- return SpdyStringPiece(dst, total_size);
- }
-
- size_t bytes_allocated() const { return arena_.status().bytes_allocated(); }
-
- // TODO(xunjieli): https://crbug.com/669108. Merge this with bytes_allocated()
- size_t EstimateMemoryUsage() const {
- return arena_.status().bytes_allocated();
- }
-
- private:
- SpdyUnsafeArena arena_;
-};
-
-SpdyHeaderBlock::HeaderValue::HeaderValue(Storage* storage,
+SpdyHeaderBlock::HeaderValue::HeaderValue(SpdyHeaderStorage* storage,
SpdyStringPiece key,
SpdyStringPiece initial_value)
: storage_(storage),
@@ -186,8 +128,8 @@
SpdyHeaderBlock::ValueProxy::~ValueProxy() {
// If the ValueProxy is destroyed while lookup_result_ == block_->end(),
- // the assignment operator was never used, and the block's Storage can
- // reclaim the memory used by the key. This makes lookup-only access to
+ // the assignment operator was never used, and the block's SpdyHeaderStorage
+ // can reclaim the memory used by the key. This makes lookup-only access to
// SpdyHeaderBlock through operator[] memory-neutral.
if (valid_ && lookup_result_ == block_->map_.end()) {
block_->GetStorage()->Rewind(key_);
@@ -197,7 +139,7 @@
SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=(
const SpdyStringPiece value) {
*spdy_header_block_value_size_ += value.size();
- Storage* storage = block_->GetStorage();
+ SpdyHeaderStorage* storage = block_->GetStorage();
if (lookup_result_ == block_->map_.end()) {
SPDY_DVLOG(1) << "Inserting: (" << key_ << ", " << value << ")";
lookup_result_ =
@@ -300,7 +242,7 @@
SPDY_DVLOG(1) << "Updating key: " << iter->first
<< " with value: " << value.second;
value_size_ -= iter->second.SizeEstimate();
- auto* storage = GetStorage();
+ SpdyHeaderStorage* storage = GetStorage();
iter->second =
HeaderValue(storage, iter->first, storage->Write(value.second));
}
@@ -350,14 +292,14 @@
void SpdyHeaderBlock::AppendHeader(const SpdyStringPiece key,
const SpdyStringPiece value) {
auto backed_key = WriteKey(key);
- auto* storage = GetStorage();
+ SpdyHeaderStorage* storage = GetStorage();
map_.emplace(std::make_pair(
backed_key, HeaderValue(storage, backed_key, storage->Write(value))));
}
-SpdyHeaderBlock::Storage* SpdyHeaderBlock::GetStorage() {
+SpdyHeaderStorage* SpdyHeaderBlock::GetStorage() {
if (storage_ == nullptr) {
- storage_ = std::make_unique<Storage>();
+ storage_ = std::make_unique<SpdyHeaderStorage>();
}
return storage_.get();
}
@@ -375,23 +317,4 @@
}
}
-size_t Join(char* dst,
- const std::vector<SpdyStringPiece>& fragments,
- SpdyStringPiece separator) {
- if (fragments.empty()) {
- return 0;
- }
- auto* original_dst = dst;
- auto it = fragments.begin();
- memcpy(dst, it->data(), it->size());
- dst += it->size();
- for (++it; it != fragments.end(); ++it) {
- memcpy(dst, separator.data(), separator.size());
- dst += separator.size();
- memcpy(dst, it->data(), it->size());
- dst += it->size();
- }
- return dst - original_dst;
-}
-
} // namespace spdy