map.h 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. // This file defines the map container and its helpers to support protobuf maps.
  31. //
  32. // The Map and MapIterator types are provided by this header file.
  33. // Please avoid using other types defined here, unless they are public
  34. // types within Map or MapIterator, such as Map::value_type.
  35. #ifndef GOOGLE_PROTOBUF_MAP_H__
  36. #define GOOGLE_PROTOBUF_MAP_H__
  37. #include <algorithm>
  38. #include <functional>
  39. #include <initializer_list>
  40. #include <iterator>
  41. #include <limits> // To support Visual Studio 2008
  42. #include <string>
  43. #include <type_traits>
  44. #include <utility>
  45. #if !defined(GOOGLE_PROTOBUF_NO_RDTSC) && defined(__APPLE__)
  46. #include <mach/mach_time.h>
  47. #endif
  48. #include "google/protobuf/stubs/common.h"
  49. #include "absl/container/btree_map.h"
  50. #include "absl/hash/hash.h"
  51. #include "absl/meta/type_traits.h"
  52. #include "absl/strings/string_view.h"
  53. #include "google/protobuf/arena.h"
  54. #include "google/protobuf/generated_enum_util.h"
  55. #include "google/protobuf/map_type_handler.h"
  56. #include "google/protobuf/port.h"
  57. #ifdef SWIG
  58. #error "You cannot SWIG proto headers"
  59. #endif
  60. // Must be included last.
  61. #include "google/protobuf/port_def.inc"
  62. namespace google {
  63. namespace protobuf {
  64. template <typename Key, typename T>
  65. class Map;
  66. class MapIterator;
  67. template <typename Enum>
  68. struct is_proto_enum;
  69. namespace internal {
  70. template <typename Derived, typename Key, typename T,
  71. WireFormatLite::FieldType key_wire_type,
  72. WireFormatLite::FieldType value_wire_type>
  73. class MapFieldLite;
  74. template <typename Derived, typename Key, typename T,
  75. WireFormatLite::FieldType key_wire_type,
  76. WireFormatLite::FieldType value_wire_type>
  77. class MapField;
  78. template <typename Key, typename T>
  79. class TypeDefinedMapFieldBase;
  80. class DynamicMapField;
  81. class GeneratedMessageReflection;
  82. // Internal type traits that can be used to define custom key/value types. These
  83. // are only be specialized by protobuf internals, and never by users.
  84. template <typename T, typename VoidT = void>
  85. struct is_internal_map_key_type : std::false_type {};
  86. template <typename T, typename VoidT = void>
  87. struct is_internal_map_value_type : std::false_type {};
  88. // re-implement std::allocator to use arena allocator for memory allocation.
  89. // Used for Map implementation. Users should not use this class
  90. // directly.
  91. template <typename U>
  92. class MapAllocator {
  93. public:
  94. using value_type = U;
  95. using pointer = value_type*;
  96. using const_pointer = const value_type*;
  97. using reference = value_type&;
  98. using const_reference = const value_type&;
  99. using size_type = size_t;
  100. using difference_type = ptrdiff_t;
  101. constexpr MapAllocator() : arena_(nullptr) {}
  102. explicit constexpr MapAllocator(Arena* arena) : arena_(arena) {}
  103. template <typename X>
  104. MapAllocator(const MapAllocator<X>& allocator) // NOLINT(runtime/explicit)
  105. : arena_(allocator.arena()) {}
  106. // MapAllocator does not support alignments beyond 8. Technically we should
  107. // support up to std::max_align_t, but this fails with ubsan and tcmalloc
  108. // debug allocation logic which assume 8 as default alignment.
  109. static_assert(alignof(value_type) <= 8, "");
  110. pointer allocate(size_type n, const void* /* hint */ = nullptr) {
  111. // If arena is not given, malloc needs to be called which doesn't
  112. // construct element object.
  113. if (arena_ == nullptr) {
  114. return static_cast<pointer>(::operator new(n * sizeof(value_type)));
  115. } else {
  116. return reinterpret_cast<pointer>(
  117. Arena::CreateArray<uint8_t>(arena_, n * sizeof(value_type)));
  118. }
  119. }
  120. void deallocate(pointer p, size_type n) {
  121. if (arena_ == nullptr) {
  122. internal::SizedDelete(p, n * sizeof(value_type));
  123. }
  124. }
  125. #if !defined(GOOGLE_PROTOBUF_OS_APPLE) && !defined(GOOGLE_PROTOBUF_OS_NACL) && \
  126. !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
  127. template <class NodeType, class... Args>
  128. void construct(NodeType* p, Args&&... args) {
  129. // Clang 3.6 doesn't compile static casting to void* directly. (Issue
  130. // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall
  131. // not cast away constness". So first the maybe const pointer is casted to
  132. // const void* and after the const void* is const casted.
  133. new (const_cast<void*>(static_cast<const void*>(p)))
  134. NodeType(std::forward<Args>(args)...);
  135. }
  136. template <class NodeType>
  137. void destroy(NodeType* p) {
  138. p->~NodeType();
  139. }
  140. #else
  141. void construct(pointer p, const_reference t) { new (p) value_type(t); }
  142. void destroy(pointer p) { p->~value_type(); }
  143. #endif
  144. template <typename X>
  145. struct rebind {
  146. using other = MapAllocator<X>;
  147. };
  148. template <typename X>
  149. bool operator==(const MapAllocator<X>& other) const {
  150. return arena_ == other.arena_;
  151. }
  152. template <typename X>
  153. bool operator!=(const MapAllocator<X>& other) const {
  154. return arena_ != other.arena_;
  155. }
  156. // To support Visual Studio 2008
  157. size_type max_size() const {
  158. // parentheses around (std::...:max) prevents macro warning of max()
  159. return (std::numeric_limits<size_type>::max)();
  160. }
  161. // To support gcc-4.4, which does not properly
  162. // support templated friend classes
  163. Arena* arena() const { return arena_; }
  164. private:
  165. using DestructorSkippable_ = void;
  166. Arena* arena_;
  167. };
  168. // To save on binary size and simplify generic uses of the map types we collapse
  169. // signed/unsigned versions of the same sized integer to the unsigned version.
  170. template <typename T, typename = void>
  171. struct KeyForBaseImpl {
  172. using type = T;
  173. };
  174. template <typename T>
  175. struct KeyForBaseImpl<T, std::enable_if_t<std::is_integral<T>::value &&
  176. std::is_signed<T>::value>> {
  177. using type = std::make_unsigned_t<T>;
  178. };
  179. template <typename T>
  180. using KeyForBase = typename KeyForBaseImpl<T>::type;
  181. // Default case: Not transparent.
  182. // We use std::hash<key_type>/std::less<key_type> and all the lookup functions
  183. // only accept `key_type`.
  184. template <typename key_type>
  185. struct TransparentSupport {
  186. using hash = std::hash<key_type>;
  187. using less = std::less<key_type>;
  188. static bool Equals(const key_type& a, const key_type& b) { return a == b; }
  189. template <typename K>
  190. using key_arg = key_type;
  191. };
  192. // We add transparent support for std::string keys. We use
  193. // std::hash<absl::string_view> as it supports the input types we care about.
  194. // The lookup functions accept arbitrary `K`. This will include any key type
  195. // that is convertible to absl::string_view.
  196. template <>
  197. struct TransparentSupport<std::string> {
  198. // If the element is not convertible to absl::string_view, try to convert to
  199. // std::string first, and then fallback to support for converting from
  200. // std::string_view. The ranked overload pattern is used to specify our
  201. // order of preference.
  202. struct Rank0 {};
  203. struct Rank1 : Rank0 {};
  204. struct Rank2 : Rank1 {};
  205. template <typename T, typename = std::enable_if_t<
  206. std::is_convertible<T, absl::string_view>::value>>
  207. static absl::string_view ImplicitConvertImpl(T&& str, Rank2) {
  208. absl::string_view ref = str;
  209. return ref;
  210. }
  211. template <typename T, typename = std::enable_if_t<
  212. std::is_convertible<T, const std::string&>::value>>
  213. static absl::string_view ImplicitConvertImpl(T&& str, Rank1) {
  214. const std::string& ref = str;
  215. return ref;
  216. }
  217. template <typename T>
  218. static absl::string_view ImplicitConvertImpl(T&& str, Rank0) {
  219. return {str.data(), str.size()};
  220. }
  221. template <typename T>
  222. static absl::string_view ImplicitConvert(T&& str) {
  223. return ImplicitConvertImpl(std::forward<T>(str), Rank2{});
  224. }
  225. struct hash : public absl::Hash<absl::string_view> {
  226. using is_transparent = void;
  227. template <typename T>
  228. size_t operator()(T&& str) const {
  229. return absl::Hash<absl::string_view>::operator()(
  230. ImplicitConvert(std::forward<T>(str)));
  231. }
  232. };
  233. struct less {
  234. using is_transparent = void;
  235. template <typename T, typename U>
  236. bool operator()(T&& t, U&& u) const {
  237. return ImplicitConvert(std::forward<T>(t)) <
  238. ImplicitConvert(std::forward<U>(u));
  239. }
  240. };
  241. template <typename T, typename U>
  242. static bool Equals(T&& t, U&& u) {
  243. return ImplicitConvert(std::forward<T>(t)) ==
  244. ImplicitConvert(std::forward<U>(u));
  245. }
  246. template <typename K>
  247. using key_arg = K;
  248. };
  249. struct NodeBase {
  250. // Align the node to allow KeyNode to predict the location of the key.
  251. // This way sizeof(NodeBase) contains any possible padding it was going to
  252. // have between NodeBase and the key.
  253. alignas(kMaxMessageAlignment) NodeBase* next;
  254. };
  255. inline NodeBase* EraseFromLinkedList(NodeBase* item, NodeBase* head) {
  256. if (head == item) {
  257. return head->next;
  258. } else {
  259. head->next = EraseFromLinkedList(item, head->next);
  260. return head;
  261. }
  262. }
  263. inline bool TableEntryIsTooLong(NodeBase* node) {
  264. const size_t kMaxLength = 8;
  265. size_t count = 0;
  266. do {
  267. ++count;
  268. node = node->next;
  269. } while (node != nullptr);
  270. // Invariant: no linked list ever is more than kMaxLength in length.
  271. ABSL_DCHECK_LE(count, kMaxLength);
  272. return count >= kMaxLength;
  273. }
  274. template <typename T>
  275. using KeyForTree = std::conditional_t<std::is_integral<T>::value, uint64_t,
  276. std::reference_wrapper<const T>>;
  277. template <typename T>
  278. using LessForTree = typename TransparentSupport<
  279. std::conditional_t<std::is_integral<T>::value, uint64_t, T>>::less;
  280. template <typename Key>
  281. using TreeForMap =
  282. absl::btree_map<KeyForTree<Key>, NodeBase*, LessForTree<Key>,
  283. MapAllocator<std::pair<const KeyForTree<Key>, NodeBase*>>>;
  284. // Type safe tagged pointer.
  285. // We convert to/from nodes and trees using the operations below.
  286. // They ensure that the tags are used correctly.
  287. // There are three states:
  288. // - x == 0: the entry is empty
  289. // - x != 0 && (x&1) == 0: the entry is a node list
  290. // - x != 0 && (x&1) == 1: the entry is a tree
  291. enum class TableEntryPtr : uintptr_t;
  292. inline bool TableEntryIsEmpty(TableEntryPtr entry) {
  293. return entry == TableEntryPtr{};
  294. }
  295. inline bool TableEntryIsTree(TableEntryPtr entry) {
  296. return (static_cast<uintptr_t>(entry) & 1) == 1;
  297. }
  298. inline bool TableEntryIsList(TableEntryPtr entry) {
  299. return !TableEntryIsTree(entry);
  300. }
  301. inline bool TableEntryIsNonEmptyList(TableEntryPtr entry) {
  302. return !TableEntryIsEmpty(entry) && TableEntryIsList(entry);
  303. }
  304. inline NodeBase* TableEntryToNode(TableEntryPtr entry) {
  305. ABSL_DCHECK(TableEntryIsList(entry));
  306. return reinterpret_cast<NodeBase*>(static_cast<uintptr_t>(entry));
  307. }
  308. inline TableEntryPtr NodeToTableEntry(NodeBase* node) {
  309. ABSL_DCHECK((reinterpret_cast<uintptr_t>(node) & 1) == 0);
  310. return static_cast<TableEntryPtr>(reinterpret_cast<uintptr_t>(node));
  311. }
  312. template <typename Tree>
  313. Tree* TableEntryToTree(TableEntryPtr entry) {
  314. ABSL_DCHECK(TableEntryIsTree(entry));
  315. return reinterpret_cast<Tree*>(static_cast<uintptr_t>(entry) - 1);
  316. }
  317. template <typename Tree>
  318. TableEntryPtr TreeToTableEntry(Tree* node) {
  319. ABSL_DCHECK((reinterpret_cast<uintptr_t>(node) & 1) == 0);
  320. return static_cast<TableEntryPtr>(reinterpret_cast<uintptr_t>(node) | 1);
  321. }
  322. // This captures all numeric types.
  323. inline size_t MapValueSpaceUsedExcludingSelfLong(bool) { return 0; }
  324. inline size_t MapValueSpaceUsedExcludingSelfLong(const std::string& str) {
  325. return StringSpaceUsedExcludingSelfLong(str);
  326. }
  327. template <typename T,
  328. typename = decltype(std::declval<const T&>().SpaceUsedLong())>
  329. size_t MapValueSpaceUsedExcludingSelfLong(const T& message) {
  330. return message.SpaceUsedLong() - sizeof(T);
  331. }
  332. constexpr size_t kGlobalEmptyTableSize = 1;
  333. PROTOBUF_EXPORT extern const TableEntryPtr
  334. kGlobalEmptyTable[kGlobalEmptyTableSize];
  335. // Space used for the table, trees, and nodes.
  336. // Does not include the indirect space used. Eg the data of a std::string.
  337. template <typename Key>
  338. PROTOBUF_NOINLINE size_t SpaceUsedInTable(TableEntryPtr* table,
  339. size_t num_buckets,
  340. size_t num_elements,
  341. size_t sizeof_node) {
  342. size_t size = 0;
  343. // The size of the table.
  344. size += sizeof(void*) * num_buckets;
  345. // All the nodes.
  346. size += sizeof_node * num_elements;
  347. // For each tree, count the overhead of the those nodes.
  348. // Two buckets at a time because we only care about trees.
  349. for (size_t b = 0; b < num_buckets; ++b) {
  350. if (internal::TableEntryIsTree(table[b])) {
  351. using Tree = TreeForMap<Key>;
  352. Tree* tree = TableEntryToTree<Tree>(table[b]);
  353. // Estimated cost of the red-black tree nodes, 3 pointers plus a
  354. // bool (plus alignment, so 4 pointers).
  355. size += tree->size() *
  356. (sizeof(typename Tree::value_type) + sizeof(void*) * 4);
  357. }
  358. }
  359. return size;
  360. }
  361. template <typename Map,
  362. typename = typename std::enable_if<
  363. !std::is_scalar<typename Map::key_type>::value ||
  364. !std::is_scalar<typename Map::mapped_type>::value>::type>
  365. size_t SpaceUsedInValues(const Map* map) {
  366. size_t size = 0;
  367. for (const auto& v : *map) {
  368. size += internal::MapValueSpaceUsedExcludingSelfLong(v.first) +
  369. internal::MapValueSpaceUsedExcludingSelfLong(v.second);
  370. }
  371. return size;
  372. }
  373. inline size_t SpaceUsedInValues(const void*) { return 0; }
  374. // Base class for all Map instantiations.
  375. // This class holds all the data and provides the basic functionality shared
  376. // among all instantiations.
  377. // Having an untyped base class helps generic consumers (like the table-driven
  378. // parser) by having non-template code that can handle all instantiations.
  379. class PROTOBUF_EXPORT UntypedMapBase {
  380. using Allocator = internal::MapAllocator<void*>;
  381. public:
  382. using size_type = size_t;
  383. explicit constexpr UntypedMapBase(Arena* arena)
  384. : num_elements_(0),
  385. num_buckets_(internal::kGlobalEmptyTableSize),
  386. seed_(0),
  387. index_of_first_non_null_(internal::kGlobalEmptyTableSize),
  388. table_(const_cast<TableEntryPtr*>(internal::kGlobalEmptyTable)),
  389. alloc_(arena) {}
  390. UntypedMapBase(const UntypedMapBase&) = delete;
  391. UntypedMapBase& operator=(const UntypedMapBase&) = delete;
  392. protected:
  393. enum { kMinTableSize = 8 };
  394. public:
  395. Arena* arena() const { return this->alloc_.arena(); }
  396. void Swap(UntypedMapBase* other) {
  397. std::swap(num_elements_, other->num_elements_);
  398. std::swap(num_buckets_, other->num_buckets_);
  399. std::swap(seed_, other->seed_);
  400. std::swap(index_of_first_non_null_, other->index_of_first_non_null_);
  401. std::swap(table_, other->table_);
  402. std::swap(alloc_, other->alloc_);
  403. }
  404. static size_type max_size() {
  405. return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
  406. }
  407. size_type size() const { return num_elements_; }
  408. bool empty() const { return size() == 0; }
  409. protected:
  410. friend class TcParser;
  411. struct NodeAndBucket {
  412. NodeBase* node;
  413. size_type bucket;
  414. };
  415. // Returns whether we should insert after the head of the list. For
  416. // non-optimized builds, we randomly decide whether to insert right at the
  417. // head of the list or just after the head. This helps add a little bit of
  418. // non-determinism to the map ordering.
  419. bool ShouldInsertAfterHead(void* node) {
  420. #ifdef NDEBUG
  421. (void)node;
  422. return false;
  423. #else
  424. // Doing modulo with a prime mixes the bits more.
  425. return (reinterpret_cast<uintptr_t>(node) ^ seed_) % 13 > 6;
  426. #endif
  427. }
  428. // Helper for InsertUnique. Handles the case where bucket b is a
  429. // not-too-long linked list.
  430. void InsertUniqueInList(size_type b, NodeBase* node) {
  431. if (!TableEntryIsEmpty(b) && ShouldInsertAfterHead(node)) {
  432. auto* first = TableEntryToNode(table_[b]);
  433. node->next = first->next;
  434. first->next = node;
  435. } else {
  436. node->next = TableEntryToNode(table_[b]);
  437. table_[b] = NodeToTableEntry(node);
  438. }
  439. }
  440. bool TableEntryIsEmpty(size_type b) const {
  441. return internal::TableEntryIsEmpty(table_[b]);
  442. }
  443. bool TableEntryIsNonEmptyList(size_type b) const {
  444. return internal::TableEntryIsNonEmptyList(table_[b]);
  445. }
  446. bool TableEntryIsTree(size_type b) const {
  447. return internal::TableEntryIsTree(table_[b]);
  448. }
  449. bool TableEntryIsList(size_type b) const {
  450. return internal::TableEntryIsList(table_[b]);
  451. }
  452. // Return whether table_[b] is a linked list that seems awfully long.
  453. // Requires table_[b] to point to a non-empty linked list.
  454. bool TableEntryIsTooLong(size_type b) {
  455. return internal::TableEntryIsTooLong(TableEntryToNode(table_[b]));
  456. }
  457. // Return a power of two no less than max(kMinTableSize, n).
  458. // Assumes either n < kMinTableSize or n is a power of two.
  459. size_type TableSize(size_type n) {
  460. return n < static_cast<size_type>(kMinTableSize)
  461. ? static_cast<size_type>(kMinTableSize)
  462. : n;
  463. }
  464. template <typename T>
  465. using AllocFor = absl::allocator_traits<Allocator>::template rebind_alloc<T>;
  466. // Alignment of the nodes is the same as alignment of NodeBase.
  467. NodeBase* AllocNode(size_t node_size) {
  468. PROTOBUF_ASSUME(node_size % sizeof(NodeBase) == 0);
  469. return AllocFor<NodeBase>(alloc_).allocate(node_size / sizeof(NodeBase));
  470. }
  471. void DeallocNode(NodeBase* node, size_t node_size) {
  472. PROTOBUF_ASSUME(node_size % sizeof(NodeBase) == 0);
  473. AllocFor<NodeBase>(alloc_).deallocate(node, node_size / sizeof(NodeBase));
  474. }
  475. void DeleteTable(TableEntryPtr* table, size_type n) {
  476. AllocFor<TableEntryPtr>(alloc_).deallocate(table, n);
  477. }
  478. TableEntryPtr* CreateEmptyTable(size_type n) {
  479. ABSL_DCHECK_GE(n, size_type{kMinTableSize});
  480. ABSL_DCHECK_EQ(n & (n - 1), 0u);
  481. TableEntryPtr* result = AllocFor<TableEntryPtr>(alloc_).allocate(n);
  482. memset(result, 0, n * sizeof(result[0]));
  483. return result;
  484. }
  485. // Return a randomish value.
  486. size_type Seed() const {
  487. // We get a little bit of randomness from the address of the map. The
  488. // lower bits are not very random, due to alignment, so we discard them
  489. // and shift the higher bits into their place.
  490. size_type s = reinterpret_cast<uintptr_t>(this) >> 4;
  491. #if !defined(GOOGLE_PROTOBUF_NO_RDTSC)
  492. #if defined(__APPLE__)
  493. // Use a commpage-based fast time function on Apple environments (MacOS,
  494. // iOS, tvOS, watchOS, etc).
  495. s += mach_absolute_time();
  496. #elif defined(__x86_64__) && defined(__GNUC__)
  497. uint32_t hi, lo;
  498. asm volatile("rdtsc" : "=a"(lo), "=d"(hi));
  499. s += ((static_cast<uint64_t>(hi) << 32) | lo);
  500. #elif defined(__aarch64__) && defined(__GNUC__)
  501. // There is no rdtsc on ARMv8. CNTVCT_EL0 is the virtual counter of the
  502. // system timer. It runs at a different frequency than the CPU's, but is
  503. // the best source of time-based entropy we get.
  504. uint64_t virtual_timer_value;
  505. asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
  506. s += virtual_timer_value;
  507. #endif
  508. #endif // !defined(GOOGLE_PROTOBUF_NO_RDTSC)
  509. return s;
  510. }
  511. size_type num_elements_;
  512. size_type num_buckets_;
  513. size_type seed_;
  514. size_type index_of_first_non_null_;
  515. TableEntryPtr* table_; // an array with num_buckets_ entries
  516. Allocator alloc_;
  517. };
  518. // The value might be of different signedness, so use memcpy to extract it.
  519. template <typename T, std::enable_if_t<std::is_integral<T>::value, int> = 0>
  520. T ReadKey(const void* ptr) {
  521. T out;
  522. memcpy(&out, ptr, sizeof(T));
  523. return out;
  524. }
  525. template <typename T, std::enable_if_t<!std::is_integral<T>::value, int> = 0>
  526. const T& ReadKey(const void* ptr) {
  527. return *reinterpret_cast<const T*>(ptr);
  528. }
  529. // KeyMapBase is a chaining hash map with the additional feature that some
  530. // buckets can be converted to use an ordered container. This ensures O(lg n)
  531. // bounds on find, insert, and erase, while avoiding the overheads of ordered
  532. // containers most of the time.
  533. //
  534. // The implementation doesn't need the full generality of unordered_map,
  535. // and it doesn't have it. More bells and whistles can be added as needed.
  536. // Some implementation details:
  537. // 1. The number of buckets is a power of two.
  538. // 2. As is typical for hash_map and such, the Keys and Values are always
  539. // stored in linked list nodes. Pointers to elements are never invalidated
  540. // until the element is deleted.
  541. // 3. The trees' payload type is pointer to linked-list node. Tree-converting
  542. // a bucket doesn't copy Key-Value pairs.
  543. // 4. Once we've tree-converted a bucket, it is never converted back unless the
  544. // bucket is completely emptied out. Note that the items a tree contains may
  545. // wind up assigned to trees or lists upon a rehash.
  546. // 5. Mutations to a map do not invalidate the map's iterators, pointers to
  547. // elements, or references to elements.
  548. // 6. Except for erase(iterator), any non-const method can reorder iterators.
  549. // 7. Uses KeyForTree<Key> when using the Tree representation, which
  550. // is either `uint64_t` if `Key` is an integer, or
  551. // `reference_wrapper<const Key>` otherwise. This avoids unnecessary copies
  552. // of string keys, for example.
  553. template <typename Key>
  554. class KeyMapBase : public UntypedMapBase {
  555. static_assert(!std::is_signed<Key>::value || !std::is_integral<Key>::value,
  556. "");
  557. public:
  558. using hasher = typename TransparentSupport<Key>::hash;
  559. using UntypedMapBase::UntypedMapBase;
  560. protected:
  561. struct KeyNode : NodeBase {
  562. static constexpr size_t kOffset = sizeof(NodeBase);
  563. decltype(auto) key() const {
  564. return ReadKey<Key>(reinterpret_cast<const char*>(this) + kOffset);
  565. }
  566. };
  567. // Trees. The payload type is a copy of Key, so that we can query the tree
  568. // with Keys that are not in any particular data structure.
  569. // The value is a void* pointing to Node. We use void* instead of Node* to
  570. // avoid code bloat. That way there is only one instantiation of the tree
  571. // class per key type.
  572. using Tree = internal::TreeForMap<Key>;
  573. using TreeIterator = typename Tree::iterator;
  574. class KeyIteratorBase {
  575. public:
  576. // Invariants:
  577. // node_ is always correct. This is handy because the most common
  578. // operations are operator* and operator-> and they only use node_.
  579. // When node_ is set to a non-null value, all the other non-const fields
  580. // are updated to be correct also, but those fields can become stale
  581. // if the underlying map is modified. When those fields are needed they
  582. // are rechecked, and updated if necessary.
  583. KeyIteratorBase() : node_(nullptr), m_(nullptr), bucket_index_(0) {}
  584. explicit KeyIteratorBase(const KeyMapBase* m) : m_(m) {
  585. SearchFrom(m->index_of_first_non_null_);
  586. }
  587. KeyIteratorBase(KeyNode* n, const KeyMapBase* m, size_type index)
  588. : node_(n), m_(m), bucket_index_(index) {}
  589. KeyIteratorBase(TreeIterator tree_it, const KeyMapBase* m, size_type index)
  590. : node_(NodeFromTreeIterator(tree_it)), m_(m), bucket_index_(index) {}
  591. // Advance through buckets, looking for the first that isn't empty.
  592. // If nothing non-empty is found then leave node_ == nullptr.
  593. void SearchFrom(size_type start_bucket) {
  594. ABSL_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
  595. !m_->TableEntryIsEmpty(m_->index_of_first_non_null_));
  596. for (size_type i = start_bucket; i < m_->num_buckets_; ++i) {
  597. TableEntryPtr entry = m_->table_[i];
  598. if (entry == TableEntryPtr{}) continue;
  599. bucket_index_ = i;
  600. if (PROTOBUF_PREDICT_TRUE(internal::TableEntryIsList(entry))) {
  601. node_ = static_cast<KeyNode*>(TableEntryToNode(entry));
  602. } else {
  603. Tree* tree = TableEntryToTree<Tree>(entry);
  604. ABSL_DCHECK(!tree->empty());
  605. node_ = static_cast<KeyNode*>(tree->begin()->second);
  606. }
  607. return;
  608. }
  609. node_ = nullptr;
  610. bucket_index_ = 0;
  611. }
  612. // The definition of operator== is handled by the derived type. If we were
  613. // to do it in this class it would allow comparing iterators of different
  614. // map types.
  615. bool Equals(const KeyIteratorBase& other) const {
  616. return node_ == other.node_;
  617. }
  618. // The definition of operator++ is handled in the derived type. We would not
  619. // be able to return the right type from here.
  620. void PlusPlus() {
  621. if (node_->next == nullptr) {
  622. SearchFrom(bucket_index_ + 1);
  623. } else {
  624. node_ = static_cast<KeyNode*>(node_->next);
  625. }
  626. }
  627. KeyNode* node_;
  628. const KeyMapBase* m_;
  629. size_type bucket_index_;
  630. };
  631. public:
  632. hasher hash_function() const { return {}; }
  633. protected:
  634. PROTOBUF_NOINLINE void erase_no_destroy(size_type b, KeyNode* node) {
  635. TreeIterator tree_it;
  636. const bool is_list = revalidate_if_necessary(b, node, &tree_it);
  637. if (is_list) {
  638. ABSL_DCHECK(TableEntryIsNonEmptyList(b));
  639. auto* head = TableEntryToNode(table_[b]);
  640. head = EraseFromLinkedList(node, head);
  641. table_[b] = NodeToTableEntry(head);
  642. } else {
  643. ABSL_DCHECK(this->TableEntryIsTree(b));
  644. Tree* tree = internal::TableEntryToTree<Tree>(this->table_[b]);
  645. if (tree_it != tree->begin()) {
  646. auto* prev = std::prev(tree_it)->second;
  647. prev->next = prev->next->next;
  648. }
  649. tree->erase(tree_it);
  650. if (tree->empty()) {
  651. this->DestroyTree(tree);
  652. this->table_[b] = TableEntryPtr{};
  653. }
  654. }
  655. --num_elements_;
  656. if (PROTOBUF_PREDICT_FALSE(b == index_of_first_non_null_)) {
  657. while (index_of_first_non_null_ < num_buckets_ &&
  658. TableEntryIsEmpty(index_of_first_non_null_)) {
  659. ++index_of_first_non_null_;
  660. }
  661. }
  662. }
  663. // TODO(sbenza): We can reduce duplication by coercing `K` to a common type.
  664. // Eg, for string keys we can coerce to string_view. Otherwise, we instantiate
  665. // this with all the different `char[N]` of the caller.
  666. template <typename K>
  667. NodeAndBucket FindHelper(const K& k, TreeIterator* it = nullptr) const {
  668. size_type b = BucketNumber(k);
  669. if (TableEntryIsNonEmptyList(b)) {
  670. auto* node = internal::TableEntryToNode(table_[b]);
  671. do {
  672. if (internal::TransparentSupport<Key>::Equals(
  673. static_cast<KeyNode*>(node)->key(), k)) {
  674. return {node, b};
  675. } else {
  676. node = node->next;
  677. }
  678. } while (node != nullptr);
  679. } else if (TableEntryIsTree(b)) {
  680. Tree* tree = internal::TableEntryToTree<Tree>(table_[b]);
  681. auto tree_it = tree->find(k);
  682. if (it != nullptr) *it = tree_it;
  683. if (tree_it != tree->end()) {
  684. return {tree_it->second, b};
  685. }
  686. }
  687. return {nullptr, b};
  688. }
  689. // Insert the given Node in bucket b. If that would make bucket b too big,
  690. // and bucket b is not a tree, create a tree for buckets b.
  691. // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
  692. // bucket. num_elements_ is not modified.
  693. void InsertUnique(size_type b, KeyNode* node) {
  694. ABSL_DCHECK(index_of_first_non_null_ == num_buckets_ ||
  695. !TableEntryIsEmpty(index_of_first_non_null_));
  696. // In practice, the code that led to this point may have already
  697. // determined whether we are inserting into an empty list, a short list,
  698. // or whatever. But it's probably cheap enough to recompute that here;
  699. // it's likely that we're inserting into an empty or short list.
  700. ABSL_DCHECK(FindHelper(node->key()).node == nullptr);
  701. if (TableEntryIsEmpty(b)) {
  702. InsertUniqueInList(b, node);
  703. index_of_first_non_null_ = (std::min)(index_of_first_non_null_, b);
  704. } else if (TableEntryIsNonEmptyList(b) && !TableEntryIsTooLong(b)) {
  705. InsertUniqueInList(b, node);
  706. } else {
  707. if (TableEntryIsNonEmptyList(b)) {
  708. TreeConvert(b);
  709. }
  710. ABSL_DCHECK(TableEntryIsTree(b))
  711. << (void*)table_[b] << " " << (uintptr_t)table_[b];
  712. InsertUniqueInTree(b, node);
  713. index_of_first_non_null_ = (std::min)(index_of_first_non_null_, b);
  714. }
  715. }
  716. // Helper for InsertUnique. Handles the case where bucket b points to a
  717. // Tree.
  718. void InsertUniqueInTree(size_type b, KeyNode* node) {
  719. auto* tree = TableEntryToTree<Tree>(table_[b]);
  720. auto it = tree->insert({node->key(), node}).first;
  721. // Maintain the linked list of the nodes in the tree.
  722. // For simplicity, they are in the same order as the tree iteration.
  723. if (it != tree->begin()) {
  724. auto* prev = std::prev(it)->second;
  725. prev->next = node;
  726. }
  727. auto next = std::next(it);
  728. node->next = next != tree->end() ? next->second : nullptr;
  729. }
  730. // Returns whether it did resize. Currently this is only used when
  731. // num_elements_ increases, though it could be used in other situations.
  732. // It checks for load too low as well as load too high: because any number
  733. // of erases can occur between inserts, the load could be as low as 0 here.
  734. // Resizing to a lower size is not always helpful, but failing to do so can
  735. // destroy the expected big-O bounds for some operations. By having the
  736. // policy that sometimes we resize down as well as up, clients can easily
  737. // keep O(size()) = O(number of buckets) if they want that.
  738. bool ResizeIfLoadIsOutOfRange(size_type new_size) {
  739. const size_type kMaxMapLoadTimes16 = 12; // controls RAM vs CPU tradeoff
  740. const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
  741. const size_type lo_cutoff = hi_cutoff / 4;
  742. // We don't care how many elements are in trees. If a lot are,
  743. // we may resize even though there are many empty buckets. In
  744. // practice, this seems fine.
  745. if (PROTOBUF_PREDICT_FALSE(new_size >= hi_cutoff)) {
  746. if (num_buckets_ <= max_size() / 2) {
  747. Resize(num_buckets_ * 2);
  748. return true;
  749. }
  750. } else if (PROTOBUF_PREDICT_FALSE(new_size <= lo_cutoff &&
  751. num_buckets_ > kMinTableSize)) {
  752. size_type lg2_of_size_reduction_factor = 1;
  753. // It's possible we want to shrink a lot here... size() could even be 0.
  754. // So, estimate how much to shrink by making sure we don't shrink so
  755. // much that we would need to grow the table after a few inserts.
  756. const size_type hypothetical_size = new_size * 5 / 4 + 1;
  757. while ((hypothetical_size << lg2_of_size_reduction_factor) < hi_cutoff) {
  758. ++lg2_of_size_reduction_factor;
  759. }
  760. size_type new_num_buckets = std::max<size_type>(
  761. kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
  762. if (new_num_buckets != num_buckets_) {
  763. Resize(new_num_buckets);
  764. return true;
  765. }
  766. }
  767. return false;
  768. }
  769. // Resize to the given number of buckets.
  770. void Resize(size_t new_num_buckets) {
  771. if (num_buckets_ == kGlobalEmptyTableSize) {
  772. // This is the global empty array.
  773. // Just overwrite with a new one. No need to transfer or free anything.
  774. num_buckets_ = index_of_first_non_null_ = kMinTableSize;
  775. table_ = CreateEmptyTable(num_buckets_);
  776. seed_ = Seed();
  777. return;
  778. }
  779. ABSL_DCHECK_GE(new_num_buckets, kMinTableSize);
  780. const auto old_table = table_;
  781. const size_type old_table_size = num_buckets_;
  782. num_buckets_ = new_num_buckets;
  783. table_ = CreateEmptyTable(num_buckets_);
  784. const size_type start = index_of_first_non_null_;
  785. index_of_first_non_null_ = num_buckets_;
  786. for (size_type i = start; i < old_table_size; ++i) {
  787. if (internal::TableEntryIsNonEmptyList(old_table[i])) {
  788. TransferList(static_cast<KeyNode*>(TableEntryToNode(old_table[i])));
  789. } else if (internal::TableEntryIsTree(old_table[i])) {
  790. TransferTree(TableEntryToTree<Tree>(old_table[i]));
  791. }
  792. }
  793. DeleteTable(old_table, old_table_size);
  794. }
  795. // Transfer all nodes in the list `node` into `this`.
  796. void TransferList(KeyNode* node) {
  797. do {
  798. auto* next = static_cast<KeyNode*>(node->next);
  799. InsertUnique(BucketNumber(node->key()), node);
  800. node = next;
  801. } while (node != nullptr);
  802. }
  803. // Transfer all nodes in the tree `tree` into `this` and destroy the tree.
  804. void TransferTree(Tree* tree) {
  805. auto* node = tree->begin()->second;
  806. DestroyTree(tree);
  807. TransferList(static_cast<KeyNode*>(node));
  808. }
  809. void TreeConvert(size_type b) {
  810. ABSL_DCHECK(!TableEntryIsTree(b));
  811. Tree* tree =
  812. Arena::Create<Tree>(alloc_.arena(), typename Tree::key_compare(),
  813. typename Tree::allocator_type(alloc_));
  814. size_type count = CopyListToTree(b, tree);
  815. ABSL_DCHECK_EQ(count, tree->size());
  816. table_[b] = TreeToTableEntry(tree);
  817. // Relink the nodes.
  818. NodeBase* next = nullptr;
  819. auto it = tree->end();
  820. do {
  821. auto* node = (--it)->second;
  822. node->next = next;
  823. next = node;
  824. } while (it != tree->begin());
  825. }
  826. // Copy a linked list in the given bucket to a tree.
  827. // Returns the number of things it copied.
  828. size_type CopyListToTree(size_type b, Tree* tree) {
  829. size_type count = 0;
  830. auto* node = TableEntryToNode(table_[b]);
  831. while (node != nullptr) {
  832. tree->insert({static_cast<KeyNode*>(node)->key(), node});
  833. ++count;
  834. auto* next = node->next;
  835. node->next = nullptr;
  836. node = next;
  837. }
  838. return count;
  839. }
  840. template <typename K>
  841. size_type BucketNumber(const K& k) const {
  842. // We xor the hash value against the random seed so that we effectively
  843. // have a random hash function.
  844. uint64_t h = hash_function()(k) ^ seed_;
  845. // We use the multiplication method to determine the bucket number from
  846. // the hash value. The constant kPhi (suggested by Knuth) is roughly
  847. // (sqrt(5) - 1) / 2 * 2^64.
  848. constexpr uint64_t kPhi = uint64_t{0x9e3779b97f4a7c15};
  849. return ((kPhi * h) >> 32) & (num_buckets_ - 1);
  850. }
  851. void DestroyTree(Tree* tree) {
  852. if (alloc_.arena() == nullptr) {
  853. delete tree;
  854. }
  855. }
  856. // Assumes node_ and m_ are correct and non-null, but other fields may be
  857. // stale. Fix them as needed. Then return true iff node_ points to a
  858. // Node in a list. If false is returned then *it is modified to be
  859. // a valid iterator for node_.
  860. bool revalidate_if_necessary(size_t& bucket_index, KeyNode* node,
  861. TreeIterator* it) const {
  862. // Force bucket_index to be in range.
  863. bucket_index &= (num_buckets_ - 1);
  864. // Common case: the bucket we think is relevant points to `node`.
  865. if (table_[bucket_index] == NodeToTableEntry(node)) return true;
  866. // Less common: the bucket is a linked list with node_ somewhere in it,
  867. // but not at the head.
  868. if (TableEntryIsNonEmptyList(bucket_index)) {
  869. auto* l = TableEntryToNode(table_[bucket_index]);
  870. while ((l = l->next) != nullptr) {
  871. if (l == node) {
  872. return true;
  873. }
  874. }
  875. }
  876. // Well, bucket_index_ still might be correct, but probably
  877. // not. Revalidate just to be sure. This case is rare enough that we
  878. // don't worry about potential optimizations, such as having a custom
  879. // find-like method that compares Node* instead of the key.
  880. auto res = FindHelper(node->key(), it);
  881. bucket_index = res.bucket;
  882. return TableEntryIsList(bucket_index);
  883. }
  884. };
  885. } // namespace internal
  886. // This is the class for Map's internal value_type.
  887. template <typename Key, typename T>
  888. using MapPair = std::pair<const Key, T>;
  889. // Map is an associative container type used to store protobuf map
  890. // fields. Each Map instance may or may not use a different hash function, a
  891. // different iteration order, and so on. E.g., please don't examine
  892. // implementation details to decide if the following would work:
  893. // Map<int, int> m0, m1;
  894. // m0[0] = m1[0] = m0[1] = m1[1] = 0;
  895. // assert(m0.begin()->first == m1.begin()->first); // Bug!
  896. //
  897. // Map's interface is similar to std::unordered_map, except that Map is not
  898. // designed to play well with exceptions.
  899. template <typename Key, typename T>
  900. class Map : private internal::KeyMapBase<internal::KeyForBase<Key>> {
  901. using Base = typename Map::KeyMapBase;
  902. public:
  903. using key_type = Key;
  904. using mapped_type = T;
  905. using init_type = std::pair<Key, T>;
  906. using value_type = MapPair<Key, T>;
  907. using pointer = value_type*;
  908. using const_pointer = const value_type*;
  909. using reference = value_type&;
  910. using const_reference = const value_type&;
  911. using size_type = size_t;
  912. using hasher = typename internal::TransparentSupport<Key>::hash;
  913. constexpr Map() : Base(nullptr) { StaticValidityCheck(); }
  914. explicit Map(Arena* arena) : Base(arena) { StaticValidityCheck(); }
  915. Map(const Map& other) : Map() { insert(other.begin(), other.end()); }
  916. Map(Map&& other) noexcept : Map() {
  917. if (other.arena() != nullptr) {
  918. *this = other;
  919. } else {
  920. swap(other);
  921. }
  922. }
  923. Map& operator=(Map&& other) noexcept {
  924. if (this != &other) {
  925. if (arena() != other.arena()) {
  926. *this = other;
  927. } else {
  928. swap(other);
  929. }
  930. }
  931. return *this;
  932. }
  933. template <class InputIt>
  934. Map(const InputIt& first, const InputIt& last) : Map() {
  935. insert(first, last);
  936. }
  937. ~Map() {
  938. // Fail-safe in case we miss calling this in a constructor. Note: this one
  939. // won't trigger for leaked maps that never get destructed.
  940. StaticValidityCheck();
  941. if (this->alloc_.arena() == nullptr &&
  942. this->num_buckets_ != internal::kGlobalEmptyTableSize) {
  943. clear();
  944. this->DeleteTable(this->table_, this->num_buckets_);
  945. }
  946. }
  947. private:
  948. static_assert(!std::is_const<mapped_type>::value &&
  949. !std::is_const<key_type>::value,
  950. "We do not support const types.");
  951. static_assert(!std::is_volatile<mapped_type>::value &&
  952. !std::is_volatile<key_type>::value,
  953. "We do not support volatile types.");
  954. static_assert(!std::is_pointer<mapped_type>::value &&
  955. !std::is_pointer<key_type>::value,
  956. "We do not support pointer types.");
  957. static_assert(!std::is_reference<mapped_type>::value &&
  958. !std::is_reference<key_type>::value,
  959. "We do not support reference types.");
  960. static constexpr PROTOBUF_ALWAYS_INLINE void StaticValidityCheck() {
  961. static_assert(alignof(internal::NodeBase) >= alignof(mapped_type),
  962. "Alignment of mapped type is too high.");
  963. static_assert(
  964. absl::disjunction<internal::is_supported_integral_type<key_type>,
  965. internal::is_supported_string_type<key_type>,
  966. internal::is_internal_map_key_type<key_type>>::value,
  967. "We only support integer, string, or designated internal key "
  968. "types.");
  969. static_assert(absl::disjunction<
  970. internal::is_supported_scalar_type<mapped_type>,
  971. is_proto_enum<mapped_type>,
  972. internal::is_supported_message_type<mapped_type>,
  973. internal::is_internal_map_value_type<mapped_type>>::value,
  974. "We only support scalar, Message, and designated internal "
  975. "mapped types.");
  976. }
  977. template <typename P>
  978. struct SameAsElementReference
  979. : std::is_same<typename std::remove_cv<
  980. typename std::remove_reference<reference>::type>::type,
  981. typename std::remove_cv<
  982. typename std::remove_reference<P>::type>::type> {};
  983. template <class P>
  984. using RequiresInsertable =
  985. typename std::enable_if<std::is_convertible<P, init_type>::value ||
  986. SameAsElementReference<P>::value,
  987. int>::type;
  988. template <class P>
  989. using RequiresNotInit =
  990. typename std::enable_if<!std::is_same<P, init_type>::value, int>::type;
  991. template <typename LookupKey>
  992. using key_arg = typename internal::TransparentSupport<
  993. key_type>::template key_arg<LookupKey>;
  994. public:
  995. // Iterators
  996. class const_iterator : private Base::KeyIteratorBase {
  997. using BaseIt = typename Base::KeyIteratorBase;
  998. public:
  999. using iterator_category = std::forward_iterator_tag;
  1000. using value_type = typename Map::value_type;
  1001. using difference_type = ptrdiff_t;
  1002. using pointer = const value_type*;
  1003. using reference = const value_type&;
  1004. const_iterator() {}
  1005. const_iterator(const const_iterator&) = default;
  1006. const_iterator& operator=(const const_iterator&) = default;
  1007. reference operator*() const { return static_cast<Node*>(this->node_)->kv; }
  1008. pointer operator->() const { return &(operator*()); }
  1009. const_iterator& operator++() {
  1010. this->PlusPlus();
  1011. return *this;
  1012. }
  1013. const_iterator operator++(int) {
  1014. auto copy = *this;
  1015. this->PlusPlus();
  1016. return copy;
  1017. }
  1018. friend bool operator==(const const_iterator& a, const const_iterator& b) {
  1019. return a.Equals(b);
  1020. }
  1021. friend bool operator!=(const const_iterator& a, const const_iterator& b) {
  1022. return !a.Equals(b);
  1023. }
  1024. private:
  1025. using BaseIt::BaseIt;
  1026. explicit const_iterator(const BaseIt& base) : BaseIt(base) {}
  1027. friend class Map;
  1028. };
  1029. class iterator : private Base::KeyIteratorBase {
  1030. using BaseIt = typename Base::KeyIteratorBase;
  1031. public:
  1032. using iterator_category = std::forward_iterator_tag;
  1033. using value_type = typename Map::value_type;
  1034. using difference_type = ptrdiff_t;
  1035. using pointer = value_type*;
  1036. using reference = value_type&;
  1037. iterator() {}
  1038. iterator(const iterator&) = default;
  1039. iterator& operator=(const iterator&) = default;
  1040. reference operator*() const { return static_cast<Node*>(this->node_)->kv; }
  1041. pointer operator->() const { return &(operator*()); }
  1042. iterator& operator++() {
  1043. this->PlusPlus();
  1044. return *this;
  1045. }
  1046. iterator operator++(int) {
  1047. auto copy = *this;
  1048. this->PlusPlus();
  1049. return copy;
  1050. }
  1051. // Allow implicit conversion to const_iterator.
  1052. operator const_iterator() const { // NOLINT(runtime/explicit)
  1053. return const_iterator(static_cast<const BaseIt&>(*this));
  1054. }
  1055. friend bool operator==(const iterator& a, const iterator& b) {
  1056. return a.Equals(b);
  1057. }
  1058. friend bool operator!=(const iterator& a, const iterator& b) {
  1059. return !a.Equals(b);
  1060. }
  1061. private:
  1062. using BaseIt::BaseIt;
  1063. friend class Map;
  1064. };
  1065. iterator begin() { return iterator(this); }
  1066. iterator end() { return iterator(); }
  1067. const_iterator begin() const { return const_iterator(this); }
  1068. const_iterator end() const { return const_iterator(); }
  1069. const_iterator cbegin() const { return begin(); }
  1070. const_iterator cend() const { return end(); }
  1071. using Base::empty;
  1072. using Base::size;
  1073. // Element access
  1074. template <typename K = key_type>
  1075. T& operator[](const key_arg<K>& key) {
  1076. return try_emplace(key).first->second;
  1077. }
  1078. template <
  1079. typename K = key_type,
  1080. // Disable for integral types to reduce code bloat.
  1081. typename = typename std::enable_if<!std::is_integral<K>::value>::type>
  1082. T& operator[](key_arg<K>&& key) {
  1083. return try_emplace(std::forward<K>(key)).first->second;
  1084. }
  1085. template <typename K = key_type>
  1086. const T& at(const key_arg<K>& key) const {
  1087. const_iterator it = find(key);
  1088. ABSL_CHECK(it != end()) << "key not found: " << static_cast<Key>(key);
  1089. return it->second;
  1090. }
  1091. template <typename K = key_type>
  1092. T& at(const key_arg<K>& key) {
  1093. iterator it = find(key);
  1094. ABSL_CHECK(it != end()) << "key not found: " << static_cast<Key>(key);
  1095. return it->second;
  1096. }
  1097. // Lookup
  1098. template <typename K = key_type>
  1099. size_type count(const key_arg<K>& key) const {
  1100. return find(key) == end() ? 0 : 1;
  1101. }
  1102. template <typename K = key_type>
  1103. const_iterator find(const key_arg<K>& key) const {
  1104. return const_cast<Map*>(this)->find(key);
  1105. }
  1106. template <typename K = key_type>
  1107. iterator find(const key_arg<K>& key) {
  1108. auto res = this->FindHelper(key);
  1109. return iterator(static_cast<Node*>(res.node), this, res.bucket);
  1110. }
  1111. template <typename K = key_type>
  1112. bool contains(const key_arg<K>& key) const {
  1113. return find(key) != end();
  1114. }
  1115. template <typename K = key_type>
  1116. std::pair<const_iterator, const_iterator> equal_range(
  1117. const key_arg<K>& key) const {
  1118. const_iterator it = find(key);
  1119. if (it == end()) {
  1120. return std::pair<const_iterator, const_iterator>(it, it);
  1121. } else {
  1122. const_iterator begin = it++;
  1123. return std::pair<const_iterator, const_iterator>(begin, it);
  1124. }
  1125. }
  1126. template <typename K = key_type>
  1127. std::pair<iterator, iterator> equal_range(const key_arg<K>& key) {
  1128. iterator it = find(key);
  1129. if (it == end()) {
  1130. return std::pair<iterator, iterator>(it, it);
  1131. } else {
  1132. iterator begin = it++;
  1133. return std::pair<iterator, iterator>(begin, it);
  1134. }
  1135. }
  1136. // insert
  1137. template <typename K, typename... Args>
  1138. std::pair<iterator, bool> try_emplace(K&& k, Args&&... args) {
  1139. // Inserts a new element into the container if there is no element with the
  1140. // key in the container.
  1141. // The new element is:
  1142. // (1) Constructed in-place with the given args, if mapped_type is not
  1143. // arena constructible.
  1144. // (2) Constructed in-place with the arena and then assigned with a
  1145. // mapped_type temporary constructed with the given args, otherwise.
  1146. return ArenaAwareTryEmplace(Arena::is_arena_constructable<mapped_type>(),
  1147. std::forward<K>(k),
  1148. std::forward<Args>(args)...);
  1149. }
  1150. std::pair<iterator, bool> insert(init_type&& value) {
  1151. return try_emplace(std::move(value.first), std::move(value.second));
  1152. }
  1153. template <typename P, RequiresInsertable<P> = 0>
  1154. std::pair<iterator, bool> insert(P&& value) {
  1155. return try_emplace(std::forward<P>(value).first,
  1156. std::forward<P>(value).second);
  1157. }
  1158. template <typename... Args>
  1159. std::pair<iterator, bool> emplace(Args&&... args) {
  1160. return EmplaceInternal(Rank0{}, std::forward<Args>(args)...);
  1161. }
  1162. template <class InputIt>
  1163. void insert(InputIt first, InputIt last) {
  1164. for (; first != last; ++first) {
  1165. auto&& pair = *first;
  1166. try_emplace(pair.first, pair.second);
  1167. }
  1168. }
  1169. void insert(std::initializer_list<init_type> values) {
  1170. insert(values.begin(), values.end());
  1171. }
  1172. template <typename P, RequiresNotInit<P> = 0,
  1173. RequiresInsertable<const P&> = 0>
  1174. void insert(std::initializer_list<P> values) {
  1175. insert(values.begin(), values.end());
  1176. }
  1177. // Erase and clear
  1178. template <typename K = key_type>
  1179. size_type erase(const key_arg<K>& key) {
  1180. iterator it = find(key);
  1181. if (it == end()) {
  1182. return 0;
  1183. } else {
  1184. erase(it);
  1185. return 1;
  1186. }
  1187. }
  1188. iterator erase(iterator pos) {
  1189. auto next = std::next(pos);
  1190. ABSL_DCHECK_EQ(pos.m_, static_cast<Base*>(this));
  1191. auto* node = static_cast<Node*>(pos.node_);
  1192. this->erase_no_destroy(pos.bucket_index_, node);
  1193. DestroyNode(node);
  1194. return next;
  1195. }
  1196. void erase(iterator first, iterator last) {
  1197. while (first != last) {
  1198. first = erase(first);
  1199. }
  1200. }
  1201. void clear() {
  1202. for (size_type b = 0; b < this->num_buckets_; b++) {
  1203. internal::NodeBase* node;
  1204. if (this->TableEntryIsNonEmptyList(b)) {
  1205. node = internal::TableEntryToNode(this->table_[b]);
  1206. this->table_[b] = TableEntryPtr{};
  1207. } else if (this->TableEntryIsTree(b)) {
  1208. Tree* tree = internal::TableEntryToTree<Tree>(this->table_[b]);
  1209. this->table_[b] = TableEntryPtr{};
  1210. node = NodeFromTreeIterator(tree->begin());
  1211. this->DestroyTree(tree);
  1212. } else {
  1213. continue;
  1214. }
  1215. do {
  1216. auto* next = node->next;
  1217. DestroyNode(static_cast<Node*>(node));
  1218. node = next;
  1219. } while (node != nullptr);
  1220. }
  1221. this->num_elements_ = 0;
  1222. this->index_of_first_non_null_ = this->num_buckets_;
  1223. }
  1224. // Assign
  1225. Map& operator=(const Map& other) {
  1226. if (this != &other) {
  1227. clear();
  1228. insert(other.begin(), other.end());
  1229. }
  1230. return *this;
  1231. }
  1232. void swap(Map& other) {
  1233. if (arena() == other.arena()) {
  1234. InternalSwap(&other);
  1235. } else {
  1236. // TODO(zuguang): optimize this. The temporary copy can be allocated
  1237. // in the same arena as the other message, and the "other = copy" can
  1238. // be replaced with the fast-path swap above.
  1239. Map copy = *this;
  1240. *this = other;
  1241. other = copy;
  1242. }
  1243. }
  1244. void InternalSwap(Map* other) { this->Swap(other); }
  1245. hasher hash_function() const { return {}; }
  1246. size_t SpaceUsedExcludingSelfLong() const {
  1247. if (empty()) return 0;
  1248. return SpaceUsedInternal() + internal::SpaceUsedInValues(this);
  1249. }
  1250. private:
  1251. struct Rank1 {};
  1252. struct Rank0 : Rank1 {};
  1253. // Linked-list nodes, as one would expect for a chaining hash table.
  1254. struct Node : Base::KeyNode {
  1255. value_type kv;
  1256. };
  1257. using Tree = internal::TreeForMap<Key>;
  1258. using TreeIterator = typename Tree::iterator;
  1259. using TableEntryPtr = internal::TableEntryPtr;
  1260. static Node* NodeFromTreeIterator(TreeIterator it) {
  1261. static_assert(
  1262. PROTOBUF_FIELD_OFFSET(Node, kv.first) == Base::KeyNode::kOffset, "");
  1263. static_assert(alignof(Node) == alignof(internal::NodeBase), "");
  1264. return static_cast<Node*>(it->second);
  1265. }
  1266. void DestroyNode(Node* node) {
  1267. if (this->alloc_.arena() == nullptr) {
  1268. node->kv.first.~key_type();
  1269. node->kv.second.~mapped_type();
  1270. this->DeallocNode(node, sizeof(Node));
  1271. }
  1272. }
  1273. size_t SpaceUsedInternal() const {
  1274. return internal::SpaceUsedInTable<Key>(this->table_, this->num_buckets_,
  1275. this->num_elements_, sizeof(Node));
  1276. }
  1277. // We try to construct `init_type` from `Args` with a fall back to
  1278. // `value_type`. The latter is less desired as it unconditionally makes a copy
  1279. // of `value_type::first`.
  1280. template <typename... Args>
  1281. auto EmplaceInternal(Rank0, Args&&... args) ->
  1282. typename std::enable_if<std::is_constructible<init_type, Args...>::value,
  1283. std::pair<iterator, bool>>::type {
  1284. return insert(init_type(std::forward<Args>(args)...));
  1285. }
  1286. template <typename... Args>
  1287. std::pair<iterator, bool> EmplaceInternal(Rank1, Args&&... args) {
  1288. return insert(value_type(std::forward<Args>(args)...));
  1289. }
  1290. template <typename K, typename... Args>
  1291. std::pair<iterator, bool> TryEmplaceInternal(K&& k, Args&&... args) {
  1292. auto p = this->FindHelper(k);
  1293. // Case 1: key was already present.
  1294. if (p.node != nullptr)
  1295. return std::make_pair(
  1296. iterator(static_cast<Node*>(p.node), this, p.bucket), false);
  1297. // Case 2: insert.
  1298. if (this->ResizeIfLoadIsOutOfRange(this->num_elements_ + 1)) {
  1299. p = this->FindHelper(k);
  1300. }
  1301. const size_type b = p.bucket; // bucket number
  1302. // If K is not key_type, make the conversion to key_type explicit.
  1303. using TypeToInit = typename std::conditional<
  1304. std::is_same<typename std::decay<K>::type, key_type>::value, K&&,
  1305. key_type>::type;
  1306. Node* node = static_cast<Node*>(this->AllocNode(sizeof(Node)));
  1307. // Even when arena is nullptr, CreateInArenaStorage is still used to
  1308. // ensure the arena of submessage will be consistent. Otherwise,
  1309. // submessage may have its own arena when message-owned arena is enabled.
  1310. // Note: This only works if `Key` is not arena constructible.
  1311. Arena::CreateInArenaStorage(const_cast<Key*>(&node->kv.first),
  1312. this->alloc_.arena(),
  1313. static_cast<TypeToInit>(std::forward<K>(k)));
  1314. // Note: if `T` is arena constructible, `Args` needs to be empty.
  1315. Arena::CreateInArenaStorage(&node->kv.second, this->alloc_.arena(),
  1316. std::forward<Args>(args)...);
  1317. this->InsertUnique(b, node);
  1318. ++this->num_elements_;
  1319. return std::make_pair(iterator(node, this, b), true);
  1320. }
  1321. // A helper function to perform an assignment of `mapped_type`.
  1322. // If the first argument is true, then it is a regular assignment.
  1323. // Otherwise, we first create a temporary and then perform an assignment.
  1324. template <typename V>
  1325. static void AssignMapped(std::true_type, mapped_type& mapped, V&& v) {
  1326. mapped = std::forward<V>(v);
  1327. }
  1328. template <typename... Args>
  1329. static void AssignMapped(std::false_type, mapped_type& mapped,
  1330. Args&&... args) {
  1331. mapped = mapped_type(std::forward<Args>(args)...);
  1332. }
  1333. // Case 1: `mapped_type` is arena constructible. A temporary object is
  1334. // created and then (if `Args` are not empty) assigned to a mapped value
  1335. // that was created with the arena.
  1336. template <typename K>
  1337. std::pair<iterator, bool> ArenaAwareTryEmplace(std::true_type, K&& k) {
  1338. // case 1.1: "default" constructed (e.g. from arena only).
  1339. return TryEmplaceInternal(std::forward<K>(k));
  1340. }
  1341. template <typename K, typename... Args>
  1342. std::pair<iterator, bool> ArenaAwareTryEmplace(std::true_type, K&& k,
  1343. Args&&... args) {
  1344. // case 1.2: "default" constructed + copy/move assignment
  1345. auto p = TryEmplaceInternal(std::forward<K>(k));
  1346. if (p.second) {
  1347. AssignMapped(std::is_same<void(typename std::decay<Args>::type...),
  1348. void(mapped_type)>(),
  1349. p.first->second, std::forward<Args>(args)...);
  1350. }
  1351. return p;
  1352. }
  1353. // Case 2: `mapped_type` is not arena constructible. Using in-place
  1354. // construction.
  1355. template <typename... Args>
  1356. std::pair<iterator, bool> ArenaAwareTryEmplace(std::false_type,
  1357. Args&&... args) {
  1358. return TryEmplaceInternal(std::forward<Args>(args)...);
  1359. }
  1360. using Base::arena;
  1361. friend class Arena;
  1362. template <typename, typename>
  1363. friend class internal::TypeDefinedMapFieldBase;
  1364. using InternalArenaConstructable_ = void;
  1365. using DestructorSkippable_ = void;
  1366. template <typename Derived, typename K, typename V,
  1367. internal::WireFormatLite::FieldType key_wire_type,
  1368. internal::WireFormatLite::FieldType value_wire_type>
  1369. friend class internal::MapFieldLite;
  1370. };
  1371. namespace internal {
  1372. template <typename... T>
  1373. PROTOBUF_NOINLINE void MapMergeFrom(Map<T...>& dest, const Map<T...>& src) {
  1374. for (const auto& elem : src) {
  1375. dest[elem.first] = elem.second;
  1376. }
  1377. }
  1378. } // namespace internal
  1379. } // namespace protobuf
  1380. } // namespace google
  1381. #include "google/protobuf/port_undef.inc"
  1382. #endif // GOOGLE_PROTOBUF_MAP_H__