map_field.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  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. #include <google/protobuf/map_field.h>
  31. #include <google/protobuf/map_field_inl.h>
  32. #include <vector>
  33. namespace google {
  34. namespace protobuf {
  35. namespace internal {
  36. MapFieldBase::~MapFieldBase() {
  37. if (repeated_field_ != NULL && arena_ == NULL) delete repeated_field_;
  38. }
  39. const RepeatedPtrFieldBase& MapFieldBase::GetRepeatedField() const {
  40. SyncRepeatedFieldWithMap();
  41. return *reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
  42. repeated_field_);
  43. }
  44. RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() {
  45. SyncRepeatedFieldWithMap();
  46. SetRepeatedDirty();
  47. return reinterpret_cast<::google::protobuf::internal::RepeatedPtrFieldBase*>(
  48. repeated_field_);
  49. }
  50. size_t MapFieldBase::SpaceUsedExcludingSelfLong() const {
  51. mutex_.Lock();
  52. size_t size = SpaceUsedExcludingSelfNoLock();
  53. mutex_.Unlock();
  54. return size;
  55. }
  56. size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const {
  57. if (repeated_field_ != NULL) {
  58. return repeated_field_->SpaceUsedExcludingSelfLong();
  59. } else {
  60. return 0;
  61. }
  62. }
  63. bool MapFieldBase::IsMapValid() const {
  64. // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get
  65. // executed before state_ is checked.
  66. int state = state_.load(std::memory_order_acquire);
  67. return state != STATE_MODIFIED_REPEATED;
  68. }
  69. bool MapFieldBase::IsRepeatedFieldValid() const {
  70. int state = state_.load(std::memory_order_acquire);
  71. return state != STATE_MODIFIED_MAP;
  72. }
  73. void MapFieldBase::SetMapDirty() {
  74. // These are called by (non-const) mutator functions. So by our API it's the
  75. // callers responsibility to have these calls properly ordered.
  76. state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
  77. }
  78. void MapFieldBase::SetRepeatedDirty() {
  79. // These are called by (non-const) mutator functions. So by our API it's the
  80. // callers responsibility to have these calls properly ordered.
  81. state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
  82. }
  83. void* MapFieldBase::MutableRepeatedPtrField() const { return repeated_field_; }
  84. void MapFieldBase::SyncRepeatedFieldWithMap() const {
  85. // acquire here matches with release below to ensure that we can only see a
  86. // value of CLEAN after all previous changes have been synced.
  87. if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_MAP) {
  88. mutex_.Lock();
  89. // Double check state, because another thread may have seen the same state
  90. // and done the synchronization before the current thread.
  91. if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_MAP) {
  92. SyncRepeatedFieldWithMapNoLock();
  93. state_.store(CLEAN, std::memory_order_release);
  94. }
  95. mutex_.Unlock();
  96. }
  97. }
  98. void MapFieldBase::SyncRepeatedFieldWithMapNoLock() const {
  99. if (repeated_field_ == NULL) {
  100. repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >(arena_);
  101. }
  102. }
  103. void MapFieldBase::SyncMapWithRepeatedField() const {
  104. // acquire here matches with release below to ensure that we can only see a
  105. // value of CLEAN after all previous changes have been synced.
  106. if (state_.load(std::memory_order_acquire) == STATE_MODIFIED_REPEATED) {
  107. mutex_.Lock();
  108. // Double check state, because another thread may have seen the same state
  109. // and done the synchronization before the current thread.
  110. if (state_.load(std::memory_order_relaxed) == STATE_MODIFIED_REPEATED) {
  111. SyncMapWithRepeatedFieldNoLock();
  112. state_.store(CLEAN, std::memory_order_release);
  113. }
  114. mutex_.Unlock();
  115. }
  116. }
  117. // ------------------DynamicMapField------------------
  118. DynamicMapField::DynamicMapField(const Message* default_entry)
  119. : default_entry_(default_entry) {
  120. }
  121. DynamicMapField::DynamicMapField(const Message* default_entry,
  122. Arena* arena)
  123. : TypeDefinedMapFieldBase<MapKey, MapValueRef>(arena),
  124. map_(arena),
  125. default_entry_(default_entry) {
  126. }
  127. DynamicMapField::~DynamicMapField() {
  128. // DynamicMapField owns map values. Need to delete them before clearing
  129. // the map.
  130. for (Map<MapKey, MapValueRef>::iterator iter = map_.begin();
  131. iter != map_.end(); ++iter) {
  132. iter->second.DeleteData();
  133. }
  134. map_.clear();
  135. }
  136. int DynamicMapField::size() const {
  137. return GetMap().size();
  138. }
  139. bool DynamicMapField::ContainsMapKey(
  140. const MapKey& map_key) const {
  141. const Map<MapKey, MapValueRef>& map = GetMap();
  142. Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key);
  143. return iter != map.end();
  144. }
  145. bool DynamicMapField::InsertOrLookupMapValue(
  146. const MapKey& map_key, MapValueRef* val) {
  147. // Always use mutable map because users may change the map value by
  148. // MapValueRef.
  149. Map<MapKey, MapValueRef>* map = MutableMap();
  150. Map<MapKey, MapValueRef>::iterator iter = map->find(map_key);
  151. if (iter == map->end()) {
  152. // Insert
  153. MapValueRef& map_val = (*map)[map_key];
  154. const FieldDescriptor* val_des =
  155. default_entry_->GetDescriptor()->FindFieldByName("value");
  156. map_val.SetType(val_des->cpp_type());
  157. // Allocate memory for the inserted MapValueRef, and initialize to
  158. // default value.
  159. switch (val_des->cpp_type()) {
  160. #define HANDLE_TYPE(CPPTYPE, TYPE) \
  161. case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
  162. TYPE * value = new TYPE(); \
  163. map_val.SetValue(value); \
  164. break; \
  165. }
  166. HANDLE_TYPE(INT32, int32);
  167. HANDLE_TYPE(INT64, int64);
  168. HANDLE_TYPE(UINT32, uint32);
  169. HANDLE_TYPE(UINT64, uint64);
  170. HANDLE_TYPE(DOUBLE, double);
  171. HANDLE_TYPE(FLOAT, float);
  172. HANDLE_TYPE(BOOL, bool);
  173. HANDLE_TYPE(STRING, string);
  174. HANDLE_TYPE(ENUM, int32);
  175. #undef HANDLE_TYPE
  176. case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
  177. const Message& message = default_entry_->GetReflection()->GetMessage(
  178. *default_entry_, val_des);
  179. Message* value = message.New();
  180. map_val.SetValue(value);
  181. break;
  182. }
  183. }
  184. val->CopyFrom(map_val);
  185. return true;
  186. }
  187. // map_key is already in the map. Make sure (*map)[map_key] is not called.
  188. // [] may reorder the map and iterators.
  189. val->CopyFrom(iter->second);
  190. return false;
  191. }
  192. bool DynamicMapField::DeleteMapValue(const MapKey& map_key) {
  193. MapFieldBase::SyncMapWithRepeatedField();
  194. Map<MapKey, MapValueRef>::iterator iter = map_.find(map_key);
  195. if (iter == map_.end()) {
  196. return false;
  197. }
  198. // Set map dirty only if the delete is successful.
  199. MapFieldBase::SetMapDirty();
  200. iter->second.DeleteData();
  201. map_.erase(iter);
  202. return true;
  203. }
  204. const Map<MapKey, MapValueRef>& DynamicMapField::GetMap() const {
  205. MapFieldBase::SyncMapWithRepeatedField();
  206. return map_;
  207. }
  208. Map<MapKey, MapValueRef>* DynamicMapField::MutableMap() {
  209. MapFieldBase::SyncMapWithRepeatedField();
  210. MapFieldBase::SetMapDirty();
  211. return &map_;
  212. }
  213. void DynamicMapField::SetMapIteratorValue(MapIterator* map_iter) const {
  214. Map<MapKey, MapValueRef>::const_iterator iter =
  215. TypeDefinedMapFieldBase<MapKey, MapValueRef>::InternalGetIterator(
  216. map_iter);
  217. if (iter == map_.end()) return;
  218. map_iter->key_.CopyFrom(iter->first);
  219. map_iter->value_.CopyFrom(iter->second);
  220. }
  221. void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const {
  222. const Reflection* reflection = default_entry_->GetReflection();
  223. const FieldDescriptor* key_des =
  224. default_entry_->GetDescriptor()->FindFieldByName("key");
  225. const FieldDescriptor* val_des =
  226. default_entry_->GetDescriptor()->FindFieldByName("value");
  227. if (MapFieldBase::repeated_field_ == NULL) {
  228. if (MapFieldBase::arena_ == NULL) {
  229. MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>();
  230. } else {
  231. MapFieldBase::repeated_field_ =
  232. Arena::CreateMessage<RepeatedPtrField<Message> >(
  233. MapFieldBase::arena_);
  234. }
  235. }
  236. MapFieldBase::repeated_field_->Clear();
  237. for (Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
  238. it != map_.end(); ++it) {
  239. Message* new_entry = default_entry_->New();
  240. MapFieldBase::repeated_field_->AddAllocated(new_entry);
  241. const MapKey& map_key = it->first;
  242. switch (key_des->cpp_type()) {
  243. case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
  244. reflection->SetString(new_entry, key_des, map_key.GetStringValue());
  245. break;
  246. case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
  247. reflection->SetInt64(new_entry, key_des, map_key.GetInt64Value());
  248. break;
  249. case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
  250. reflection->SetInt32(new_entry, key_des, map_key.GetInt32Value());
  251. break;
  252. case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
  253. reflection->SetUInt64(new_entry, key_des, map_key.GetUInt64Value());
  254. break;
  255. case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
  256. reflection->SetUInt32(new_entry, key_des, map_key.GetUInt32Value());
  257. break;
  258. case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
  259. reflection->SetBool(new_entry, key_des, map_key.GetBoolValue());
  260. break;
  261. case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
  262. case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
  263. case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
  264. case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
  265. GOOGLE_LOG(FATAL) << "Can't get here.";
  266. break;
  267. }
  268. const MapValueRef& map_val = it->second;
  269. switch (val_des->cpp_type()) {
  270. case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
  271. reflection->SetString(new_entry, val_des, map_val.GetStringValue());
  272. break;
  273. case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
  274. reflection->SetInt64(new_entry, val_des, map_val.GetInt64Value());
  275. break;
  276. case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
  277. reflection->SetInt32(new_entry, val_des, map_val.GetInt32Value());
  278. break;
  279. case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
  280. reflection->SetUInt64(new_entry, val_des, map_val.GetUInt64Value());
  281. break;
  282. case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
  283. reflection->SetUInt32(new_entry, val_des, map_val.GetUInt32Value());
  284. break;
  285. case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
  286. reflection->SetBool(new_entry, val_des, map_val.GetBoolValue());
  287. break;
  288. case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
  289. reflection->SetDouble(new_entry, val_des, map_val.GetDoubleValue());
  290. break;
  291. case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
  292. reflection->SetFloat(new_entry, val_des, map_val.GetFloatValue());
  293. break;
  294. case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
  295. reflection->SetEnumValue(new_entry, val_des, map_val.GetEnumValue());
  296. break;
  297. case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
  298. const Message& message = map_val.GetMessageValue();
  299. reflection->MutableMessage(new_entry, val_des)->CopyFrom(message);
  300. break;
  301. }
  302. }
  303. }
  304. }
  305. void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const {
  306. Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_;
  307. const Reflection* reflection = default_entry_->GetReflection();
  308. const FieldDescriptor* key_des =
  309. default_entry_->GetDescriptor()->FindFieldByName("key");
  310. const FieldDescriptor* val_des =
  311. default_entry_->GetDescriptor()->FindFieldByName("value");
  312. // DynamicMapField owns map values. Need to delete them before clearing
  313. // the map.
  314. for (Map<MapKey, MapValueRef>::iterator iter = map->begin();
  315. iter != map->end(); ++iter) {
  316. iter->second.DeleteData();
  317. }
  318. map->clear();
  319. for (RepeatedPtrField<Message>::iterator it =
  320. MapFieldBase::repeated_field_->begin();
  321. it != MapFieldBase::repeated_field_->end(); ++it) {
  322. MapKey map_key;
  323. switch (key_des->cpp_type()) {
  324. case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
  325. map_key.SetStringValue(reflection->GetString(*it, key_des));
  326. break;
  327. case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
  328. map_key.SetInt64Value(reflection->GetInt64(*it, key_des));
  329. break;
  330. case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
  331. map_key.SetInt32Value(reflection->GetInt32(*it, key_des));
  332. break;
  333. case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
  334. map_key.SetUInt64Value(reflection->GetUInt64(*it, key_des));
  335. break;
  336. case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
  337. map_key.SetUInt32Value(reflection->GetUInt32(*it, key_des));
  338. break;
  339. case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
  340. map_key.SetBoolValue(reflection->GetBool(*it, key_des));
  341. break;
  342. case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
  343. case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
  344. case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
  345. case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
  346. GOOGLE_LOG(FATAL) << "Can't get here.";
  347. break;
  348. }
  349. // Remove existing map value with same key.
  350. Map<MapKey, MapValueRef>::iterator iter = map->find(map_key);
  351. if (iter != map->end()) {
  352. iter->second.DeleteData();
  353. }
  354. MapValueRef& map_val = (*map)[map_key];
  355. map_val.SetType(val_des->cpp_type());
  356. switch (val_des->cpp_type()) {
  357. #define HANDLE_TYPE(CPPTYPE, TYPE, METHOD) \
  358. case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
  359. TYPE * value = new TYPE; \
  360. *value = reflection->Get##METHOD(*it, val_des); \
  361. map_val.SetValue(value); \
  362. break; \
  363. }
  364. HANDLE_TYPE(INT32, int32, Int32);
  365. HANDLE_TYPE(INT64, int64, Int64);
  366. HANDLE_TYPE(UINT32, uint32, UInt32);
  367. HANDLE_TYPE(UINT64, uint64, UInt64);
  368. HANDLE_TYPE(DOUBLE, double, Double);
  369. HANDLE_TYPE(FLOAT, float, Float);
  370. HANDLE_TYPE(BOOL, bool, Bool);
  371. HANDLE_TYPE(STRING, string, String);
  372. HANDLE_TYPE(ENUM, int32, EnumValue);
  373. #undef HANDLE_TYPE
  374. case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
  375. const Message& message = reflection->GetMessage(*it, val_des);
  376. Message* value = message.New();
  377. value->CopyFrom(message);
  378. map_val.SetValue(value);
  379. break;
  380. }
  381. }
  382. }
  383. }
  384. size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const {
  385. size_t size = 0;
  386. if (MapFieldBase::repeated_field_ != NULL) {
  387. size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong();
  388. }
  389. size += sizeof(map_);
  390. size_t map_size = map_.size();
  391. if (map_size) {
  392. Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
  393. size += sizeof(it->first) * map_size;
  394. size += sizeof(it->second) * map_size;
  395. // If key is string, add the allocated space.
  396. if (it->first.type() == google::protobuf::FieldDescriptor::CPPTYPE_STRING) {
  397. size += sizeof(string) * map_size;
  398. }
  399. // Add the allocated space in MapValueRef.
  400. switch (it->second.type()) {
  401. #define HANDLE_TYPE(CPPTYPE, TYPE) \
  402. case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
  403. size += sizeof(TYPE) * map_size; \
  404. break; \
  405. }
  406. HANDLE_TYPE(INT32, int32);
  407. HANDLE_TYPE(INT64, int64);
  408. HANDLE_TYPE(UINT32, uint32);
  409. HANDLE_TYPE(UINT64, uint64);
  410. HANDLE_TYPE(DOUBLE, double);
  411. HANDLE_TYPE(FLOAT, float);
  412. HANDLE_TYPE(BOOL, bool);
  413. HANDLE_TYPE(STRING, string);
  414. HANDLE_TYPE(ENUM, int32);
  415. #undef HANDLE_TYPE
  416. case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
  417. while (it != map_.end()) {
  418. const Message& message = it->second.GetMessageValue();
  419. size += message.GetReflection()->SpaceUsedLong(message);
  420. ++it;
  421. }
  422. break;
  423. }
  424. }
  425. }
  426. return size;
  427. }
  428. } // namespace internal
  429. } // namespace protobuf
  430. } // namespace google