This change simplifies SpdyHeaderBlock and SpdyHeaderStorage, now that the underlying arena implementation does not allocate memory upon construction. gfe-relnote: Code simplifications to classes in //third_party/spdy, no functional change; not protected. PiperOrigin-RevId: 284805587 Change-Id: I3b0cbdda821c1f2ea89b9f880d76a3132490b196
diff --git a/spdy/core/spdy_header_block.cc b/spdy/core/spdy_header_block.cc index 9ccc627..609f6d7 100644 --- a/spdy/core/spdy_header_block.cc +++ b/spdy/core/spdy_header_block.cc
@@ -12,7 +12,6 @@ #include "net/third_party/quiche/src/spdy/platform/api/spdy_estimate_memory_usage.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h" #include "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h" -#include "net/third_party/quiche/src/spdy/platform/api/spdy_unsafe_arena.h" namespace spdy { namespace { @@ -65,6 +64,10 @@ return *this; } +void SpdyHeaderBlock::HeaderValue::set_storage(SpdyHeaderStorage* storage) { + storage_ = storage; +} + SpdyHeaderBlock::HeaderValue::~HeaderValue() = default; SpdyStringPiece SpdyHeaderBlock::HeaderValue::ConsolidatedValue() const { @@ -132,14 +135,14 @@ // 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_); + block_->storage_.Rewind(key_); } } SpdyHeaderBlock::ValueProxy& SpdyHeaderBlock::ValueProxy::operator=( const SpdyStringPiece value) { *spdy_header_block_value_size_ += value.size(); - SpdyHeaderStorage* storage = block_->GetStorage(); + SpdyHeaderStorage* storage = &block_->storage_; if (lookup_result_ == block_->map_.end()) { SPDY_DVLOG(1) << "Inserting: (" << key_ << ", " << value << ")"; lookup_result_ = @@ -168,7 +171,10 @@ SpdyHeaderBlock::SpdyHeaderBlock(SpdyHeaderBlock&& other) : map_(kInitialMapBuckets) { map_.swap(other.map_); - storage_.swap(other.storage_); + storage_ = std::move(other.storage_); + for (auto& p : map_) { + p.second.set_storage(&storage_); + } key_size_ = other.key_size_; value_size_ = other.value_size_; } @@ -177,7 +183,10 @@ SpdyHeaderBlock& SpdyHeaderBlock::operator=(SpdyHeaderBlock&& other) { map_.swap(other.map_); - storage_.swap(other.storage_); + storage_ = std::move(other.storage_); + for (auto& p : map_) { + p.second.set_storage(&storage_); + } key_size_ = other.key_size_; value_size_ = other.value_size_; return *this; @@ -226,7 +235,7 @@ key_size_ = 0; value_size_ = 0; map_.clear(); - storage_.reset(); + storage_.Clear(); } void SpdyHeaderBlock::insert(const SpdyHeaderBlock::value_type& value) { @@ -242,9 +251,8 @@ SPDY_DVLOG(1) << "Updating key: " << iter->first << " with value: " << value.second; value_size_ -= iter->second.SizeEstimate(); - SpdyHeaderStorage* storage = GetStorage(); iter->second = - HeaderValue(storage, iter->first, storage->Write(value.second)); + HeaderValue(&storage_, iter->first, storage_.Write(value.second)); } } @@ -280,7 +288,7 @@ SPDY_DVLOG(1) << "Updating key: " << iter->first << "; appending value: " << value; value_size_ += SeparatorForKey(key).size(); - iter->second.Append(GetStorage()->Write(value)); + iter->second.Append(storage_.Write(value)); } size_t SpdyHeaderBlock::EstimateMemoryUsage() const { @@ -292,29 +300,17 @@ void SpdyHeaderBlock::AppendHeader(const SpdyStringPiece key, const SpdyStringPiece value) { auto backed_key = WriteKey(key); - SpdyHeaderStorage* storage = GetStorage(); map_.emplace(std::make_pair( - backed_key, HeaderValue(storage, backed_key, storage->Write(value)))); -} - -SpdyHeaderStorage* SpdyHeaderBlock::GetStorage() { - if (storage_ == nullptr) { - storage_ = std::make_unique<SpdyHeaderStorage>(); - } - return storage_.get(); + backed_key, HeaderValue(&storage_, backed_key, storage_.Write(value)))); } SpdyStringPiece SpdyHeaderBlock::WriteKey(const SpdyStringPiece key) { key_size_ += key.size(); - return GetStorage()->Write(key); + return storage_.Write(key); } size_t SpdyHeaderBlock::bytes_allocated() const { - if (storage_ == nullptr) { - return 0; - } else { - return storage_->bytes_allocated(); - } + return storage_.bytes_allocated(); } } // namespace spdy
diff --git a/spdy/core/spdy_header_block.h b/spdy/core/spdy_header_block.h index ff5f4c9..bd575f4 100644 --- a/spdy/core/spdy_header_block.h +++ b/spdy/core/spdy_header_block.h
@@ -8,7 +8,6 @@ #include <stddef.h> #include <list> -#include <memory> #include <string> #include <utility> #include <vector> @@ -51,6 +50,8 @@ HeaderValue(HeaderValue&& other); HeaderValue& operator=(HeaderValue&& other); + void set_storage(SpdyHeaderStorage* storage); + // Copies are not. HeaderValue(const HeaderValue& other) = delete; HeaderValue& operator=(const HeaderValue& other) = delete; @@ -225,14 +226,12 @@ friend class test::SpdyHeaderBlockPeer; void AppendHeader(const SpdyStringPiece key, const SpdyStringPiece value); - SpdyHeaderStorage* GetStorage(); SpdyStringPiece WriteKey(const SpdyStringPiece key); size_t bytes_allocated() const; - // SpdyStringPieces held by |map_| point to memory owned by |*storage_|. - // |storage_| might be nullptr as long as |map_| is empty. + // SpdyStringPieces held by |map_| point to memory owned by |storage_|. MapType map_; - std::unique_ptr<SpdyHeaderStorage> storage_; + SpdyHeaderStorage storage_; size_t key_size_ = 0; size_t value_size_ = 0;
diff --git a/spdy/core/spdy_header_block_test.cc b/spdy/core/spdy_header_block_test.cc index a744a3b..774854b 100644 --- a/spdy/core/spdy_header_block_test.cc +++ b/spdy/core/spdy_header_block_test.cc
@@ -118,6 +118,13 @@ EXPECT_NE(block1, block2); } +SpdyHeaderBlock ReturnTestHeaderBlock() { + SpdyHeaderBlock block; + block["foo"] = "bar"; + block.insert(std::make_pair("foo2", "baz")); + return block; +} + // Test that certain methods do not crash on moved-from instances. TEST(SpdyHeaderBlockTest, MovedFromIsValid) { SpdyHeaderBlock block1; @@ -139,6 +146,11 @@ block1["foo"] = "bar"; EXPECT_THAT(block1, ElementsAre(Pair("foo", "bar"))); + + SpdyHeaderBlock block5 = ReturnTestHeaderBlock(); + block5.AppendValueOrAddHeader("foo", "bar2"); + EXPECT_THAT(block5, ElementsAre(Pair("foo", std::string("bar\0bar2", 8)), + Pair("foo2", "baz"))); } // This test verifies that headers can be appended to no matter how they were
diff --git a/spdy/core/spdy_header_storage.h b/spdy/core/spdy_header_storage.h index fd31555..fc559ec 100644 --- a/spdy/core/spdy_header_storage.h +++ b/spdy/core/spdy_header_storage.h
@@ -23,6 +23,9 @@ SpdyHeaderStorage(const SpdyHeaderStorage&) = delete; SpdyHeaderStorage& operator=(const SpdyHeaderStorage&) = delete; + SpdyHeaderStorage(SpdyHeaderStorage&& other) = default; + SpdyHeaderStorage& operator=(SpdyHeaderStorage&& other) = default; + SpdyStringPiece Write(SpdyStringPiece s); // If |s| points to the most recent allocation from arena_, the arena will