Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: base/containers/flat_set.h

Issue 2776793002: Make flat containers stable, allow constructing from vector. (Closed)
Patch Set: Merge Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_CONTAINERS_FLAT_SET_H_ 5 #ifndef BASE_CONTAINERS_FLAT_SET_H_
6 #define BASE_CONTAINERS_FLAT_SET_H_ 6 #define BASE_CONTAINERS_FLAT_SET_H_
7 7
8 #include "base/containers/flat_tree.h" 8 #include "base/containers/flat_tree.h"
9 9
10 namespace base { 10 namespace base {
11 11
12 // Overview: 12 // Overview:
13 // This file implements flat_set container. It is an alternative to standard 13 // This file implements flat_set container. It is an alternative to standard
14 // sorted containers that stores it's elements in contiguous memory (current 14 // sorted containers that stores it's elements in contiguous memory using a
15 // version uses sorted std::vector). 15 // std::vector.
16 //
16 // Discussion that preceded introduction of this container can be found here: 17 // Discussion that preceded introduction of this container can be found here:
17 // https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/vector $20based/chromium-dev/4uQMma9vj9w/HaQ-WvMOAwAJ 18 // https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/vector $20based/chromium-dev/4uQMma9vj9w/HaQ-WvMOAwAJ
18 // 19 //
19 // Motivation: 20 // Motivation:
20 // Contiguous memory is very beneficial to iteration and copy speed at the cost 21 // Contiguous memory is very beneficial to iteration and copy speed at the cost
21 // of worse algorithmic complexity of insertion/erasure operations. They can 22 // of worse algorithmic complexity of insertion/erasure operations. They can
22 // be very fast for set operations and for small number of elements. 23 // be very fast for set operations and for small number of elements.
23 // 24 //
24 // Usage guidance: 25 // Usage guidance:
danakj 2017/04/05 21:33:43 Noticing that guidance of some sort like this is c
25 // Prefer base::flat_set for: 26 // Prefer base::flat_set for:
26 // * Very small sets, something that is an easy fit for cache. Consider 27 // * Very small sets, something that is an easy fit for cache. Consider
27 // "very small" to be under a 100 32bit integers. 28 // "very small" to be under 100 32bit integers.
28 // * Sets that are built once (using flat_set::flat_set(first, last)). Consider 29 // * Sets that are built once (using flat_set::flat_set(first, last)). Consider
29 // collecting all data in a vector and then building flat_set out of it. 30 // collecting all data in a vector and then building flat_set out of it.
30 // TODO(dyaroshev): improve the interface to better support this pattern 31 // Using the cosntructor that takes a vector rvalue allows you to re-use
danakj 2017/04/05 21:33:43 no rvalue
brettw 2017/04/07 21:59:03 Done.
31 // (crbug.com/682254). 32 // storage.
32 // * Sets where mutating happens in big bulks: to erase multiple elements, use 33 // * Sets where mutating happens in big bulks: to erase multiple elements, use
33 // base::EraseIf() rather than repeated single-element removal. Insertion is 34 // base::EraseIf() rather than repeated single-element removal. Insertion is
34 // harder - consider set operations or building a new vector. Set operations 35 // harder - consider set operations or building a new vector. Set operations
35 // can be slow if one of the sets is considerably bigger. Also be aware that 36 // can be slow if one of the sets is considerably bigger. Also be aware that
36 // beating performance of sort + unique (implementation of flat_set's 37 // beating performance of sort + unique (implementation of flat_set's
37 // constructor) is hard, clever merge of many sets might not win. Generally 38 // constructor) is hard, clever merge of many sets might not win. Generally
38 // avoid inserting into flat set without benchmarks. 39 // avoid inserting into flat set without benchmarks.
39 // * Copying and iterating. 40 // * Copying and iterating.
40 // * Set operations (union/intersect etc). 41 // * Set operations (union/intersect etc).
41 // 42 //
42 // Prefer to build a new flat_set from a std::vector (or similar) instead of 43 // Prefer to build a new flat_set from a std::vector (or similar) instead of
43 // calling insert() repeatedly, which would have O(size^2) complexity. 44 // calling insert() repeatedly, which would have O(size^2) complexity. The
45 // constructor that moves a vector (not required to be sorted) is the most
danakj 2017/04/05 21:33:43 receives a vector?
brettw 2017/04/07 21:59:04 Done.
46 // efficient.
44 // 47 //
45 // TODO(dyaroshev): develop standalone benchmarks to find performance boundaries 48 // TODO(dyaroshev): develop standalone benchmarks to find performance boundaries
46 // for different types of sets crbug.com/682215. 49 // for different types of sets crbug.com/682215.
47 // 50 //
48 // If you do write a benchmark that significantly depends on using sets please 51 // If you do write a benchmark that significantly depends on using sets please
49 // share your results at: 52 // share your results at:
50 // https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/vector $20based/chromium-dev/4uQMma9vj9w/HaQ-WvMOAwAJ 53 // https://groups.google.com/a/chromium.org/forum/#!searchin/chromium-dev/vector $20based/chromium-dev/4uQMma9vj9w/HaQ-WvMOAwAJ
51 // 54 //
52 // Important usability aspects: 55 // Important usability aspects:
53 // * flat_set implements std::set interface from C++11 where possible. It 56 // * flat_set implements std::set interface from C++11 where possible. It
54 // also has reserve(), capacity() and shrink_to_fit() from std::vector. 57 // also has reserve(), capacity() and shrink_to_fit() from std::vector.
55 // * iteration invalidation rules differ: 58 // * iteration invalidation rules differ:
56 // - all cases of std::vector::iterator invalidation also apply. 59 // - all cases of std::vector::iterator invalidation also apply.
57 // - we ask (for now) to assume that move operations invalidate iterators. 60 // - we ask (for now) to assume that move operations invalidate iterators.
58 // TODO(dyaroshev): Research the possibility of using a small buffer 61 // TODO(dyaroshev): Research the possibility of using a small buffer
59 // optimization crbug.com/682240. 62 // optimization crbug.com/682240.
60 // * Constructor sorts elements in a non-stable manner (unlike std::set). So
61 // among equivalent (with respect to provided compare) elements passed to
62 // the constructor it is unspecified with one will end up in the set.
63 // However insert()/emplace() methods are stable with respect to already
64 // inserted elements - an element that is already in the set will not be
65 // replaced.
66 // * allocator support is not implemented. 63 // * allocator support is not implemented.
67 // * insert(first, last) and insert(std::initializer_list) are not 64 // * insert(first, last) and insert(std::initializer_list) are not
68 // implemented (see Notes section). 65 // implemented (see Notes section).
69 // 66 //
70 // Notes: 67 // Notes:
71 // Current implementation is based on boost::containers::flat_set, 68 // Current implementation is based on boost::containers::flat_set,
72 // eastl::vector_set and folly::sorted_vector. All of these implementations do 69 // eastl::vector_set and folly::sorted_vector. All of these implementations do
73 // insert(first, last) as insertion one by one (some implementations with hints 70 // insert(first, last) as insertion one by one (some implementations with hints
74 // and/or reserve). Boost documentation claims this algorithm to be O(n*log(n)) 71 // and/or reserve). Boost documentation claims this algorithm to be O(n*log(n))
75 // but it seems to be a quadratic algorithm. For now we do not implement this 72 // but it seems to be a quadratic algorithm. For now we do not implement this
76 // method. 73 // method.
77 // TODO(dyaroshev): research an algorithm for range insertion crbug.com/682249. 74 // TODO(dyaroshev): research an algorithm for range insertion crbug.com/682249.
78 75
79 // QUICK REFERENCE 76 // QUICK REFERENCE
80 // 77 //
81 // Most of the core functionality is inherited from flat_tree. Please see 78 // Most of the core functionality is inherited from flat_tree. Please see
82 // flat_tree.h for more details for most of these functions. As a quick 79 // flat_tree.h for more details for most of these functions. As a quick
83 // reference, the functions available are: 80 // reference, the functions available are:
84 // 81 //
82 // Constructors (inputs need not be sorted, first of duplicates will be kept):
danakj 2017/04/05 21:33:42 Like in the map, the comments saying first is kept
brettw 2017/04/07 21:59:04 Done.
83 // flat_set(InputIterator first, InputIterator last,
84 // FlatContainerDupes, const Compare& compare = Compare());
85 // flat_set(const flat_set&);
86 // flat_set(flat_set&&);
87 // flat_set(std::vector<Key>, FlatContainerDupes); // Re-use storage.
88 // flat_set(std::initializer_list<value_type> ilist,
89 // const Compare& comp = Compare());
90 //
85 // Assignment functions: 91 // Assignment functions:
86 // flat_set& operator=(const flat_set&); 92 // flat_set& operator=(const flat_set&);
87 // flat_set& operator=(flat_set&&); 93 // flat_set& operator=(flat_set&&);
88 // flat_set& operator=(initializer_list<Key>); 94 // flat_set& operator=(initializer_list<Key>);
89 // 95 //
90 // Memory management functions: 96 // Memory management functions:
91 // void reserve(size_t); 97 // void reserve(size_t);
92 // size_t capacity() const; 98 // size_t capacity() const;
93 // void shrink_to_fit(); 99 // void shrink_to_fit();
94 // 100 //
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // Search functions: 136 // Search functions:
131 // size_t count(const Key&) const; 137 // size_t count(const Key&) const;
132 // iterator find(const Key&); 138 // iterator find(const Key&);
133 // const_iterator find(const Key&) const; 139 // const_iterator find(const Key&) const;
134 // pair<iterator, iterator> equal_range(Key&) 140 // pair<iterator, iterator> equal_range(Key&)
135 // iterator lower_bound(const Key&); 141 // iterator lower_bound(const Key&);
136 // const_iterator lower_bound(const Key&) const; 142 // const_iterator lower_bound(const Key&) const;
137 // iterator upper_bound(const Key&); 143 // iterator upper_bound(const Key&);
138 // const_iterator upper_bound(const Key&) const; 144 // const_iterator upper_bound(const Key&) const;
139 // 145 //
140 // General functions 146 // General functions:
141 // void swap(flat_set&&) 147 // void swap(flat_set&&)
142 // 148 //
143 // Non-member operators: 149 // Non-member operators:
144 // bool operator==(const flat_set&, const flat_set); 150 // bool operator==(const flat_set&, const flat_set);
145 // bool operator!=(const flat_set&, const flat_set); 151 // bool operator!=(const flat_set&, const flat_set);
146 // bool operator<(const flat_set&, const flat_set); 152 // bool operator<(const flat_set&, const flat_set);
147 // bool operator>(const flat_set&, const flat_set); 153 // bool operator>(const flat_set&, const flat_set);
148 // bool operator>=(const flat_set&, const flat_set); 154 // bool operator>=(const flat_set&, const flat_set);
149 // bool operator<=(const flat_set&, const flat_set); 155 // bool operator<=(const flat_set&, const flat_set);
150 // 156 //
151 template <class Key, class Compare = std::less<Key>> 157 template <class Key, class Compare = std::less<Key>>
152 using flat_set = typename ::base::internal::flat_tree< 158 using flat_set = typename ::base::internal::flat_tree<
153 Key, 159 Key,
154 Key, 160 Key,
155 ::base::internal::GetKeyFromValueIdentity<Key>, 161 ::base::internal::GetKeyFromValueIdentity<Key>,
156 Compare>; 162 Compare>;
157 163
158 } // namespace base 164 } // namespace base
159 165
160 #endif // BASE_CONTAINERS_FLAT_SET_H_ 166 #endif // BASE_CONTAINERS_FLAT_SET_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698