map_field_test.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  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 <map>
  31. #include <memory>
  32. #include <google/protobuf/stubs/logging.h>
  33. #include <google/protobuf/stubs/common.h>
  34. #include <google/protobuf/arena.h>
  35. #include <google/protobuf/map.h>
  36. #include <google/protobuf/arena_test_util.h>
  37. #include <google/protobuf/map_unittest.pb.h>
  38. #include <google/protobuf/map_test_util.h>
  39. #include <google/protobuf/unittest.pb.h>
  40. #include <google/protobuf/map_field_inl.h>
  41. #include <google/protobuf/message.h>
  42. #include <google/protobuf/repeated_field.h>
  43. #include <google/protobuf/wire_format_lite_inl.h>
  44. #include <gtest/gtest.h>
  45. namespace google {
  46. namespace protobuf {
  47. namespace internal {
  48. using unittest::TestAllTypes;
  49. class MapFieldBaseStub : public MapFieldBase {
  50. public:
  51. typedef void InternalArenaConstructable_;
  52. typedef void DestructorSkippable_;
  53. MapFieldBaseStub() {}
  54. explicit MapFieldBaseStub(Arena* arena) : MapFieldBase(arena) {}
  55. void SyncRepeatedFieldWithMap() const {
  56. MapFieldBase::SyncRepeatedFieldWithMap();
  57. }
  58. void SyncMapWithRepeatedField() const {
  59. MapFieldBase::SyncMapWithRepeatedField();
  60. }
  61. // Get underlined repeated field without synchronizing map.
  62. RepeatedPtrField<Message>* InternalRepeatedField() {
  63. return repeated_field_;
  64. }
  65. bool IsMapClean() {
  66. return state_.load(std::memory_order_relaxed) != STATE_MODIFIED_MAP;
  67. }
  68. bool IsRepeatedClean() {
  69. return state_.load(std::memory_order_relaxed) != STATE_MODIFIED_REPEATED;
  70. }
  71. void SetMapDirty() {
  72. state_.store(STATE_MODIFIED_MAP, std::memory_order_relaxed);
  73. }
  74. void SetRepeatedDirty() {
  75. state_.store(STATE_MODIFIED_REPEATED, std::memory_order_relaxed);
  76. }
  77. bool ContainsMapKey(const MapKey& map_key) const {
  78. return false;
  79. }
  80. bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val) {
  81. return false;
  82. }
  83. bool DeleteMapValue(const MapKey& map_key) {
  84. return false;
  85. }
  86. bool EqualIterator(const MapIterator& a, const MapIterator& b) const {
  87. return false;
  88. }
  89. int size() const { return 0; }
  90. void MapBegin(MapIterator* map_iter) const {}
  91. void MapEnd(MapIterator* map_iter) const {}
  92. void InitializeIterator(MapIterator* map_iter) const {}
  93. void DeleteIterator(MapIterator* map_iter) const {}
  94. void CopyIterator(MapIterator* this_iterator,
  95. const MapIterator& other_iterator) const {}
  96. void IncreaseIterator(MapIterator* map_iter) const {}
  97. void SetDefaultMessageEntry(const Message* message) const {}
  98. const Message* GetDefaultMessageEntry() const { return NULL; }
  99. };
  100. class MapFieldBasePrimitiveTest : public ::testing::Test {
  101. protected:
  102. typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType;
  103. typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
  104. WireFormatLite::TYPE_INT32, false>
  105. MapFieldType;
  106. MapFieldBasePrimitiveTest() {
  107. // Get descriptors
  108. map_descriptor_ = unittest::TestMap::descriptor()
  109. ->FindFieldByName("map_int32_int32")
  110. ->message_type();
  111. key_descriptor_ = map_descriptor_->FindFieldByName("key");
  112. value_descriptor_ = map_descriptor_->FindFieldByName("value");
  113. // Build map field
  114. map_field_.reset(new MapFieldType);
  115. map_field_base_ = map_field_.get();
  116. map_ = map_field_->MutableMap();
  117. initial_value_map_[0] = 100;
  118. initial_value_map_[1] = 101;
  119. map_->insert(initial_value_map_.begin(), initial_value_map_.end());
  120. EXPECT_EQ(2, map_->size());
  121. }
  122. std::unique_ptr<MapFieldType> map_field_;
  123. MapFieldBase* map_field_base_;
  124. Map<int32, int32>* map_;
  125. const Descriptor* map_descriptor_;
  126. const FieldDescriptor* key_descriptor_;
  127. const FieldDescriptor* value_descriptor_;
  128. std::map<int32, int32> initial_value_map_; // copy of initial values inserted
  129. };
  130. TEST_F(MapFieldBasePrimitiveTest, SpaceUsedExcludingSelf) {
  131. EXPECT_LT(0, map_field_base_->SpaceUsedExcludingSelf());
  132. }
  133. TEST_F(MapFieldBasePrimitiveTest, GetRepeatedField) {
  134. const RepeatedPtrField<Message>& repeated =
  135. reinterpret_cast<const RepeatedPtrField<Message>&>(
  136. map_field_base_->GetRepeatedField());
  137. EXPECT_EQ(2, repeated.size());
  138. for (int i = 0; i < repeated.size(); i++) {
  139. const Message& message = repeated.Get(i);
  140. int key = message.GetReflection()->GetInt32(message, key_descriptor_);
  141. int value = message.GetReflection()->GetInt32(message, value_descriptor_);
  142. EXPECT_EQ(value, initial_value_map_[key]);
  143. }
  144. }
  145. TEST_F(MapFieldBasePrimitiveTest, MutableRepeatedField) {
  146. RepeatedPtrField<Message>* repeated =
  147. reinterpret_cast<RepeatedPtrField<Message>*>(
  148. map_field_base_->MutableRepeatedField());
  149. EXPECT_EQ(2, repeated->size());
  150. for (int i = 0; i < repeated->size(); i++) {
  151. const Message& message = repeated->Get(i);
  152. int key = message.GetReflection()->GetInt32(message, key_descriptor_);
  153. int value = message.GetReflection()->GetInt32(message, value_descriptor_);
  154. EXPECT_EQ(value, initial_value_map_[key]);
  155. }
  156. }
  157. TEST_F(MapFieldBasePrimitiveTest, Arena) {
  158. // Allocate a large initial block to avoid mallocs during hooked test.
  159. std::vector<char> arena_block(128 * 1024);
  160. ArenaOptions options;
  161. options.initial_block = &arena_block[0];
  162. options.initial_block_size = arena_block.size();
  163. Arena arena(options);
  164. {
  165. // TODO(liujisi): Re-write the test to ensure the memory for the map and
  166. // repeated fields are allocated from arenas.
  167. // NoHeapChecker no_heap;
  168. MapFieldType* map_field = Arena::CreateMessage<MapFieldType>(&arena);
  169. // Set content in map
  170. (*map_field->MutableMap())[100] = 101;
  171. // Trigger conversion to repeated field.
  172. map_field->GetRepeatedField();
  173. }
  174. {
  175. // TODO(liujisi): Re-write the test to ensure the memory for the map and
  176. // repeated fields are allocated from arenas.
  177. // NoHeapChecker no_heap;
  178. MapFieldBaseStub* map_field =
  179. Arena::CreateMessage<MapFieldBaseStub>(&arena);
  180. // Trigger conversion to repeated field.
  181. EXPECT_TRUE(map_field->MutableRepeatedField() != NULL);
  182. }
  183. }
  184. namespace {
  185. enum State { CLEAN, MAP_DIRTY, REPEATED_DIRTY };
  186. } // anonymous namespace
  187. class MapFieldStateTest
  188. : public testing::TestWithParam<State> {
  189. public:
  190. protected:
  191. typedef unittest::TestMap_MapInt32Int32Entry_DoNotUse EntryType;
  192. typedef MapField<EntryType, int32, int32, WireFormatLite::TYPE_INT32,
  193. WireFormatLite::TYPE_INT32, false>
  194. MapFieldType;
  195. MapFieldStateTest() : state_(GetParam()) {
  196. // Build map field
  197. map_field_.reset(new MapFieldType());
  198. map_field_base_ = map_field_.get();
  199. Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
  200. switch (state_) {
  201. case CLEAN:
  202. AddOneStillClean(map_field_.get());
  203. break;
  204. case MAP_DIRTY:
  205. MakeMapDirty(map_field_.get());
  206. break;
  207. case REPEATED_DIRTY:
  208. MakeRepeatedDirty(map_field_.get());
  209. break;
  210. default:
  211. break;
  212. }
  213. }
  214. void AddOneStillClean(MapFieldType* map_field) {
  215. MapFieldBase* map_field_base = map_field;
  216. Map<int32, int32>* map = map_field->MutableMap();
  217. (*map)[0] = 0;
  218. map_field_base->GetRepeatedField();
  219. Expect(map_field, CLEAN, 1, 1, false);
  220. }
  221. void MakeMapDirty(MapFieldType* map_field) {
  222. Map<int32, int32>* map = map_field->MutableMap();
  223. (*map)[0] = 0;
  224. Expect(map_field, MAP_DIRTY, 1, 0, true);
  225. }
  226. void MakeRepeatedDirty(MapFieldType* map_field) {
  227. MakeMapDirty(map_field);
  228. MapFieldBase* map_field_base = map_field;
  229. map_field_base->MutableRepeatedField();
  230. // We use MutableMap on impl_ because we don't want to disturb the syncing
  231. Map<int32, int32>* map = map_field->impl_.MutableMap();
  232. map->clear();
  233. Expect(map_field, REPEATED_DIRTY, 0, 1, false);
  234. }
  235. void Expect(MapFieldType* map_field, State state, int map_size,
  236. int repeated_size, bool is_repeated_null) {
  237. MapFieldBase* map_field_base = map_field;
  238. MapFieldBaseStub* stub =
  239. reinterpret_cast<MapFieldBaseStub*>(map_field_base);
  240. // We use MutableMap on impl_ because we don't want to disturb the syncing
  241. Map<int32, int32>* map = map_field->impl_.MutableMap();
  242. RepeatedPtrField<Message>* repeated_field = stub->InternalRepeatedField();
  243. switch (state) {
  244. case MAP_DIRTY:
  245. EXPECT_FALSE(stub->IsMapClean());
  246. EXPECT_TRUE(stub->IsRepeatedClean());
  247. break;
  248. case REPEATED_DIRTY:
  249. EXPECT_TRUE(stub->IsMapClean());
  250. EXPECT_FALSE(stub->IsRepeatedClean());
  251. break;
  252. case CLEAN:
  253. EXPECT_TRUE(stub->IsMapClean());
  254. EXPECT_TRUE(stub->IsRepeatedClean());
  255. break;
  256. default:
  257. FAIL();
  258. }
  259. EXPECT_EQ(map_size, map->size());
  260. if (is_repeated_null) {
  261. EXPECT_TRUE(repeated_field == NULL);
  262. } else {
  263. EXPECT_EQ(repeated_size, repeated_field->size());
  264. }
  265. }
  266. std::unique_ptr<MapFieldType> map_field_;
  267. MapFieldBase* map_field_base_;
  268. State state_;
  269. };
  270. INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest,
  271. ::testing::Values(CLEAN, MAP_DIRTY, REPEATED_DIRTY));
  272. TEST_P(MapFieldStateTest, GetMap) {
  273. map_field_->GetMap();
  274. if (state_ != MAP_DIRTY) {
  275. Expect(map_field_.get(), CLEAN, 1, 1, false);
  276. } else {
  277. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  278. }
  279. }
  280. TEST_P(MapFieldStateTest, MutableMap) {
  281. map_field_->MutableMap();
  282. if (state_ != MAP_DIRTY) {
  283. Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
  284. } else {
  285. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  286. }
  287. }
  288. TEST_P(MapFieldStateTest, MergeFromClean) {
  289. MapFieldType other;
  290. AddOneStillClean(&other);
  291. map_field_->MergeFrom(other);
  292. if (state_ != MAP_DIRTY) {
  293. Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
  294. } else {
  295. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  296. }
  297. Expect(&other, CLEAN, 1, 1, false);
  298. }
  299. TEST_P(MapFieldStateTest, MergeFromMapDirty) {
  300. MapFieldType other;
  301. MakeMapDirty(&other);
  302. map_field_->MergeFrom(other);
  303. if (state_ != MAP_DIRTY) {
  304. Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
  305. } else {
  306. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  307. }
  308. Expect(&other, MAP_DIRTY, 1, 0, true);
  309. }
  310. TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) {
  311. MapFieldType other;
  312. MakeRepeatedDirty(&other);
  313. map_field_->MergeFrom(other);
  314. if (state_ != MAP_DIRTY) {
  315. Expect(map_field_.get(), MAP_DIRTY, 1, 1, false);
  316. } else {
  317. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  318. }
  319. Expect(&other, CLEAN, 1, 1, false);
  320. }
  321. TEST_P(MapFieldStateTest, SwapClean) {
  322. MapFieldType other;
  323. AddOneStillClean(&other);
  324. map_field_->Swap(&other);
  325. Expect(map_field_.get(), CLEAN, 1, 1, false);
  326. switch (state_) {
  327. case CLEAN:
  328. Expect(&other, CLEAN, 1, 1, false);
  329. break;
  330. case MAP_DIRTY:
  331. Expect(&other, MAP_DIRTY, 1, 0, true);
  332. break;
  333. case REPEATED_DIRTY:
  334. Expect(&other, REPEATED_DIRTY, 0, 1, false);
  335. break;
  336. default:
  337. break;
  338. }
  339. }
  340. TEST_P(MapFieldStateTest, SwapMapDirty) {
  341. MapFieldType other;
  342. MakeMapDirty(&other);
  343. map_field_->Swap(&other);
  344. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  345. switch (state_) {
  346. case CLEAN:
  347. Expect(&other, CLEAN, 1, 1, false);
  348. break;
  349. case MAP_DIRTY:
  350. Expect(&other, MAP_DIRTY, 1, 0, true);
  351. break;
  352. case REPEATED_DIRTY:
  353. Expect(&other, REPEATED_DIRTY, 0, 1, false);
  354. break;
  355. default:
  356. break;
  357. }
  358. }
  359. TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
  360. MapFieldType other;
  361. MakeRepeatedDirty(&other);
  362. map_field_->Swap(&other);
  363. Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
  364. switch (state_) {
  365. case CLEAN:
  366. Expect(&other, CLEAN, 1, 1, false);
  367. break;
  368. case MAP_DIRTY:
  369. Expect(&other, MAP_DIRTY, 1, 0, true);
  370. break;
  371. case REPEATED_DIRTY:
  372. Expect(&other, REPEATED_DIRTY, 0, 1, false);
  373. break;
  374. default:
  375. break;
  376. }
  377. }
  378. TEST_P(MapFieldStateTest, Clear) {
  379. map_field_->Clear();
  380. if (state_ != MAP_DIRTY) {
  381. Expect(map_field_.get(), MAP_DIRTY, 0, 1, false);
  382. } else {
  383. Expect(map_field_.get(), MAP_DIRTY, 0, 0, true);
  384. }
  385. }
  386. TEST_P(MapFieldStateTest, SpaceUsedExcludingSelf) {
  387. map_field_base_->SpaceUsedExcludingSelf();
  388. switch (state_) {
  389. case CLEAN:
  390. Expect(map_field_.get(), CLEAN, 1, 1, false);
  391. break;
  392. case MAP_DIRTY:
  393. Expect(map_field_.get(), MAP_DIRTY, 1, 0, true);
  394. break;
  395. case REPEATED_DIRTY:
  396. Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
  397. break;
  398. default:
  399. break;
  400. }
  401. }
  402. TEST_P(MapFieldStateTest, GetMapField) {
  403. map_field_base_->GetRepeatedField();
  404. if (state_ != REPEATED_DIRTY) {
  405. Expect(map_field_.get(), CLEAN, 1, 1, false);
  406. } else {
  407. Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
  408. }
  409. }
  410. TEST_P(MapFieldStateTest, MutableMapField) {
  411. map_field_base_->MutableRepeatedField();
  412. if (state_ != REPEATED_DIRTY) {
  413. Expect(map_field_.get(), REPEATED_DIRTY, 1, 1, false);
  414. } else {
  415. Expect(map_field_.get(), REPEATED_DIRTY, 0, 1, false);
  416. }
  417. }
  418. } // namespace internal
  419. } // namespace protobuf
  420. } // namespace google