Commit b4d098e3 authored by Dan Zhang's avatar Dan Zhang Committed by Commit Bot

Add SimpleLinkedHashMap and its platform impl's. Deprecate...

Add SimpleLinkedHashMap and its platform impl's. Deprecate net::linked_hash_map and replace it with the new class.

R=rch@chromium.org

Change-Id: I326fbe373d9e036c2c7cd30dd378f44e5055ef21
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1590616Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarRyan Hamilton <rch@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Commit-Queue: Dan Zhang <danzh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#656383}
parent 11cae6b9
......@@ -10,12 +10,12 @@
#include <memory>
#include "base/macros.h"
#include "net/base/linked_hash_map.h"
#include "net/third_party/quiche/src/common/simple_linked_hash_map.h"
template <class Key, class Value>
class ScopedPtrExpiringCache {
private:
typedef net::linked_hash_map<Key, Value*> LinkedHashMap;
typedef quiche::SimpleLinkedHashMap<Key, Value*> LinkedHashMap;
public:
typedef typename LinkedHashMap::iterator iterator;
......
......@@ -459,7 +459,6 @@ component("net") {
"base/ip_pattern.h",
"base/layered_network_delegate.cc",
"base/layered_network_delegate.h",
"base/linked_hash_map.h",
"base/load_flags.h",
"base/load_flags_list.h",
"base/load_states.h",
......@@ -1057,6 +1056,9 @@ component("net") {
"quic/quic_stream_factory.h",
"quic/quic_utils_chromium.cc",
"quic/quic_utils_chromium.h",
"quiche/common/platform/impl/quiche_logging_impl.h",
"quiche/common/platform/impl/quiche_ptr_util_impl.h",
"quiche/common/platform/impl/quiche_unordered_containers_impl.h",
"socket/client_socket_factory.cc",
"socket/client_socket_factory.h",
"socket/client_socket_pool.cc",
......@@ -1208,7 +1210,6 @@ component("net") {
"third_party/mozilla_security_manager/nsPKCS12Blob.h",
"third_party/quiche/src/common/platform/api/quiche_logging.h",
"third_party/quiche/src/common/platform/api/quiche_ptr_util.h",
"third_party/quiche/src/common/platform/api/quiche_test.h",
"third_party/quiche/src/common/platform/api/quiche_unordered_containers.h",
"third_party/quiche/src/common/simple_linked_hash_map.h",
"third_party/quiche/src/http2/decoder/decode_buffer.cc",
......@@ -3263,6 +3264,18 @@ source_set("spdy_test_tools") {
]
}
source_set("quiche_test_tools") {
testonly = true
sources = [
"quiche/common/platform/impl/quiche_test_impl.h",
"third_party/quiche/src/common/platform/api/quiche_test.h",
]
deps = [
"//testing/gmock",
"//testing/gtest",
]
}
source_set("quic_test_tools") {
testonly = true
sources = [
......@@ -5213,6 +5226,7 @@ test("net_unittests") {
"test/run_all_unittests.cc",
"test/tcp_socket_proxy_unittest.cc",
"third_party/nist-pkits/pkits_testcases-inl.h",
"third_party/quiche/src/common/simple_linked_hash_map_test.cc",
"third_party/quiche/src/http2/decoder/decode_buffer_test.cc",
"third_party/quiche/src/http2/decoder/decode_http2_structures_test.cc",
"third_party/quiche/src/http2/decoder/frame_decoder_state_test_util.cc",
......@@ -5544,6 +5558,7 @@ test("net_unittests") {
deps = [
":net",
":quic_test_tools",
":quiche_test_tools",
":simple_quic_tools",
":spdy_test_tools",
":test_support",
......
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// This is a simplistic insertion-ordered map. It behaves similarly to an STL
// map, but only implements a small subset of the map's methods. Internally, we
// just keep a map and a list going in parallel.
//
// This class provides no thread safety guarantees, beyond what you would
// normally see with std::list.
//
// Iterators should be stable in the face of mutations, except for an
// iterator pointing to an element that was just deleted.
#ifndef NET_BASE_LINKED_HASH_MAP_H_
#define NET_BASE_LINKED_HASH_MAP_H_
#include <stddef.h>
#include <list>
#include <unordered_map>
#include <utility>
#include "base/logging.h"
#include "base/macros.h"
namespace net {
// This holds a list of pair<Key, Value> items. This list is what gets
// traversed, and it's iterators from this list that we return from
// begin/end/find.
//
// We also keep a map<Key, list::iterator> for find. Since std::list is a
// doubly-linked list, the iterators should remain stable.
template <class Key, class Value, class Hash = std::hash<Key>>
class linked_hash_map {
private:
typedef std::list<std::pair<Key, Value> > ListType;
typedef std::unordered_map<Key, typename ListType::iterator, Hash> MapType;
public:
typedef typename ListType::iterator iterator;
typedef typename ListType::reverse_iterator reverse_iterator;
typedef typename ListType::const_iterator const_iterator;
typedef typename ListType::const_reverse_iterator const_reverse_iterator;
typedef typename MapType::key_type key_type;
typedef typename ListType::value_type value_type;
typedef typename ListType::size_type size_type;
linked_hash_map() = default;
explicit linked_hash_map(size_type bucket_count) : map_(bucket_count) {}
linked_hash_map(linked_hash_map&& other) = default;
linked_hash_map& operator=(linked_hash_map&& other) = default;
// Returns an iterator to the first (insertion-ordered) element. Like a map,
// this can be dereferenced to a pair<Key, Value>.
iterator begin() {
return list_.begin();
}
const_iterator begin() const {
return list_.begin();
}
// Returns an iterator beyond the last element.
iterator end() {
return list_.end();
}
const_iterator end() const {
return list_.end();
}
// Returns an iterator to the last (insertion-ordered) element. Like a map,
// this can be dereferenced to a pair<Key, Value>.
reverse_iterator rbegin() {
return list_.rbegin();
}
const_reverse_iterator rbegin() const {
return list_.rbegin();
}
// Returns an iterator beyond the first element.
reverse_iterator rend() {
return list_.rend();
}
const_reverse_iterator rend() const {
return list_.rend();
}
// Front and back accessors common to many stl containers.
// Returns the earliest-inserted element
const value_type& front() const {
return list_.front();
}
// Returns the earliest-inserted element.
value_type& front() {
return list_.front();
}
// Returns the most-recently-inserted element.
const value_type& back() const {
return list_.back();
}
// Returns the most-recently-inserted element.
value_type& back() {
return list_.back();
}
// Clears the map of all values.
void clear() {
map_.clear();
list_.clear();
}
// Returns true iff the map is empty.
bool empty() const {
return list_.empty();
}
// Removes the first element from the list.
void pop_front() { erase(begin()); }
// Erases values with the provided key. Returns the number of elements
// erased. In this implementation, this will be 0 or 1.
size_type erase(const Key& key) {
typename MapType::iterator found = map_.find(key);
if (found == map_.end()) return 0;
list_.erase(found->second);
map_.erase(found);
return 1;
}
// Erases the item that 'position' points to. Returns an iterator that points
// to the item that comes immediately after the deleted item in the list, or
// end().
// If the provided iterator is invalid or there is inconsistency between the
// map and list, a CHECK() error will occur.
iterator erase(iterator position) {
typename MapType::iterator found = map_.find(position->first);
CHECK(found->second == position)
<< "Inconsisent iterator for map and list, or the iterator is invalid.";
map_.erase(found);
return list_.erase(position);
}
// Erases all the items in the range [first, last). Returns an iterator that
// points to the item that comes immediately after the last deleted item in
// the list, or end().
iterator erase(iterator first, iterator last) {
while (first != last && first != end()) {
first = erase(first);
}
return first;
}
// Finds the element with the given key. Returns an iterator to the
// value found, or to end() if the value was not found. Like a map, this
// iterator points to a pair<Key, Value>.
iterator find(const Key& key) {
typename MapType::iterator found = map_.find(key);
if (found == map_.end()) {
return end();
}
return found->second;
}
const_iterator find(const Key& key) const {
typename MapType::const_iterator found = map_.find(key);
if (found == map_.end()) {
return end();
}
return found->second;
}
// Returns the bounds of a range that includes all the elements in the
// container with a key that compares equal to x.
std::pair<iterator, iterator> equal_range(const key_type& key) {
std::pair<typename MapType::iterator, typename MapType::iterator> eq_range =
map_.equal_range(key);
return std::make_pair(eq_range.first->second, eq_range.second->second);
}
std::pair<const_iterator, const_iterator> equal_range(
const key_type& key) const {
std::pair<typename MapType::const_iterator,
typename MapType::const_iterator> eq_range =
map_.equal_range(key);
const const_iterator& start_iter = eq_range.first != map_.end() ?
eq_range.first->second : end();
const const_iterator& end_iter = eq_range.second != map_.end() ?
eq_range.second->second : end();
return std::make_pair(start_iter, end_iter);
}
// Returns the value mapped to key, or an inserted iterator to that position
// in the map.
Value& operator[](const key_type& key) {
return (*((this->insert(std::make_pair(key, Value()))).first)).second;
}
// Inserts an element into the map
std::pair<iterator, bool> insert(const std::pair<Key, Value>& pair) {
// First make sure the map doesn't have a key with this value. If it does,
// return a pair with an iterator to it, and false indicating that we
// didn't insert anything.
typename MapType::iterator found = map_.find(pair.first);
if (found != map_.end()) return std::make_pair(found->second, false);
// Otherwise, insert into the list first.
list_.push_back(pair);
// Obtain an iterator to the newly added element. We do -- instead of -
// since list::iterator doesn't implement operator-().
typename ListType::iterator last = list_.end();
--last;
CHECK(map_.insert(std::make_pair(pair.first, last)).second)
<< "Map and list are inconsistent";
return std::make_pair(last, true);
}
size_type size() const {
return list_.size();
}
template <typename... Args>
std::pair<iterator, bool> emplace(Args&&... args) {
ListType node_donor;
auto node_pos =
node_donor.emplace(node_donor.end(), std::forward<Args>(args)...);
const auto& k = node_pos->first;
auto ins = map_.insert({k, node_pos});
if (!ins.second)
return {ins.first->second, false};
list_.splice(list_.end(), node_donor, node_pos);
return {ins.first->second, true};
}
void swap(linked_hash_map& other) {
map_.swap(other.map_);
list_.swap(other.list_);
}
private:
// The map component, used for speedy lookups
MapType map_;
// The list component, used for maintaining insertion order
ListType list_;
// |map_| contains iterators to |list_|, therefore a default copy constructor
// or copy assignment operator would result in an inconsistent state.
DISALLOW_COPY_AND_ASSIGN(linked_hash_map);
};
} // namespace net
#endif // NET_BASE_LINKED_HASH_MAP_H_
......@@ -21,7 +21,6 @@
#include "base/values.h"
#include "net/base/host_port_pair.h"
#include "net/base/ip_address.h"
#include "net/base/linked_hash_map.h"
#include "net/base/net_export.h"
#include "net/http/broken_alternative_services.h"
#include "net/http/http_server_properties.h"
......
......@@ -13,7 +13,7 @@
#include "base/containers/queue.h"
#include "base/containers/small_map.h"
#include "net/base/interval_set.h"
#include "net/base/linked_hash_map.h"
#include "net/third_party/quiche/src/common/simple_linked_hash_map.h"
namespace quic {
......@@ -43,7 +43,7 @@ using QuicUnorderedSetImpl = std::unordered_set<Key, Hash, Eq, Alloc>;
// A map which offers insertion-ordered iteration.
template <typename Key, typename Value, typename Hash>
using QuicLinkedHashMapImpl = net::linked_hash_map<Key, Value, Hash>;
using QuicLinkedHashMapImpl = quiche::SimpleLinkedHashMap<Key, Value, Hash>;
// A map which is faster than (for example) hash_map for a certain number of
// unique key-value-pair elements, and upgrades itself to unordered_map when
......
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
#include "base/logging.h"
#endif // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_LOGGING_IMPL_H_
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_PTR_UTIL_IMPL_H_
#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_PTR_UTIL_IMPL_H_
#include <memory>
namespace quiche {
template <typename T, typename... Args>
std::unique_ptr<T> QuicheMakeUniqueImpl(Args&&... args) {
return std::make_unique<T>(std::forward<Args>(args)...);
}
} // namespace quiche
#endif // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_PTR_UTIL_IMPL_H_
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TEST_IMPL_H_
#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TEST_IMPL_H_
#include "testing/gmock/include/gmock/gmock.h" // IWYU pragma: export
#include "testing/gtest/include/gtest/gtest.h" // IWYU pragma: export
#endif // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_TEST_IMPL_H_
// Copyright (c) 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_UNORDERED_CONTAINERS_IMPL_H_
#define NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_UNORDERED_CONTAINERS_IMPL_H_
#include <unordered_map>
namespace quiche {
// The default hasher used by hash tables.
template <typename Key>
using QuicheDefaultHasherImpl = std::hash<Key>;
template <typename Key,
typename Value,
typename Hash,
typename Eq =
typename std::unordered_map<Key, Value, Hash>::key_equal,
typename Alloc =
typename std::unordered_map<Key, Value, Hash>::allocator_type>
using QuicheUnorderedMapImpl = std::unordered_map<Key, Value, Hash, Eq, Alloc>;
} // namespace quiche
#endif // NET_QUICHE_COMMON_PLATFORM_IMPL_QUICHE_UNORDERED_CONTAINERS_IMPL_H_
......@@ -9,7 +9,7 @@
#include <vector>
#include "base/strings/string_piece.h"
#include "net/base/linked_hash_map.h"
#include "net/third_party/quiche/src/common/simple_linked_hash_map.h"
namespace spdy {
......@@ -23,7 +23,7 @@ template <typename ElementType, typename Hasher, typename Eq>
using SpdyHashSetImpl = std::unordered_set<ElementType, Hasher, Eq>;
template <typename Key, typename Value, typename Hash>
using SpdyLinkedHashMapImpl = net::linked_hash_map<Key, Value, Hash>;
using SpdyLinkedHashMapImpl = quiche::SimpleLinkedHashMap<Key, Value, Hash>;
template <typename T, size_t N, typename A = std::allocator<T>>
using SpdyInlinedVectorImpl = std::vector<T, A>;
......
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