• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
31 #ifndef GOOGLE_PROTOBUF_MAP_H__
32 #define GOOGLE_PROTOBUF_MAP_H__
33 
34 #include <google/protobuf/stubs/hash.h>
35 #include <iterator>
36 #include <limits>  // To support Visual Studio 2008
37 #include <set>
38 #include <utility>
39 
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/arena.h>
42 #include <google/protobuf/generated_enum_util.h>
43 #include <google/protobuf/map_type_handler.h>
44 #include <google/protobuf/message.h>
45 #include <google/protobuf/descriptor.h>
46 #if __cpp_exceptions && LANG_CXX11
47 #include <random>
48 #endif
49 
50 namespace google {
51 namespace protobuf {
52 
53 // The Map and MapIterator types are provided by this header file.
54 // Please avoid using other types defined here, unless they are public
55 // types within Map or MapIterator, such as Map::value_type.
56 template <typename Key, typename T>
57 class Map;
58 
59 class MapIterator;
60 
61 template <typename Enum> struct is_proto_enum;
62 
63 namespace internal {
64 template <typename Key, typename T,
65           WireFormatLite::FieldType key_wire_type,
66           WireFormatLite::FieldType value_wire_type,
67           int default_enum_value>
68 class MapFieldLite;
69 
70 template <typename Key, typename T,
71           WireFormatLite::FieldType key_wire_type,
72           WireFormatLite::FieldType value_wire_type,
73           int default_enum_value>
74 class MapField;
75 
76 template <typename Key, typename T>
77 class TypeDefinedMapFieldBase;
78 
79 class DynamicMapField;
80 
81 class GeneratedMessageReflection;
82 }  // namespace internal
83 
84 #define TYPE_CHECK(EXPECTEDTYPE, METHOD)                        \
85   if (type() != EXPECTEDTYPE) {                                 \
86     GOOGLE_LOG(FATAL)                                                  \
87         << "Protocol Buffer map usage error:\n"                 \
88         << METHOD << " type does not match\n"                   \
89         << "  Expected : "                                      \
90         << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n"   \
91         << "  Actual   : "                                      \
92         << FieldDescriptor::CppTypeName(type());                \
93   }
94 
95 // MapKey is an union type for representing any possible
96 // map key.
97 class LIBPROTOBUF_EXPORT MapKey {
98  public:
MapKey()99   MapKey() : type_(0) {
100   }
MapKey(const MapKey & other)101   MapKey(const MapKey& other) : type_(0) {
102     CopyFrom(other);
103   }
104 
~MapKey()105   ~MapKey() {
106     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
107       delete val_.string_value_;
108     }
109   }
110 
type()111   FieldDescriptor::CppType type() const {
112     if (type_ == 0) {
113       GOOGLE_LOG(FATAL)
114           << "Protocol Buffer map usage error:\n"
115           << "MapKey::type MapKey is not initialized. "
116           << "Call set methods to initialize MapKey.";
117     }
118     return (FieldDescriptor::CppType)type_;
119   }
120 
SetInt64Value(int64 value)121   void SetInt64Value(int64 value) {
122     SetType(FieldDescriptor::CPPTYPE_INT64);
123     val_.int64_value_ = value;
124   }
SetUInt64Value(uint64 value)125   void SetUInt64Value(uint64 value) {
126     SetType(FieldDescriptor::CPPTYPE_UINT64);
127     val_.uint64_value_ = value;
128   }
SetInt32Value(int32 value)129   void SetInt32Value(int32 value) {
130     SetType(FieldDescriptor::CPPTYPE_INT32);
131     val_.int32_value_ = value;
132   }
SetUInt32Value(uint32 value)133   void SetUInt32Value(uint32 value) {
134     SetType(FieldDescriptor::CPPTYPE_UINT32);
135     val_.uint32_value_ = value;
136   }
SetBoolValue(bool value)137   void SetBoolValue(bool value) {
138     SetType(FieldDescriptor::CPPTYPE_BOOL);
139     val_.bool_value_ = value;
140   }
SetStringValue(const string & val)141   void SetStringValue(const string& val) {
142     SetType(FieldDescriptor::CPPTYPE_STRING);
143     *val_.string_value_ = val;
144   }
145 
GetInt64Value()146   int64 GetInt64Value() const {
147     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
148                "MapKey::GetInt64Value");
149     return val_.int64_value_;
150   }
GetUInt64Value()151   uint64 GetUInt64Value() const {
152     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
153                "MapKey::GetUInt64Value");
154     return val_.uint64_value_;
155   }
GetInt32Value()156   int32 GetInt32Value() const {
157     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
158                "MapKey::GetInt32Value");
159     return val_.int32_value_;
160   }
GetUInt32Value()161   uint32 GetUInt32Value() const {
162     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
163                "MapKey::GetUInt32Value");
164     return val_.uint32_value_;
165   }
GetBoolValue()166   bool GetBoolValue() const {
167     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
168                "MapKey::GetBoolValue");
169     return val_.bool_value_;
170   }
GetStringValue()171   const string& GetStringValue() const {
172     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
173                "MapKey::GetStringValue");
174     return *val_.string_value_;
175   }
176 
177   bool operator<(const MapKey& other) const {
178     if (type_ != other.type_) {
179       // We could define a total order that handles this case, but
180       // there currently no need.  So, for now, fail.
181       GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
182     }
183     switch (type()) {
184       case FieldDescriptor::CPPTYPE_DOUBLE:
185       case FieldDescriptor::CPPTYPE_FLOAT:
186       case FieldDescriptor::CPPTYPE_ENUM:
187       case FieldDescriptor::CPPTYPE_MESSAGE:
188         GOOGLE_LOG(FATAL) << "Unsupported";
189         return false;
190       case FieldDescriptor::CPPTYPE_STRING:
191         return *val_.string_value_ < *other.val_.string_value_;
192       case FieldDescriptor::CPPTYPE_INT64:
193         return val_.int64_value_ < other.val_.int64_value_;
194       case FieldDescriptor::CPPTYPE_INT32:
195         return val_.int32_value_ < other.val_.int32_value_;
196       case FieldDescriptor::CPPTYPE_UINT64:
197         return val_.uint64_value_ < other.val_.uint64_value_;
198       case FieldDescriptor::CPPTYPE_UINT32:
199         return val_.uint32_value_ < other.val_.uint32_value_;
200       case FieldDescriptor::CPPTYPE_BOOL:
201         return val_.bool_value_ < other.val_.bool_value_;
202     }
203     return false;
204   }
205 
206   bool operator==(const MapKey& other) const {
207     if (type_ != other.type_) {
208       // To be consistent with operator<, we don't allow this either.
209       GOOGLE_LOG(FATAL) << "Unsupported: type mismatch";
210     }
211     switch (type()) {
212       case FieldDescriptor::CPPTYPE_DOUBLE:
213       case FieldDescriptor::CPPTYPE_FLOAT:
214       case FieldDescriptor::CPPTYPE_ENUM:
215       case FieldDescriptor::CPPTYPE_MESSAGE:
216         GOOGLE_LOG(FATAL) << "Unsupported";
217         break;
218       case FieldDescriptor::CPPTYPE_STRING:
219         return *val_.string_value_ == *other.val_.string_value_;
220       case FieldDescriptor::CPPTYPE_INT64:
221         return val_.int64_value_ == other.val_.int64_value_;
222       case FieldDescriptor::CPPTYPE_INT32:
223         return val_.int32_value_ == other.val_.int32_value_;
224       case FieldDescriptor::CPPTYPE_UINT64:
225         return val_.uint64_value_ == other.val_.uint64_value_;
226       case FieldDescriptor::CPPTYPE_UINT32:
227         return val_.uint32_value_ == other.val_.uint32_value_;
228       case FieldDescriptor::CPPTYPE_BOOL:
229         return val_.bool_value_ == other.val_.bool_value_;
230     }
231     GOOGLE_LOG(FATAL) << "Can't get here.";
232     return false;
233   }
234 
CopyFrom(const MapKey & other)235   void CopyFrom(const MapKey& other) {
236     SetType(other.type());
237     switch (type_) {
238       case FieldDescriptor::CPPTYPE_DOUBLE:
239       case FieldDescriptor::CPPTYPE_FLOAT:
240       case FieldDescriptor::CPPTYPE_ENUM:
241       case FieldDescriptor::CPPTYPE_MESSAGE:
242         GOOGLE_LOG(FATAL) << "Unsupported";
243         break;
244       case FieldDescriptor::CPPTYPE_STRING:
245         *val_.string_value_ = *other.val_.string_value_;
246         break;
247       case FieldDescriptor::CPPTYPE_INT64:
248         val_.int64_value_ = other.val_.int64_value_;
249         break;
250       case FieldDescriptor::CPPTYPE_INT32:
251         val_.int32_value_ = other.val_.int32_value_;
252         break;
253       case FieldDescriptor::CPPTYPE_UINT64:
254         val_.uint64_value_ = other.val_.uint64_value_;
255         break;
256       case FieldDescriptor::CPPTYPE_UINT32:
257         val_.uint32_value_ = other.val_.uint32_value_;
258         break;
259       case FieldDescriptor::CPPTYPE_BOOL:
260         val_.bool_value_ = other.val_.bool_value_;
261         break;
262     }
263   }
264 
265  private:
266   template <typename K, typename V>
267   friend class internal::TypeDefinedMapFieldBase;
268   friend class MapIterator;
269   friend class internal::DynamicMapField;
270 
271   union KeyValue {
KeyValue()272     KeyValue() {}
273     string* string_value_;
274     int64 int64_value_;
275     int32 int32_value_;
276     uint64 uint64_value_;
277     uint32 uint32_value_;
278     bool bool_value_;
279   } val_;
280 
SetType(FieldDescriptor::CppType type)281   void SetType(FieldDescriptor::CppType type) {
282     if (type_ == type) return;
283     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
284       delete val_.string_value_;
285     }
286     type_ = type;
287     if (type_ == FieldDescriptor::CPPTYPE_STRING) {
288       val_.string_value_ = new string;
289     }
290   }
291 
292   // type_ is 0 or a valid FieldDescriptor::CppType.
293   int type_;
294 };
295 
296 // MapValueRef points to a map value.
297 class LIBPROTOBUF_EXPORT MapValueRef {
298  public:
MapValueRef()299   MapValueRef() : data_(NULL), type_(0) {}
300 
SetInt64Value(int64 value)301   void SetInt64Value(int64 value) {
302     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
303                "MapValueRef::SetInt64Value");
304     *reinterpret_cast<int64*>(data_) = value;
305   }
SetUInt64Value(uint64 value)306   void SetUInt64Value(uint64 value) {
307     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
308                "MapValueRef::SetUInt64Value");
309     *reinterpret_cast<uint64*>(data_) = value;
310   }
SetInt32Value(int32 value)311   void SetInt32Value(int32 value) {
312     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
313                "MapValueRef::SetInt32Value");
314     *reinterpret_cast<int32*>(data_) = value;
315   }
SetUInt32Value(uint32 value)316   void SetUInt32Value(uint32 value) {
317     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
318                "MapValueRef::SetUInt32Value");
319     *reinterpret_cast<uint32*>(data_) = value;
320   }
SetBoolValue(bool value)321   void SetBoolValue(bool value) {
322     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
323                "MapValueRef::SetBoolValue");
324     *reinterpret_cast<bool*>(data_) = value;
325   }
326   // TODO(jieluo) - Checks that enum is member.
SetEnumValue(int value)327   void SetEnumValue(int value) {
328     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
329                "MapValueRef::SetEnumValue");
330     *reinterpret_cast<int*>(data_) = value;
331   }
SetStringValue(const string & value)332   void SetStringValue(const string& value) {
333     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
334                "MapValueRef::SetStringValue");
335     *reinterpret_cast<string*>(data_) = value;
336   }
SetFloatValue(float value)337   void SetFloatValue(float value) {
338     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
339                "MapValueRef::SetFloatValue");
340     *reinterpret_cast<float*>(data_) = value;
341   }
SetDoubleValue(double value)342   void SetDoubleValue(double value) {
343     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
344                "MapValueRef::SetDoubleValue");
345     *reinterpret_cast<double*>(data_) = value;
346   }
347 
GetInt64Value()348   int64 GetInt64Value() const {
349     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
350                "MapValueRef::GetInt64Value");
351     return *reinterpret_cast<int64*>(data_);
352   }
GetUInt64Value()353   uint64 GetUInt64Value() const {
354     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
355                "MapValueRef::GetUInt64Value");
356     return *reinterpret_cast<uint64*>(data_);
357   }
GetInt32Value()358   int32 GetInt32Value() const {
359     TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
360                "MapValueRef::GetInt32Value");
361     return *reinterpret_cast<int32*>(data_);
362   }
GetUInt32Value()363   uint32 GetUInt32Value() const {
364     TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
365                "MapValueRef::GetUInt32Value");
366     return *reinterpret_cast<uint32*>(data_);
367   }
GetBoolValue()368   bool GetBoolValue() const {
369     TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
370                "MapValueRef::GetBoolValue");
371     return *reinterpret_cast<bool*>(data_);
372   }
GetEnumValue()373   int GetEnumValue() const {
374     TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
375                "MapValueRef::GetEnumValue");
376     return *reinterpret_cast<int*>(data_);
377   }
GetStringValue()378   const string& GetStringValue() const {
379     TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
380                "MapValueRef::GetStringValue");
381     return *reinterpret_cast<string*>(data_);
382   }
GetFloatValue()383   float GetFloatValue() const {
384     TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
385                "MapValueRef::GetFloatValue");
386     return *reinterpret_cast<float*>(data_);
387   }
GetDoubleValue()388   double GetDoubleValue() const {
389     TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
390                "MapValueRef::GetDoubleValue");
391     return *reinterpret_cast<double*>(data_);
392   }
393 
GetMessageValue()394   const Message& GetMessageValue() const {
395     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
396                "MapValueRef::GetMessageValue");
397     return *reinterpret_cast<Message*>(data_);
398   }
399 
MutableMessageValue()400   Message* MutableMessageValue() {
401     TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
402                "MapValueRef::MutableMessageValue");
403     return reinterpret_cast<Message*>(data_);
404   }
405 
406  private:
407   template <typename K, typename V,
408             internal::WireFormatLite::FieldType key_wire_type,
409             internal::WireFormatLite::FieldType value_wire_type,
410             int default_enum_value>
411   friend class internal::MapField;
412   template <typename K, typename V>
413   friend class internal::TypeDefinedMapFieldBase;
414   friend class MapIterator;
415   friend class internal::GeneratedMessageReflection;
416   friend class internal::DynamicMapField;
417 
SetType(FieldDescriptor::CppType type)418   void SetType(FieldDescriptor::CppType type) {
419     type_ = type;
420   }
421 
type()422   FieldDescriptor::CppType type() const {
423     if (type_ == 0 || data_ == NULL) {
424       GOOGLE_LOG(FATAL)
425           << "Protocol Buffer map usage error:\n"
426           << "MapValueRef::type MapValueRef is not initialized.";
427     }
428     return (FieldDescriptor::CppType)type_;
429   }
SetValue(const void * val)430   void SetValue(const void* val) {
431     data_ = const_cast<void*>(val);
432   }
CopyFrom(const MapValueRef & other)433   void CopyFrom(const MapValueRef& other) {
434     type_ = other.type_;
435     data_ = other.data_;
436   }
437   // Only used in DynamicMapField
DeleteData()438   void DeleteData() {
439     switch (type_) {
440 #define HANDLE_TYPE(CPPTYPE, TYPE)                              \
441       case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: {        \
442         delete reinterpret_cast<TYPE*>(data_);                  \
443         break;                                                  \
444       }
445       HANDLE_TYPE(INT32, int32);
446       HANDLE_TYPE(INT64, int64);
447       HANDLE_TYPE(UINT32, uint32);
448       HANDLE_TYPE(UINT64, uint64);
449       HANDLE_TYPE(DOUBLE, double);
450       HANDLE_TYPE(FLOAT, float);
451       HANDLE_TYPE(BOOL, bool);
452       HANDLE_TYPE(STRING, string);
453       HANDLE_TYPE(ENUM, int32);
454       HANDLE_TYPE(MESSAGE, Message);
455 #undef HANDLE_TYPE
456     }
457   }
458   // data_ point to a map value. MapValueRef does not
459   // own this value.
460   void* data_;
461   // type_ is 0 or a valid FieldDescriptor::CppType.
462   int type_;
463 };
464 
465 #undef TYPE_CHECK
466 
467 // This is the class for google::protobuf::Map's internal value_type. Instead of using
468 // std::pair as value_type, we use this class which provides us more control of
469 // its process of construction and destruction.
470 template <typename Key, typename T>
471 class MapPair {
472  public:
473   typedef const Key first_type;
474   typedef T second_type;
475 
MapPair(const Key & other_first,const T & other_second)476   MapPair(const Key& other_first, const T& other_second)
477       : first(other_first), second(other_second) {}
MapPair(const Key & other_first)478   explicit MapPair(const Key& other_first) : first(other_first), second() {}
MapPair(const MapPair & other)479   MapPair(const MapPair& other)
480       : first(other.first), second(other.second) {}
481 
~MapPair()482   ~MapPair() {}
483 
484   // Implicitly convertible to std::pair of compatible types.
485   template <typename T1, typename T2>
486   operator std::pair<T1, T2>() const {
487     return std::pair<T1, T2>(first, second);
488   }
489 
490   const Key first;
491   T second;
492 
493  private:
494   friend class ::google::protobuf::Arena;
495   friend class Map<Key, T>;
496 };
497 
498 // google::protobuf::Map is an associative container type used to store protobuf map
499 // fields.  Each Map instance may or may not use a different hash function, a
500 // different iteration order, and so on.  E.g., please don't examine
501 // implementation details to decide if the following would work:
502 //  Map<int, int> m0, m1;
503 //  m0[0] = m1[0] = m0[1] = m1[1] = 0;
504 //  assert(m0.begin()->first == m1.begin()->first);  // Bug!
505 //
506 // Map's interface is similar to std::unordered_map, except that Map is not
507 // designed to play well with exceptions.
508 template <typename Key, typename T>
509 class Map {
510  public:
511   typedef Key key_type;
512   typedef T mapped_type;
513   typedef MapPair<Key, T> value_type;
514 
515   typedef value_type* pointer;
516   typedef const value_type* const_pointer;
517   typedef value_type& reference;
518   typedef const value_type& const_reference;
519 
520   typedef size_t size_type;
521   typedef hash<Key> hasher;
522 
523   Map(bool old_style = true)
arena_(NULL)524       : arena_(NULL),
525         default_enum_value_(0),
526         old_style_(old_style) {
527     Init();
528   }
529   explicit Map(Arena* arena, bool old_style = true)
arena_(arena)530       : arena_(arena),
531         default_enum_value_(0),
532         old_style_(old_style) {
533     Init();
534   }
Map(const Map & other)535   Map(const Map& other)
536       : arena_(NULL),
537         default_enum_value_(other.default_enum_value_),
538         old_style_(other.old_style_) {
539     Init();
540     insert(other.begin(), other.end());
541   }
542   template <class InputIt>
543   Map(const InputIt& first, const InputIt& last, bool old_style = true)
arena_(NULL)544       : arena_(NULL),
545         default_enum_value_(0),
546         old_style_(old_style) {
547     Init();
548     insert(first, last);
549   }
550 
~Map()551   ~Map() {
552     clear();
553     if (arena_ == NULL) {
554       if (old_style_)
555         delete deprecated_elements_;
556       else
557         delete elements_;
558     }
559   }
560 
561  private:
Init()562   void Init() {
563     if (old_style_)
564       deprecated_elements_ = Arena::Create<DeprecatedInnerMap>(
565           arena_, 0, hasher(), equal_to<Key>(),
566           MapAllocator<std::pair<const Key, MapPair<Key, T>*> >(arena_));
567     else
568       elements_ =
569           Arena::Create<InnerMap>(arena_, 0, hasher(), Allocator(arena_));
570   }
571 
572   // re-implement std::allocator to use arena allocator for memory allocation.
573   // Used for google::protobuf::Map implementation. Users should not use this class
574   // directly.
575   template <typename U>
576   class MapAllocator {
577    public:
578     typedef U value_type;
579     typedef value_type* pointer;
580     typedef const value_type* const_pointer;
581     typedef value_type& reference;
582     typedef const value_type& const_reference;
583     typedef size_t size_type;
584     typedef ptrdiff_t difference_type;
585 
MapAllocator()586     MapAllocator() : arena_(NULL) {}
MapAllocator(Arena * arena)587     explicit MapAllocator(Arena* arena) : arena_(arena) {}
588     template <typename X>
MapAllocator(const MapAllocator<X> & allocator)589     MapAllocator(const MapAllocator<X>& allocator)
590         : arena_(allocator.arena_) {}
591 
592     pointer allocate(size_type n, const_pointer hint = 0) {
593       // If arena is not given, malloc needs to be called which doesn't
594       // construct element object.
595       if (arena_ == NULL) {
596         return reinterpret_cast<pointer>(malloc(n * sizeof(value_type)));
597       } else {
598         return reinterpret_cast<pointer>(
599             Arena::CreateArray<uint8>(arena_, n * sizeof(value_type)));
600       }
601     }
602 
deallocate(pointer p,size_type n)603     void deallocate(pointer p, size_type n) {
604       if (arena_ == NULL) {
605         free(p);
606       }
607     }
608 
609 #if __cplusplus >= 201103L && !defined(GOOGLE_PROTOBUF_OS_APPLE) && \
610     !defined(GOOGLE_PROTOBUF_OS_NACL) &&                            \
611     !defined(GOOGLE_PROTOBUF_OS_ANDROID) &&                         \
612     !defined(GOOGLE_PROTOBUF_OS_EMSCRIPTEN)
613     template<class NodeType, class... Args>
construct(NodeType * p,Args &&...args)614     void construct(NodeType* p, Args&&... args) {
615       // Clang 3.6 doesn't compile static casting to void* directly. (Issue
616       // #1266) According C++ standard 5.2.9/1: "The static_cast operator shall
617       // not cast away constness". So first the maybe const pointer is casted to
618       // const void* and after the const void* is const casted.
619       new (const_cast<void*>(static_cast<const void*>(p)))
620           NodeType(std::forward<Args>(args)...);
621     }
622 
623     template<class NodeType>
destroy(NodeType * p)624     void destroy(NodeType* p) {
625       p->~NodeType();
626     }
627 #else
construct(pointer p,const_reference t)628     void construct(pointer p, const_reference t) { new (p) value_type(t); }
629 
destroy(pointer p)630     void destroy(pointer p) { p->~value_type(); }
631 #endif
632 
633     template <typename X>
634     struct rebind {
635       typedef MapAllocator<X> other;
636     };
637 
638     template <typename X>
639     bool operator==(const MapAllocator<X>& other) const {
640       return arena_ == other.arena_;
641     }
642 
643     template <typename X>
644     bool operator!=(const MapAllocator<X>& other) const {
645       return arena_ != other.arena_;
646     }
647 
648     // To support Visual Studio 2008
max_size()649     size_type max_size() const {
650       return std::numeric_limits<size_type>::max();
651     }
652 
653    private:
654     typedef void DestructorSkippable_;
655     Arena* const arena_;
656 
657     template <typename X>
658     friend class MapAllocator;
659   };
660 
661   // InnerMap's key type is Key and its value type is value_type*.  We use a
662   // custom class here and for Node, below, to ensure that k_ is at offset 0,
663   // allowing safe conversion from pointer to Node to pointer to Key, and vice
664   // versa when appropriate.
665   class KeyValuePair {
666    public:
KeyValuePair(const Key & k,value_type * v)667     KeyValuePair(const Key& k, value_type* v) : k_(k), v_(v) {}
668 
key()669     const Key& key() const { return k_; }
key()670     Key& key() { return k_; }
value()671     value_type* const value() const { return v_; }
value()672     value_type*& value() { return v_; }
673 
674    private:
675     Key k_;
676     value_type* v_;
677   };
678 
679   typedef MapAllocator<KeyValuePair> Allocator;
680 
681   // InnerMap is a generic hash-based map.  It doesn't contain any
682   // protocol-buffer-specific logic.  It is a chaining hash map with the
683   // additional feature that some buckets can be converted to use an ordered
684   // container.  This ensures O(lg n) bounds on find, insert, and erase, while
685   // avoiding the overheads of ordered containers most of the time.
686   //
687   // The implementation doesn't need the full generality of unordered_map,
688   // and it doesn't have it.  More bells and whistles can be added as needed.
689   // Some implementation details:
690   // 1. The hash function has type hasher and the equality function
691   //    equal_to<Key>.  We inherit from hasher to save space
692   //    (empty-base-class optimization).
693   // 2. The number of buckets is a power of two.
694   // 3. Buckets are converted to trees in pairs: if we convert bucket b then
695   //    buckets b and b^1 will share a tree.  Invariant: buckets b and b^1 have
696   //    the same non-NULL value iff they are sharing a tree.  (An alternative
697   //    implementation strategy would be to have a tag bit per bucket.)
698   // 4. As is typical for hash_map and such, the Keys and Values are always
699   //    stored in linked list nodes.  Pointers to elements are never invalidated
700   //    until the element is deleted.
701   // 5. The trees' payload type is pointer to linked-list node.  Tree-converting
702   //    a bucket doesn't copy Key-Value pairs.
703   // 6. Once we've tree-converted a bucket, it is never converted back. However,
704   //    the items a tree contains may wind up assigned to trees or lists upon a
705   //    rehash.
706   // 7. The code requires no C++ features from C++11 or later.
707   // 8. Mutations to a map do not invalidate the map's iterators, pointers to
708   //    elements, or references to elements.
709   // 9. Except for erase(iterator), any non-const method can reorder iterators.
710   class InnerMap : private hasher {
711    public:
712     typedef value_type* Value;
713 
InnerMap(size_type n,hasher h,Allocator alloc)714     InnerMap(size_type n, hasher h, Allocator alloc)
715         : hasher(h),
716           num_elements_(0),
717           seed_(Seed()),
718           table_(NULL),
719           alloc_(alloc) {
720       n = TableSize(n);
721       table_ = CreateEmptyTable(n);
722       num_buckets_ = index_of_first_non_null_ = n;
723     }
724 
~InnerMap()725     ~InnerMap() {
726       if (table_ != NULL) {
727         clear();
728         Dealloc<void*>(table_, num_buckets_);
729       }
730     }
731 
732    private:
733     enum { kMinTableSize = 8 };
734 
735     // Linked-list nodes, as one would expect for a chaining hash table.
736     struct Node {
737       KeyValuePair kv;
738       Node* next;
739     };
740 
741     // This is safe only if the given pointer is known to point to a Key that is
742     // part of a Node.
NodePtrFromKeyPtr(Key * k)743     static Node* NodePtrFromKeyPtr(Key* k) {
744       return reinterpret_cast<Node*>(k);
745     }
746 
KeyPtrFromNodePtr(Node * node)747     static Key* KeyPtrFromNodePtr(Node* node) { return &node->kv.key(); }
748 
749     // Trees.  The payload type is pointer to Key, so that we can query the tree
750     // with Keys that are not in any particular data structure.  When we insert,
751     // though, the pointer is always pointing to a Key that is inside a Node.
752     struct KeyCompare {
operatorKeyCompare753       bool operator()(const Key* n0, const Key* n1) const { return *n0 < *n1; }
754     };
755     typedef typename Allocator::template rebind<Key*>::other KeyPtrAllocator;
756     typedef std::set<Key*, KeyCompare, KeyPtrAllocator> Tree;
757 
758     // iterator and const_iterator are instantiations of iterator_base.
759     template <typename KeyValueType>
760     class iterator_base {
761      public:
762       typedef KeyValueType& reference;
763       typedef KeyValueType* pointer;
764       typedef typename Tree::iterator TreeIterator;
765 
766       // Invariants:
767       // node_ is always correct. This is handy because the most common
768       // operations are operator* and operator-> and they only use node_.
769       // When node_ is set to a non-NULL value, all the other non-const fields
770       // are updated to be correct also, but those fields can become stale
771       // if the underlying map is modified.  When those fields are needed they
772       // are rechecked, and updated if necessary.
iterator_base()773       iterator_base() : node_(NULL) {}
774 
iterator_base(const InnerMap * m)775       explicit iterator_base(const InnerMap* m) : m_(m) {
776         SearchFrom(m->index_of_first_non_null_);
777       }
778 
779       // Any iterator_base can convert to any other.  This is overkill, and we
780       // rely on the enclosing class to use it wisely.  The standard "iterator
781       // can convert to const_iterator" is OK but the reverse direction is not.
782       template <typename U>
iterator_base(const iterator_base<U> & it)783       explicit iterator_base(const iterator_base<U>& it)
784           : node_(it.node_),
785             m_(it.m_),
786             bucket_index_(it.bucket_index_),
787             tree_it_(it.tree_it_) {}
788 
iterator_base(Node * n,const InnerMap * m,size_type index)789       iterator_base(Node* n, const InnerMap* m, size_type index)
790           : node_(n),
791             m_(m),
792             bucket_index_(index) {}
793 
iterator_base(TreeIterator tree_it,const InnerMap * m,size_type index)794       iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index)
795           : node_(NodePtrFromKeyPtr(*tree_it)),
796             m_(m),
797             bucket_index_(index),
798             tree_it_(tree_it) {
799         // Invariant: iterators that use tree_it_ have an even bucket_index_.
800         GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0);
801       }
802 
803       // Advance through buckets, looking for the first that isn't empty.
804       // If nothing non-empty is found then leave node_ == NULL.
SearchFrom(size_type start_bucket)805       void SearchFrom(size_type start_bucket) {
806         GOOGLE_DCHECK(m_->index_of_first_non_null_ == m_->num_buckets_ ||
807                m_->table_[m_->index_of_first_non_null_] != NULL);
808         node_ = NULL;
809         for (bucket_index_ = start_bucket; bucket_index_ < m_->num_buckets_;
810              bucket_index_++) {
811           if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
812             node_ = static_cast<Node*>(m_->table_[bucket_index_]);
813             break;
814           } else if (m_->TableEntryIsTree(bucket_index_)) {
815             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
816             GOOGLE_DCHECK(!tree->empty());
817             tree_it_ = tree->begin();
818             node_ = NodePtrFromKeyPtr(*tree_it_);
819             break;
820           }
821         }
822       }
823 
824       reference operator*() const { return node_->kv; }
825       pointer operator->() const { return &(operator*()); }
826 
827       friend bool operator==(const iterator_base& a, const iterator_base& b) {
828         return a.node_ == b.node_;
829       }
830       friend bool operator!=(const iterator_base& a, const iterator_base& b) {
831         return a.node_ != b.node_;
832       }
833 
834       iterator_base& operator++() {
835         if (node_->next == NULL) {
836           const bool is_list = revalidate_if_necessary();
837           if (is_list) {
838             SearchFrom(bucket_index_ + 1);
839           } else {
840             GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0);
841             Tree* tree = static_cast<Tree*>(m_->table_[bucket_index_]);
842             if (++tree_it_ == tree->end()) {
843               SearchFrom(bucket_index_ + 2);
844             } else {
845               node_ = NodePtrFromKeyPtr(*tree_it_);
846             }
847           }
848         } else {
849           node_ = node_->next;
850         }
851         return *this;
852       }
853 
854       iterator_base operator++(int /* unused */) {
855         iterator_base tmp = *this;
856         ++*this;
857         return tmp;
858       }
859 
860       // Assumes node_ and m_ are correct and non-NULL, but other fields may be
861       // stale.  Fix them as needed.  Then return true iff node_ points to a
862       // Node in a list.
revalidate_if_necessary()863       bool revalidate_if_necessary() {
864         GOOGLE_DCHECK(node_ != NULL && m_ != NULL);
865         // Force bucket_index_ to be in range.
866         bucket_index_ &= (m_->num_buckets_ - 1);
867         // Common case: the bucket we think is relevant points to node_.
868         if (m_->table_[bucket_index_] == static_cast<void*>(node_))
869           return true;
870         // Less common: the bucket is a linked list with node_ somewhere in it,
871         // but not at the head.
872         if (m_->TableEntryIsNonEmptyList(bucket_index_)) {
873           Node* l = static_cast<Node*>(m_->table_[bucket_index_]);
874           while ((l = l->next) != NULL) {
875             if (l == node_) {
876               return true;
877             }
878           }
879         }
880         // Well, bucket_index_ still might be correct, but probably
881         // not.  Revalidate just to be sure.  This case is rare enough that we
882         // don't worry about potential optimizations, such as having a custom
883         // find-like method that compares Node* instead of const Key&.
884         iterator_base i(m_->find(*KeyPtrFromNodePtr(node_)));
885         bucket_index_ = i.bucket_index_;
886         tree_it_ = i.tree_it_;
887         return m_->TableEntryIsList(bucket_index_);
888       }
889 
890       Node* node_;
891       const InnerMap* m_;
892       size_type bucket_index_;
893       TreeIterator tree_it_;
894     };
895 
896    public:
897     typedef iterator_base<KeyValuePair> iterator;
898     typedef iterator_base<const KeyValuePair> const_iterator;
899 
begin()900     iterator begin() { return iterator(this); }
end()901     iterator end() { return iterator(); }
begin()902     const_iterator begin() const { return const_iterator(this); }
end()903     const_iterator end() const { return const_iterator(); }
904 
clear()905     void clear() {
906       for (size_type b = 0; b < num_buckets_; b++) {
907         if (TableEntryIsNonEmptyList(b)) {
908           Node* node = static_cast<Node*>(table_[b]);
909           table_[b] = NULL;
910           do {
911             Node* next = node->next;
912             DestroyNode(node);
913             node = next;
914           } while (node != NULL);
915         } else if (TableEntryIsTree(b)) {
916           Tree* tree = static_cast<Tree*>(table_[b]);
917           GOOGLE_DCHECK(table_[b] == table_[b + 1] && (b & 1) == 0);
918           table_[b] = table_[b + 1] = NULL;
919           typename Tree::iterator tree_it = tree->begin();
920           do {
921             Node* node = NodePtrFromKeyPtr(*tree_it);
922             typename Tree::iterator next = tree_it;
923             ++next;
924             tree->erase(tree_it);
925             DestroyNode(node);
926             tree_it = next;
927           } while (tree_it != tree->end());
928           DestroyTree(tree);
929           b++;
930         }
931       }
932       num_elements_ = 0;
933       index_of_first_non_null_ = num_buckets_;
934     }
935 
hash_function()936     const hasher& hash_function() const { return *this; }
937 
max_size()938     static size_type max_size() {
939       return static_cast<size_type>(1) << (sizeof(void**) >= 8 ? 60 : 28);
940     }
size()941     size_type size() const { return num_elements_; }
empty()942     bool empty() const { return size() == 0; }
943 
find(const Key & k)944     iterator find(const Key& k) { return iterator(FindHelper(k).first); }
find(const Key & k)945     const_iterator find(const Key& k) const { return FindHelper(k).first; }
946 
947     // In traditional C++ style, this performs "insert if not present."
insert(const KeyValuePair & kv)948     std::pair<iterator, bool> insert(const KeyValuePair& kv) {
949       std::pair<const_iterator, size_type> p = FindHelper(kv.key());
950       // Case 1: key was already present.
951       if (p.first.node_ != NULL)
952         return std::make_pair(iterator(p.first), false);
953       // Case 2: insert.
954       if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
955         p = FindHelper(kv.key());
956       }
957       const size_type b = p.second;  // bucket number
958       Node* node = Alloc<Node>(1);
959       alloc_.construct(&node->kv, kv);
960       iterator result = InsertUnique(b, node);
961       ++num_elements_;
962       return std::make_pair(result, true);
963     }
964 
965     // The same, but if an insertion is necessary then the value portion of the
966     // inserted key-value pair is left uninitialized.
insert(const Key & k)967     std::pair<iterator, bool> insert(const Key& k) {
968       std::pair<const_iterator, size_type> p = FindHelper(k);
969       // Case 1: key was already present.
970       if (p.first.node_ != NULL)
971         return std::make_pair(iterator(p.first), false);
972       // Case 2: insert.
973       if (ResizeIfLoadIsOutOfRange(num_elements_ + 1)) {
974         p = FindHelper(k);
975       }
976       const size_type b = p.second;  // bucket number
977       Node* node = Alloc<Node>(1);
978       typedef typename Allocator::template rebind<Key>::other KeyAllocator;
979       KeyAllocator(alloc_).construct(&node->kv.key(), k);
980       iterator result = InsertUnique(b, node);
981       ++num_elements_;
982       return std::make_pair(result, true);
983     }
984 
985     Value& operator[](const Key& k) {
986       KeyValuePair kv(k, Value());
987       return insert(kv).first->value();
988     }
989 
erase(iterator it)990     void erase(iterator it) {
991       GOOGLE_DCHECK_EQ(it.m_, this);
992       const bool is_list = it.revalidate_if_necessary();
993       size_type b = it.bucket_index_;
994       Node* const item = it.node_;
995       if (is_list) {
996         GOOGLE_DCHECK(TableEntryIsNonEmptyList(b));
997         Node* head = static_cast<Node*>(table_[b]);
998         head = EraseFromLinkedList(item, head);
999         table_[b] = static_cast<void*>(head);
1000       } else {
1001         GOOGLE_DCHECK(TableEntryIsTree(b));
1002         Tree* tree = static_cast<Tree*>(table_[b]);
1003         tree->erase(it.tree_it_);
1004         if (tree->empty()) {
1005           // Force b to be the minimum of b and b ^ 1.  This is important
1006           // only because we want index_of_first_non_null_ to be correct.
1007           b &= ~static_cast<size_type>(1);
1008           DestroyTree(tree);
1009           table_[b] = table_[b + 1] = NULL;
1010         }
1011       }
1012       DestroyNode(item);
1013       --num_elements_;
1014       if (GOOGLE_PREDICT_FALSE(b == index_of_first_non_null_)) {
1015         while (index_of_first_non_null_ < num_buckets_ &&
1016                table_[index_of_first_non_null_] == NULL) {
1017           ++index_of_first_non_null_;
1018         }
1019       }
1020     }
1021 
1022    private:
FindHelper(const Key & k)1023     std::pair<const_iterator, size_type> FindHelper(const Key& k) const {
1024       size_type b = BucketNumber(k);
1025       if (TableEntryIsNonEmptyList(b)) {
1026         Node* node = static_cast<Node*>(table_[b]);
1027         do {
1028           if (IsMatch(*KeyPtrFromNodePtr(node), k)) {
1029             return std::make_pair(const_iterator(node, this, b), b);
1030           } else {
1031             node = node->next;
1032           }
1033         } while (node != NULL);
1034       } else if (TableEntryIsTree(b)) {
1035         GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
1036         b &= ~static_cast<size_t>(1);
1037         Tree* tree = static_cast<Tree*>(table_[b]);
1038         Key* key = const_cast<Key*>(&k);
1039         typename Tree::iterator tree_it = tree->find(key);
1040         if (tree_it != tree->end()) {
1041           return std::make_pair(const_iterator(tree_it, this, b), b);
1042         }
1043       }
1044       return std::make_pair(end(), b);
1045     }
1046 
1047     // Insert the given Node in bucket b.  If that would make bucket b too big,
1048     // and bucket b is not a tree, create a tree for buckets b and b^1 to share.
1049     // Requires count(*KeyPtrFromNodePtr(node)) == 0 and that b is the correct
1050     // bucket.  num_elements_ is not modified.
InsertUnique(size_type b,Node * node)1051     iterator InsertUnique(size_type b, Node* node) {
1052       GOOGLE_DCHECK(index_of_first_non_null_ == num_buckets_ ||
1053              table_[index_of_first_non_null_] != NULL);
1054       // In practice, the code that led to this point may have already
1055       // determined whether we are inserting into an empty list, a short list,
1056       // or whatever.  But it's probably cheap enough to recompute that here;
1057       // it's likely that we're inserting into an empty or short list.
1058       iterator result;
1059       GOOGLE_DCHECK(find(*KeyPtrFromNodePtr(node)) == end());
1060       if (TableEntryIsEmpty(b)) {
1061         result = InsertUniqueInList(b, node);
1062       } else if (TableEntryIsNonEmptyList(b)) {
1063         if (GOOGLE_PREDICT_FALSE(TableEntryIsTooLong(b))) {
1064           TreeConvert(b);
1065           result = InsertUniqueInTree(b, node);
1066           GOOGLE_DCHECK_EQ(result.bucket_index_, b & ~static_cast<size_type>(1));
1067         } else {
1068           // Insert into a pre-existing list.  This case cannot modify
1069           // index_of_first_non_null_, so we skip the code to update it.
1070           return InsertUniqueInList(b, node);
1071         }
1072       } else {
1073         // Insert into a pre-existing tree.  This case cannot modify
1074         // index_of_first_non_null_, so we skip the code to update it.
1075         return InsertUniqueInTree(b, node);
1076       }
1077       index_of_first_non_null_ =
1078           std::min(index_of_first_non_null_, result.bucket_index_);
1079       return result;
1080     }
1081 
1082     // Helper for InsertUnique.  Handles the case where bucket b is a
1083     // not-too-long linked list.
InsertUniqueInList(size_type b,Node * node)1084     iterator InsertUniqueInList(size_type b, Node* node) {
1085       node->next = static_cast<Node*>(table_[b]);
1086       table_[b] = static_cast<void*>(node);
1087       return iterator(node, this, b);
1088     }
1089 
1090     // Helper for InsertUnique.  Handles the case where bucket b points to a
1091     // Tree.
InsertUniqueInTree(size_type b,Node * node)1092     iterator InsertUniqueInTree(size_type b, Node* node) {
1093       GOOGLE_DCHECK_EQ(table_[b], table_[b ^ 1]);
1094       // Maintain the invariant that node->next is NULL for all Nodes in Trees.
1095       node->next = NULL;
1096       return iterator(static_cast<Tree*>(table_[b])
1097                       ->insert(KeyPtrFromNodePtr(node))
1098                       .first,
1099                       this, b & ~static_cast<size_t>(1));
1100     }
1101 
1102     // Returns whether it did resize.  Currently this is only used when
1103     // num_elements_ increases, though it could be used in other situations.
1104     // It checks for load too low as well as load too high: because any number
1105     // of erases can occur between inserts, the load could be as low as 0 here.
1106     // Resizing to a lower size is not always helpful, but failing to do so can
1107     // destroy the expected big-O bounds for some operations. By having the
1108     // policy that sometimes we resize down as well as up, clients can easily
1109     // keep O(size()) = O(number of buckets) if they want that.
ResizeIfLoadIsOutOfRange(size_type new_size)1110     bool ResizeIfLoadIsOutOfRange(size_type new_size) {
1111       const size_type kMaxMapLoadTimes16 = 12;  // controls RAM vs CPU tradeoff
1112       const size_type hi_cutoff = num_buckets_ * kMaxMapLoadTimes16 / 16;
1113       const size_type lo_cutoff = hi_cutoff / 4;
1114       // We don't care how many elements are in trees.  If a lot are,
1115       // we may resize even though there are many empty buckets.  In
1116       // practice, this seems fine.
1117       if (GOOGLE_PREDICT_FALSE(new_size >= hi_cutoff)) {
1118         if (num_buckets_ <= max_size() / 2) {
1119           Resize(num_buckets_ * 2);
1120           return true;
1121         }
1122       } else if (GOOGLE_PREDICT_FALSE(new_size <= lo_cutoff &&
1123                                num_buckets_ > kMinTableSize)) {
1124         size_type lg2_of_size_reduction_factor = 1;
1125         // It's possible we want to shrink a lot here... size() could even be 0.
1126         // So, estimate how much to shrink by making sure we don't shrink so
1127         // much that we would need to grow the table after a few inserts.
1128         const size_type hypothetical_size = new_size * 5 / 4 + 1;
1129         while ((hypothetical_size << lg2_of_size_reduction_factor) <
1130                hi_cutoff) {
1131           ++lg2_of_size_reduction_factor;
1132         }
1133         size_type new_num_buckets = std::max<size_type>(
1134             kMinTableSize, num_buckets_ >> lg2_of_size_reduction_factor);
1135         if (new_num_buckets != num_buckets_) {
1136           Resize(new_num_buckets);
1137           return true;
1138         }
1139       }
1140       return false;
1141     }
1142 
1143     // Resize to the given number of buckets.
Resize(size_t new_num_buckets)1144     void Resize(size_t new_num_buckets) {
1145       GOOGLE_DCHECK_GE(new_num_buckets, kMinTableSize);
1146       void** const old_table = table_;
1147       const size_type old_table_size = num_buckets_;
1148       num_buckets_ = new_num_buckets;
1149       table_ = CreateEmptyTable(num_buckets_);
1150       const size_type start = index_of_first_non_null_;
1151       index_of_first_non_null_ = num_buckets_;
1152       for (size_type i = start; i < old_table_size; i++) {
1153         if (TableEntryIsNonEmptyList(old_table, i)) {
1154           TransferList(old_table, i);
1155         } else if (TableEntryIsTree(old_table, i)) {
1156           TransferTree(old_table, i++);
1157         }
1158       }
1159       Dealloc<void*>(old_table, old_table_size);
1160     }
1161 
TransferList(void * const * table,size_type index)1162     void TransferList(void* const* table, size_type index) {
1163       Node* node = static_cast<Node*>(table[index]);
1164       do {
1165         Node* next = node->next;
1166         InsertUnique(BucketNumber(*KeyPtrFromNodePtr(node)), node);
1167         node = next;
1168       } while (node != NULL);
1169     }
1170 
TransferTree(void * const * table,size_type index)1171     void TransferTree(void* const* table, size_type index) {
1172       Tree* tree = static_cast<Tree*>(table[index]);
1173       typename Tree::iterator tree_it = tree->begin();
1174       do {
1175         Node* node = NodePtrFromKeyPtr(*tree_it);
1176         InsertUnique(BucketNumber(**tree_it), node);
1177       } while (++tree_it != tree->end());
1178       DestroyTree(tree);
1179     }
1180 
EraseFromLinkedList(Node * item,Node * head)1181     Node* EraseFromLinkedList(Node* item, Node* head) {
1182       if (head == item) {
1183         return head->next;
1184       } else {
1185         head->next = EraseFromLinkedList(item, head->next);
1186         return head;
1187       }
1188     }
1189 
TableEntryIsEmpty(size_type b)1190     bool TableEntryIsEmpty(size_type b) const {
1191       return TableEntryIsEmpty(table_, b);
1192     }
TableEntryIsNonEmptyList(size_type b)1193     bool TableEntryIsNonEmptyList(size_type b) const {
1194       return TableEntryIsNonEmptyList(table_, b);
1195     }
TableEntryIsTree(size_type b)1196     bool TableEntryIsTree(size_type b) const {
1197       return TableEntryIsTree(table_, b);
1198     }
TableEntryIsList(size_type b)1199     bool TableEntryIsList(size_type b) const {
1200       return TableEntryIsList(table_, b);
1201     }
TableEntryIsEmpty(void * const * table,size_type b)1202     static bool TableEntryIsEmpty(void* const* table, size_type b) {
1203       return table[b] == NULL;
1204     }
TableEntryIsNonEmptyList(void * const * table,size_type b)1205     static bool TableEntryIsNonEmptyList(void* const* table, size_type b) {
1206       return table[b] != NULL && table[b] != table[b ^ 1];
1207     }
TableEntryIsTree(void * const * table,size_type b)1208     static bool TableEntryIsTree(void* const* table, size_type b) {
1209       return !TableEntryIsEmpty(table, b) &&
1210           !TableEntryIsNonEmptyList(table, b);
1211     }
TableEntryIsList(void * const * table,size_type b)1212     static bool TableEntryIsList(void* const* table, size_type b) {
1213       return !TableEntryIsTree(table, b);
1214     }
1215 
TreeConvert(size_type b)1216     void TreeConvert(size_type b) {
1217       GOOGLE_DCHECK(!TableEntryIsTree(b) && !TableEntryIsTree(b ^ 1));
1218       typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
1219       Tree* tree = tree_allocator.allocate(1);
1220       // We want to use the three-arg form of construct, if it exists, but we
1221       // create a temporary and use the two-arg construct that's known to exist.
1222       // It's clunky, but the compiler should be able to generate more-or-less
1223       // the same code.
1224       tree_allocator.construct(tree,
1225                                Tree(KeyCompare(), KeyPtrAllocator(alloc_)));
1226       // Now the tree is ready to use.
1227       size_type count = CopyListToTree(b, tree) + CopyListToTree(b ^ 1, tree);
1228       GOOGLE_DCHECK_EQ(count, tree->size());
1229       table_[b] = table_[b ^ 1] = static_cast<void*>(tree);
1230     }
1231 
1232     // Copy a linked list in the given bucket to a tree.
1233     // Returns the number of things it copied.
CopyListToTree(size_type b,Tree * tree)1234     size_type CopyListToTree(size_type b, Tree* tree) {
1235       size_type count = 0;
1236       Node* node = static_cast<Node*>(table_[b]);
1237       while (node != NULL) {
1238         tree->insert(KeyPtrFromNodePtr(node));
1239         ++count;
1240         Node* next = node->next;
1241         node->next = NULL;
1242         node = next;
1243       }
1244       return count;
1245     }
1246 
1247     // Return whether table_[b] is a linked list that seems awfully long.
1248     // Requires table_[b] to point to a non-empty linked list.
TableEntryIsTooLong(size_type b)1249     bool TableEntryIsTooLong(size_type b) {
1250       const int kMaxLength = 8;
1251       size_type count = 0;
1252       Node* node = static_cast<Node*>(table_[b]);
1253       do {
1254         ++count;
1255         node = node->next;
1256       } while (node != NULL);
1257       // Invariant: no linked list ever is more than kMaxLength in length.
1258       GOOGLE_DCHECK_LE(count, kMaxLength);
1259       return count >= kMaxLength;
1260     }
1261 
BucketNumber(const Key & k)1262     size_type BucketNumber(const Key& k) const {
1263       // We inherit from hasher, so one-arg operator() provides a hash function.
1264       size_type h = (*const_cast<InnerMap*>(this))(k);
1265       // To help prevent people from making assumptions about the hash function,
1266       // we use the seed differently depending on NDEBUG.  The default hash
1267       // function, the seeding, etc., are all likely to change in the future.
1268 #ifndef NDEBUG
1269       return (h * (seed_ | 1)) & (num_buckets_ - 1);
1270 #else
1271       return (h + seed_) & (num_buckets_ - 1);
1272 #endif
1273     }
1274 
IsMatch(const Key & k0,const Key & k1)1275     bool IsMatch(const Key& k0, const Key& k1) const {
1276       return std::equal_to<Key>()(k0, k1);
1277     }
1278 
1279     // Return a power of two no less than max(kMinTableSize, n).
1280     // Assumes either n < kMinTableSize or n is a power of two.
TableSize(size_type n)1281     size_type TableSize(size_type n) {
1282       return n < kMinTableSize ? kMinTableSize : n;
1283     }
1284 
1285     // Use alloc_ to allocate an array of n objects of type U.
1286     template <typename U>
Alloc(size_type n)1287     U* Alloc(size_type n) {
1288       typedef typename Allocator::template rebind<U>::other alloc_type;
1289       return alloc_type(alloc_).allocate(n);
1290     }
1291 
1292     // Use alloc_ to deallocate an array of n objects of type U.
1293     template <typename U>
Dealloc(U * t,size_type n)1294     void Dealloc(U* t, size_type n) {
1295       typedef typename Allocator::template rebind<U>::other alloc_type;
1296       alloc_type(alloc_).deallocate(t, n);
1297     }
1298 
DestroyNode(Node * node)1299     void DestroyNode(Node* node) {
1300       alloc_.destroy(&node->kv);
1301       Dealloc<Node>(node, 1);
1302     }
1303 
DestroyTree(Tree * tree)1304     void DestroyTree(Tree* tree) {
1305       typename Allocator::template rebind<Tree>::other tree_allocator(alloc_);
1306       tree_allocator.destroy(tree);
1307       tree_allocator.deallocate(tree, 1);
1308     }
1309 
CreateEmptyTable(size_type n)1310     void** CreateEmptyTable(size_type n) {
1311       GOOGLE_DCHECK(n >= kMinTableSize);
1312       GOOGLE_DCHECK_EQ(n & (n - 1), 0);
1313       void** result = Alloc<void*>(n);
1314       memset(result, 0, n * sizeof(result[0]));
1315       return result;
1316     }
1317 
1318     // Return a randomish value.
Seed()1319     size_type Seed() const {
1320       // random_device can throw, so avoid it unless we are compiling with
1321       // exceptions enabled.
1322 #if __cpp_exceptions && LANG_CXX11
1323       try {
1324         std::random_device rd;
1325         std::knuth_b knuth(rd());
1326         std::uniform_int_distribution<size_type> u;
1327         return u(knuth);
1328       } catch (...) { }
1329 #endif
1330       size_type s = static_cast<size_type>(reinterpret_cast<uintptr_t>(this));
1331 #if defined(__x86_64__) && defined(__GNUC__)
1332       uint32 hi, lo;
1333       asm("rdtsc" : "=a" (lo), "=d" (hi));
1334       s += ((static_cast<uint64>(hi) << 32) | lo);
1335 #endif
1336       return s;
1337     }
1338 
1339     size_type num_elements_;
1340     size_type num_buckets_;
1341     size_type seed_;
1342     size_type index_of_first_non_null_;
1343     void** table_;  // an array with num_buckets_ entries
1344     Allocator alloc_;
1345     GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap);
1346   };  // end of class InnerMap
1347 
1348   typedef hash_map<Key, value_type*, hash<Key>, equal_to<Key>,
1349                    MapAllocator<std::pair<const Key, MapPair<Key, T>*> > >
1350       DeprecatedInnerMap;
1351 
1352  public:
1353   // Iterators
1354   class iterator_base {
1355    public:
1356     // We support "old style" and "new style" iterators for now. This is
1357     // temporary.  Also, for "iterator()" we have an unknown category.
1358     // TODO(gpike): get rid of this.
1359     enum IteratorStyle { kUnknown, kOld, kNew };
iterator_base(IteratorStyle style)1360     explicit iterator_base(IteratorStyle style) : iterator_style_(style) {}
1361 
OldStyle()1362     bool OldStyle() const {
1363       GOOGLE_DCHECK_NE(iterator_style_, kUnknown);
1364       return iterator_style_ == kOld;
1365     }
UnknownStyle()1366     bool UnknownStyle() const {
1367       return iterator_style_ == kUnknown;
1368     }
SameStyle(const iterator_base & other)1369     bool SameStyle(const iterator_base& other) const {
1370       return iterator_style_ == other.iterator_style_;
1371     }
1372 
1373    private:
1374     IteratorStyle iterator_style_;
1375   };
1376 
1377   class const_iterator
1378       : private iterator_base,
1379         public std::iterator<std::forward_iterator_tag, value_type, ptrdiff_t,
1380                              const value_type*, const value_type&> {
1381     typedef typename InnerMap::const_iterator InnerIt;
1382     typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt;
1383 
1384    public:
const_iterator()1385     const_iterator() : iterator_base(iterator_base::kUnknown) {}
const_iterator(const DeprecatedInnerIt & dit)1386     explicit const_iterator(const DeprecatedInnerIt& dit)
1387         : iterator_base(iterator_base::kOld), dit_(dit) {}
const_iterator(const InnerIt & it)1388     explicit const_iterator(const InnerIt& it)
1389         : iterator_base(iterator_base::kNew), it_(it) {}
1390 
const_iterator(const const_iterator & other)1391     const_iterator(const const_iterator& other)
1392         : iterator_base(other), it_(other.it_), dit_(other.dit_) {}
1393 
1394     const_reference operator*() const {
1395       return this->OldStyle() ? *dit_->second : *it_->value();
1396     }
1397     const_pointer operator->() const { return &(operator*()); }
1398 
1399     const_iterator& operator++() {
1400       if (this->OldStyle())
1401         ++dit_;
1402       else
1403         ++it_;
1404       return *this;
1405     }
1406     const_iterator operator++(int) {
1407       return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++);
1408     }
1409 
1410     friend bool operator==(const const_iterator& a, const const_iterator& b) {
1411       if (!a.SameStyle(b)) return false;
1412       if (a.UnknownStyle()) return true;
1413       return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_);
1414     }
1415     friend bool operator!=(const const_iterator& a, const const_iterator& b) {
1416       return !(a == b);
1417     }
1418 
1419    private:
1420     InnerIt it_;
1421     DeprecatedInnerIt dit_;
1422   };
1423 
1424   class iterator : private iterator_base,
1425                    public std::iterator<std::forward_iterator_tag, value_type> {
1426     typedef typename InnerMap::iterator InnerIt;
1427     typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt;
1428 
1429    public:
iterator()1430     iterator() : iterator_base(iterator_base::kUnknown) {}
iterator(const DeprecatedInnerIt & dit)1431     explicit iterator(const DeprecatedInnerIt& dit)
1432         : iterator_base(iterator_base::kOld), dit_(dit) {}
iterator(const InnerIt & it)1433     explicit iterator(const InnerIt& it)
1434         : iterator_base(iterator_base::kNew), it_(it) {}
1435 
1436     reference operator*() const {
1437       return this->OldStyle() ? *dit_->second : *it_->value();
1438     }
1439     pointer operator->() const { return &(operator*()); }
1440 
1441     iterator& operator++() {
1442       if (this->OldStyle())
1443         ++dit_;
1444       else
1445         ++it_;
1446       return *this;
1447     }
1448     iterator operator++(int) {
1449       return this->OldStyle() ? iterator(dit_++) : iterator(it_++);
1450     }
1451 
1452     // Allow implicit conversion to const_iterator.
const_iterator()1453     operator const_iterator() const {
1454       return this->OldStyle() ?
1455           const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) :
1456           const_iterator(typename InnerMap::const_iterator(it_));
1457     }
1458 
1459     friend bool operator==(const iterator& a, const iterator& b) {
1460       if (!a.SameStyle(b)) return false;
1461       if (a.UnknownStyle()) return true;
1462       return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_;
1463     }
1464     friend bool operator!=(const iterator& a, const iterator& b) {
1465       return !(a == b);
1466     }
1467 
1468    private:
1469     friend class Map;
1470 
1471     InnerIt it_;
1472     DeprecatedInnerIt dit_;
1473   };
1474 
begin()1475   iterator begin() {
1476     return old_style_ ? iterator(deprecated_elements_->begin())
1477                       : iterator(elements_->begin());
1478   }
end()1479   iterator end() {
1480     return old_style_ ? iterator(deprecated_elements_->end())
1481                       : iterator(elements_->end());
1482   }
begin()1483   const_iterator begin() const {
1484     return old_style_ ? const_iterator(deprecated_elements_->begin())
1485                       : const_iterator(iterator(elements_->begin()));
1486   }
end()1487   const_iterator end() const {
1488     return old_style_ ? const_iterator(deprecated_elements_->end())
1489                       : const_iterator(iterator(elements_->end()));
1490   }
cbegin()1491   const_iterator cbegin() const { return begin(); }
cend()1492   const_iterator cend() const { return end(); }
1493 
1494   // Capacity
size()1495   size_type size() const {
1496     return old_style_ ? deprecated_elements_->size() : elements_->size();
1497   }
empty()1498   bool empty() const { return size() == 0; }
1499 
1500   // Element access
1501   T& operator[](const key_type& key) {
1502     value_type** value =
1503         old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key];
1504     if (*value == NULL) {
1505       *value = CreateValueTypeInternal(key);
1506       internal::MapValueInitializer<google::protobuf::is_proto_enum<T>::value,
1507                                     T>::Initialize((*value)->second,
1508                                                    default_enum_value_);
1509     }
1510     return (*value)->second;
1511   }
at(const key_type & key)1512   const T& at(const key_type& key) const {
1513     const_iterator it = find(key);
1514     GOOGLE_CHECK(it != end());
1515     return it->second;
1516   }
at(const key_type & key)1517   T& at(const key_type& key) {
1518     iterator it = find(key);
1519     GOOGLE_CHECK(it != end());
1520     return it->second;
1521   }
1522 
1523   // Lookup
count(const key_type & key)1524   size_type count(const key_type& key) const {
1525     if (find(key) != end()) assert(key == find(key)->first);
1526     return find(key) == end() ? 0 : 1;
1527   }
find(const key_type & key)1528   const_iterator find(const key_type& key) const {
1529     return old_style_ ? const_iterator(deprecated_elements_->find(key))
1530         : const_iterator(iterator(elements_->find(key)));
1531   }
find(const key_type & key)1532   iterator find(const key_type& key) {
1533     return old_style_ ? iterator(deprecated_elements_->find(key))
1534                       : iterator(elements_->find(key));
1535   }
equal_range(const key_type & key)1536   std::pair<const_iterator, const_iterator> equal_range(
1537       const key_type& key) const {
1538     const_iterator it = find(key);
1539     if (it == end()) {
1540       return std::pair<const_iterator, const_iterator>(it, it);
1541     } else {
1542       const_iterator begin = it++;
1543       return std::pair<const_iterator, const_iterator>(begin, it);
1544     }
1545   }
equal_range(const key_type & key)1546   std::pair<iterator, iterator> equal_range(const key_type& key) {
1547     iterator it = find(key);
1548     if (it == end()) {
1549       return std::pair<iterator, iterator>(it, it);
1550     } else {
1551       iterator begin = it++;
1552       return std::pair<iterator, iterator>(begin, it);
1553     }
1554   }
1555 
1556   // insert
insert(const value_type & value)1557   std::pair<iterator, bool> insert(const value_type& value) {
1558     if (old_style_) {
1559       iterator it = find(value.first);
1560       if (it != end()) {
1561         return std::pair<iterator, bool>(it, false);
1562       } else {
1563         return std::pair<iterator, bool>(
1564             iterator(deprecated_elements_->insert(std::pair<Key, value_type*>(
1565                 value.first, CreateValueTypeInternal(value))).first), true);
1566       }
1567     } else {
1568       std::pair<typename InnerMap::iterator, bool> p =
1569           elements_->insert(value.first);
1570       if (p.second) {
1571         p.first->value() = CreateValueTypeInternal(value);
1572       }
1573       return std::pair<iterator, bool>(iterator(p.first), p.second);
1574     }
1575   }
1576   template <class InputIt>
insert(InputIt first,InputIt last)1577   void insert(InputIt first, InputIt last) {
1578     for (InputIt it = first; it != last; ++it) {
1579       iterator exist_it = find(it->first);
1580       if (exist_it == end()) {
1581         operator[](it->first) = it->second;
1582       }
1583     }
1584   }
1585 
1586   // Erase and clear
erase(const key_type & key)1587   size_type erase(const key_type& key) {
1588     iterator it = find(key);
1589     if (it == end()) {
1590       return 0;
1591     } else {
1592       erase(it);
1593       return 1;
1594     }
1595   }
erase(iterator pos)1596   iterator erase(iterator pos) {
1597     if (arena_ == NULL) delete pos.operator->();
1598     iterator i = pos++;
1599     if (old_style_)
1600       deprecated_elements_->erase(i.dit_);
1601     else
1602       elements_->erase(i.it_);
1603     return pos;
1604   }
erase(iterator first,iterator last)1605   void erase(iterator first, iterator last) {
1606     while (first != last) {
1607       first = erase(first);
1608     }
1609   }
clear()1610   void clear() { erase(begin(), end()); }
1611 
1612   // Assign
1613   Map& operator=(const Map& other) {
1614     if (this != &other) {
1615       clear();
1616       insert(other.begin(), other.end());
1617     }
1618     return *this;
1619   }
1620 
1621   // Access to hasher.  Currently this returns a copy, but it may
1622   // be modified to return a const reference in the future.
hash_function()1623   hasher hash_function() const {
1624     return old_style_ ? deprecated_elements_->hash_function()
1625                       : elements_->hash_function();
1626   }
1627 
1628  private:
1629   // Set default enum value only for proto2 map field whose value is enum type.
SetDefaultEnumValue(int default_enum_value)1630   void SetDefaultEnumValue(int default_enum_value) {
1631     default_enum_value_ = default_enum_value;
1632   }
1633 
CreateValueTypeInternal(const Key & key)1634   value_type* CreateValueTypeInternal(const Key& key) {
1635     if (arena_ == NULL) {
1636       return new value_type(key);
1637     } else {
1638       value_type* value = reinterpret_cast<value_type*>(
1639           Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
1640       Arena::CreateInArenaStorage(const_cast<Key*>(&value->first), arena_);
1641       Arena::CreateInArenaStorage(&value->second, arena_);
1642       const_cast<Key&>(value->first) = key;
1643       return value;
1644     }
1645   }
1646 
CreateValueTypeInternal(const value_type & value)1647   value_type* CreateValueTypeInternal(const value_type& value) {
1648     if (arena_ == NULL) {
1649       return new value_type(value);
1650     } else {
1651       value_type* p = reinterpret_cast<value_type*>(
1652           Arena::CreateArray<uint8>(arena_, sizeof(value_type)));
1653       Arena::CreateInArenaStorage(const_cast<Key*>(&p->first), arena_);
1654       Arena::CreateInArenaStorage(&p->second, arena_);
1655       const_cast<Key&>(p->first) = value.first;
1656       p->second = value.second;
1657       return p;
1658     }
1659   }
1660 
1661   Arena* arena_;
1662   int default_enum_value_;
1663   // The following is a tagged union because we support two map styles
1664   // for now.
1665   // TODO(gpike): get rid of the old style.
1666   const bool old_style_;
1667   union {
1668     InnerMap* elements_;
1669     DeprecatedInnerMap* deprecated_elements_;
1670   };
1671 
1672   friend class ::google::protobuf::Arena;
1673   typedef void InternalArenaConstructable_;
1674   typedef void DestructorSkippable_;
1675   template <typename K, typename V,
1676             internal::WireFormatLite::FieldType key_wire_type,
1677             internal::WireFormatLite::FieldType value_wire_type,
1678             int default_enum_value>
1679   friend class internal::MapFieldLite;
1680 };
1681 
1682 }  // namespace protobuf
1683 }  // namespace google
1684 
1685 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
1686 template<>
1687 struct hash<google::protobuf::MapKey> {
1688   size_t
1689   operator()(const google::protobuf::MapKey& map_key) const {
1690     switch (map_key.type()) {
1691       case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
1692       case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
1693       case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
1694       case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
1695         GOOGLE_LOG(FATAL) << "Unsupported";
1696         break;
1697       case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
1698         return hash<string>()(map_key.GetStringValue());
1699       case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
1700         return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
1701       case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
1702         return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
1703       case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
1704         return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
1705       case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
1706         return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
1707       case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
1708         return hash<bool>()(map_key.GetBoolValue());
1709     }
1710     GOOGLE_LOG(FATAL) << "Can't get here.";
1711     return 0;
1712   }
1713   bool
1714   operator()(const google::protobuf::MapKey& map_key1,
1715              const google::protobuf::MapKey& map_key2) const {
1716     return map_key1 < map_key2;
1717   }
1718 };
1719 GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
1720 
1721 #endif  // GOOGLE_PROTOBUF_MAP_H__
1722