@ -54,33 +54,21 @@ namespace internal {
using unittest : : TestAllTypes ;
// ArenaHolder from map_test_util.h works fine for fields other than map
// fields. For arena-owned map fields, the ArenaDestruct() call must be made
// because the destructor will be skipped.
template < typename MapType >
struct ArenaDestructor : ArenaHolder < MapType > {
ArenaDestructor ( Arena * arena )
: ArenaHolder < MapType > ( arena ) , owned_by_arena ( arena ! = nullptr ) { }
~ ArenaDestructor ( ) {
if ( owned_by_arena ) ArenaHolder < MapType > : : get ( ) - > ArenaDestruct ( ) ;
}
bool owned_by_arena ;
} ;
class MapFieldBaseStub : public MapFieldBase {
public :
typedef void InternalArenaConstructable_ ;
using InternalArenaConstructable_ = void ;
typedef void DestructorSkippable_ ;
MapFieldBaseStub ( ) { }
virtual ~ MapFieldBaseStub ( ) { }
explicit MapFieldBaseStub ( Arena * arena ) : MapFieldBase ( arena ) { }
void SetMapDirty ( ) {
state_ . store ( STATE_MODIFIED_MAP , std : : memory_order_relaxed ) ;
payload ( ) . state . store ( STATE_MODIFIED_MAP , std : : memory_order_relaxed ) ;
}
void SetRepeatedDirty ( ) {
state_ . store ( STATE_MODIFIED_REPEATED , std : : memory_order_relaxed ) ;
payload ( ) . state . store ( STATE_MODIFIED_REPEATED , std : : memory_order_relaxed ) ;
}
void SyncRepeatedFieldWithMapNoLock ( ) const override { }
void SyncMapWithRepeatedFieldNoLock ( ) const override { }
UntypedMapBase * MutableMap ( ) override { return nullptr ; }
bool ContainsMapKey ( const MapKey & map_key ) const override { return false ; }
bool InsertOrLookupMapValue ( const MapKey & map_key ,
@ -142,7 +130,7 @@ class MapFieldBasePrimitiveTest : public testing::TestWithParam<bool> {
}
std : : unique_ptr < Arena > arena_ ;
ArenaDestructo r < MapFieldType > map_field_ ;
ArenaHolde r < MapFieldType > map_field_ ;
MapFieldBase * map_field_base_ ;
Map < int32_t , int32_t > * map_ ;
const Descriptor * map_descriptor_ ;
@ -246,7 +234,7 @@ class MapFieldStateTest
map_field_base_ ( map_field_ . get ( ) ) ,
state_ ( std : : get < 0 > ( GetParam ( ) ) ) {
// Build map field
Expect ( map_field_ . get ( ) , MAP_DIRTY , 0 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 0 , 0 ) ;
switch ( state_ ) {
case CLEAN :
AddOneStillClean ( map_field_ . get ( ) ) ;
@ -267,13 +255,13 @@ class MapFieldStateTest
Map < int32_t , int32_t > * map = map_field - > MutableMap ( ) ;
( * map ) [ 0 ] = 0 ;
map_field_base - > GetRepeatedField ( ) ;
Expect ( map_field , CLEAN , 1 , 1 , false ) ;
Expect ( map_field , CLEAN , 1 , 1 ) ;
}
void MakeMapDirty ( MapFieldType * map_field ) {
Map < int32_t , int32_t > * map = map_field - > MutableMap ( ) ;
( * map ) [ 0 ] = 0 ;
Expect ( map_field , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field , MAP_DIRTY , 1 , 0 ) ;
}
void MakeRepeatedDirty ( MapFieldType * map_field ) {
@ -284,32 +272,28 @@ class MapFieldStateTest
Map < int32_t , int32_t > * map = map_field - > impl_ . MutableMap ( ) ;
map - > clear ( ) ;
Expect ( map_field , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( map_field , REPEATED_DIRTY , 0 , 1 ) ;
}
void Expect ( MapFieldType * map_field , State state , int map_size ,
int repeated_size , bool is_repeated_null ) {
int repeated_size ) {
// We use MutableMap on impl_ because we don't want to disturb the syncing
Map < int32_t , int32_t > * map = map_field - > impl_ . MutableMap ( ) ;
RepeatedPtrField < Message > * repeated_field = map_field - > repeated_field_ ;
switch ( state ) {
case MAP_DIRTY :
EXPECT_FALSE ( map_field - > state_ . load ( std : : memory_order_relaxed ) ! =
MapFieldType : : STATE_MODIFIED_MAP ) ;
EXPECT_TRUE ( map_field - > state_ . load ( std : : memory_order_relaxed ) ! =
EXPECT_FALSE ( map_field - > state ( ) ! = MapFieldType : : STATE_MODIFIED_MAP ) ;
EXPECT_TRUE ( map_field - > state ( ) ! =
MapFieldType : : STATE_MODIFIED_REPEATED ) ;
break ;
case REPEATED_DIRTY :
EXPECT_TRUE ( map_field - > state_ . load ( std : : memory_order_relaxed ) ! =
MapFieldType : : STATE_MODIFIED_MAP ) ;
EXPECT_FALSE ( map_field - > state_ . load ( std : : memory_order_relaxed ) ! =
EXPECT_TRUE ( map_field - > state ( ) ! = MapFieldType : : STATE_MODIFIED_MAP ) ;
EXPECT_FALSE ( map_field - > state ( ) ! =
MapFieldType : : STATE_MODIFIED_REPEATED ) ;
break ;
case CLEAN :
EXPECT_TRUE ( map_field - > state_ . load ( std : : memory_order_relaxed ) ! =
MapFieldType : : STATE_MODIFIED_MAP ) ;
EXPECT_TRUE ( map_field - > state_ . load ( std : : memory_order_relaxed ) ! =
EXPECT_TRUE ( map_field - > state ( ) ! = MapFieldType : : STATE_MODIFIED_MAP ) ;
EXPECT_TRUE ( map_field - > state ( ) ! =
MapFieldType : : STATE_MODIFIED_REPEATED ) ;
break ;
default :
@ -317,19 +301,14 @@ class MapFieldStateTest
}
EXPECT_EQ ( map_size , map - > size ( ) ) ;
if ( is_repeated_null ) {
EXPECT_TRUE ( repeated_field = = nullptr ) ;
} else {
if ( repeated_field = = nullptr ) {
EXPECT_EQ ( repeated_size , 0 ) ;
} else {
EXPECT_EQ ( repeated_size , repeated_field - > size ( ) ) ;
}
}
EXPECT_EQ ( repeated_size ,
map_field - > maybe_payload ( ) = = nullptr
? 0
: map_field - > maybe_payload ( ) - > repeated_field . size ( ) ) ;
}
std : : unique_ptr < Arena > arena_ ;
ArenaDestructo r < MapFieldType > map_field_ ;
ArenaHolder < MapFieldType > map_field_ ;
MapFieldBase * map_field_base_ ;
State state_ ;
} ;
@ -342,83 +321,83 @@ INSTANTIATE_TEST_SUITE_P(MapFieldStateTestInstance, MapFieldStateTest,
TEST_P ( MapFieldStateTest , GetMap ) {
map_field_ - > GetMap ( ) ;
if ( state_ ! = MAP_DIRTY ) {
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
}
}
TEST_P ( MapFieldStateTest , MutableMap ) {
map_field_ - > MutableMap ( ) ;
if ( state_ ! = MAP_DIRTY ) {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
}
}
TEST_P ( MapFieldStateTest , MergeFromClean ) {
ArenaDestructo r < MapFieldType > other ( arena_ . get ( ) ) ;
ArenaHolde r < MapFieldType > other ( arena_ . get ( ) ) ;
AddOneStillClean ( other . get ( ) ) ;
map_field_ - > MergeFrom ( * other ) ;
if ( state_ ! = MAP_DIRTY ) {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
}
Expect ( other . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( other . get ( ) , CLEAN , 1 , 1 ) ;
}
TEST_P ( MapFieldStateTest , MergeFromMapDirty ) {
ArenaDestructo r < MapFieldType > other ( arena_ . get ( ) ) ;
ArenaHolde r < MapFieldType > other ( arena_ . get ( ) ) ;
MakeMapDirty ( other . get ( ) ) ;
map_field_ - > MergeFrom ( * other ) ;
if ( state_ ! = MAP_DIRTY ) {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
}
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 ) ;
}
TEST_P ( MapFieldStateTest , MergeFromRepeatedDirty ) {
ArenaDestructo r < MapFieldType > other ( arena_ . get ( ) ) ;
ArenaHolde r < MapFieldType > other ( arena_ . get ( ) ) ;
MakeRepeatedDirty ( other . get ( ) ) ;
map_field_ - > MergeFrom ( * other ) ;
if ( state_ ! = MAP_DIRTY ) {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
}
Expect ( other . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( other . get ( ) , CLEAN , 1 , 1 ) ;
}
TEST_P ( MapFieldStateTest , SwapClean ) {
ArenaDestructo r < MapFieldType > other ( arena_ . get ( ) ) ;
ArenaHolde r < MapFieldType > other ( arena_ . get ( ) ) ;
AddOneStillClean ( other . get ( ) ) ;
map_field_ - > Swap ( other . get ( ) ) ;
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 ) ;
switch ( state_ ) {
case CLEAN :
Expect ( other . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( other . get ( ) , CLEAN , 1 , 1 ) ;
break ;
case MAP_DIRTY :
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 ) ;
break ;
case REPEATED_DIRTY :
Expect ( other . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( other . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
break ;
default :
break ;
@ -426,22 +405,22 @@ TEST_P(MapFieldStateTest, SwapClean) {
}
TEST_P ( MapFieldStateTest , SwapMapDirty ) {
ArenaDestructo r < MapFieldType > other ( arena_ . get ( ) ) ;
ArenaHolde r < MapFieldType > other ( arena_ . get ( ) ) ;
MakeMapDirty ( other . get ( ) ) ;
map_field_ - > Swap ( other . get ( ) ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
switch ( state_ ) {
case CLEAN :
Expect ( other . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( other . get ( ) , CLEAN , 1 , 1 ) ;
break ;
case MAP_DIRTY :
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 ) ;
break ;
case REPEATED_DIRTY :
Expect ( other . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( other . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
break ;
default :
break ;
@ -449,22 +428,22 @@ TEST_P(MapFieldStateTest, SwapMapDirty) {
}
TEST_P ( MapFieldStateTest , SwapRepeatedDirty ) {
ArenaDestructo r < MapFieldType > other ( arena_ . get ( ) ) ;
ArenaHolde r < MapFieldType > other ( arena_ . get ( ) ) ;
MakeRepeatedDirty ( other . get ( ) ) ;
map_field_ - > Swap ( other . get ( ) ) ;
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
switch ( state_ ) {
case CLEAN :
Expect ( other . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( other . get ( ) , CLEAN , 1 , 1 ) ;
break ;
case MAP_DIRTY :
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( other . get ( ) , MAP_DIRTY , 1 , 0 ) ;
break ;
case REPEATED_DIRTY :
Expect ( other . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( other . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
break ;
default :
break ;
@ -474,7 +453,7 @@ TEST_P(MapFieldStateTest, SwapRepeatedDirty) {
TEST_P ( MapFieldStateTest , Clear ) {
map_field_ - > Clear ( ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 0 , 0 , false ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 0 , 0 ) ;
}
TEST_P ( MapFieldStateTest , SpaceUsedExcludingSelf ) {
@ -482,13 +461,13 @@ TEST_P(MapFieldStateTest, SpaceUsedExcludingSelf) {
switch ( state_ ) {
case CLEAN :
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 ) ;
break ;
case MAP_DIRTY :
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 , true ) ;
Expect ( map_field_ . get ( ) , MAP_DIRTY , 1 , 0 ) ;
break ;
case REPEATED_DIRTY :
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
break ;
default :
break ;
@ -499,9 +478,9 @@ TEST_P(MapFieldStateTest, GetMapField) {
map_field_base_ - > GetRepeatedField ( ) ;
if ( state_ ! = REPEATED_DIRTY ) {
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , CLEAN , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
}
}
@ -509,20 +488,16 @@ TEST_P(MapFieldStateTest, MutableMapField) {
map_field_base_ - > MutableRepeatedField ( ) ;
if ( state_ ! = REPEATED_DIRTY ) {
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 1 , 1 , false ) ;
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 1 , 1 ) ;
} else {
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 , false ) ;
Expect ( map_field_ . get ( ) , REPEATED_DIRTY , 0 , 1 ) ;
}
}
class MyMapField
: public MapField < unittest : : TestMap_MapInt32Int32Entry_DoNotUse , int32_t ,
int32_t , internal : : WireFormatLite : : TYPE_INT32 ,
internal : : WireFormatLite : : TYPE_INT32 > {
public :
constexpr MyMapField ( )
: MyMapField : : MapField ( internal : : ConstantInitialized { } ) { }
} ;
using MyMapField =
MapField < unittest : : TestMap_MapInt32Int32Entry_DoNotUse , int32_t , int32_t ,
internal : : WireFormatLite : : TYPE_INT32 ,
internal : : WireFormatLite : : TYPE_INT32 > ;
TEST ( MapFieldTest , ConstInit ) {
// This tests that `MapField` and all its base classes can be constant