Source/platform/heap/HeapTest.cpp
// This is an example to show how you can remove entries from a T->WeakSet map
// when the weak sets become empty. For this example we are using a type that
// is given to use (HeapHashSet) rather than a type of our own. This means:
// 1) We can't just override the HashTrait for the type since this would affect
//    all collections that use this kind of weak set. Instead we have our own
//    traits and use a map with custom traits for the value type. These traits
//    are the 5th template parameter, so we have to supply default values for
//    the 3rd and 4th template parameters
// 2) We can't just inherit from WeakHandlingHashTraits, since that trait
//    assumes we can add methods to the type, but we can't add methods to
//    HeapHashSet.
This is an example to show how you can remove entries from a T->WeakSet map
when the weak sets become empty. For this example we are using a type that
is given to use (HeapHashSet) rather than a type of our own. This means:
1) We can't just override the HashTrait for the type since this would affect
all collections that use this kind of weak set. Instead we have our own
traits and use a map with custom traits for the value type. These traits
are the 5th template parameter, so we have to supply default values for
the 3rd and 4th template parameters
2) We can't just inherit from WeakHandlingHashTraits, since that trait
assumes we can add methods to the type, but we can't add methods to
HeapHashSet.
This is an example to show how you can remove entries from a T - > WeakSet map when the weak sets become empty . For this example we are using a type that is given to use ( HeapHashSet ) rather than a type of our own . This means : 1 ) We can ' t just override the HashTrait for the type since this would affect all collections that use this kind of weak set . Instead we have our own traits and use a map with custom traits for the value type . These traits are the 5th template parameter so we have to supply default values for the 3rd and 4th template parameters 2 ) We can ' t just inherit from WeakHandlingHashTraits since that trait assumes we can add methods to the type but we can ' t add methods to HeapHashSet .
TEST(HeapTest, RemoveEmptySets)
{
    HeapStats initialHeapSize;
    clearOutOldGarbage(&initialHeapSize);
    OffHeapInt::s_destructorCalls = 0;
    Persistent<IntWrapper> livingInt(IntWrapper::create(42));
    typedef RefPtr<OffHeapInt> Key;
    typedef HeapHashMap<Key, WeakSet, WTF::DefaultHash<Key>::Hash, HashTraits<Key>, EmptyClearingHastSetTraits> Map;
    Persistent<Map> map(new Map());
    map->add(OffHeapInt::create(1), WeakSet());
    {
        WeakSet& set = map->begin()->value;
        set.add(IntWrapper::create(103)); 
        set.add(livingInt); 
        EXPECT_EQ(2u, set.size());
    }
    map->add(OffHeapInt::create(2), WeakSet());
    EXPECT_EQ(2u, map->size());
    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    EXPECT_EQ(1u, map->size()); 
    EXPECT_EQ(1, OffHeapInt::s_destructorCalls);
    {
        WeakSet& set = map->begin()->value;
        EXPECT_EQ(1u, set.size());
    }
    livingInt.clear(); 
    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    if (map->size() == 1u) {
        WeakSet& set = map->begin()->value;
        EXPECT_EQ(0u, set.size());
    }
    Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
    EXPECT_EQ(0u, map->size());
}
TEST ( HeapTest , RemoveEmptySets ) { HeapStats initialHeapSize ; clearOutOldGarbage ( & initialHeapSize ) ; OffHeapInt :: s_destructorCalls = 0 ; Persistent < IntWrapper > livingInt ( IntWrapper :: create ( 42 ) ) ; typedef RefPtr < OffHeapInt > Key ; typedef HeapHashMap < Key , WeakSet , WTF :: DefaultHash < Key > :: Hash , HashTraits < Key > , EmptyClearingHastSetTraits > Map ; Persistent < Map > map ( new Map ( ) ) ; map -> add ( OffHeapInt :: create ( 1 ) , WeakSet ( ) ) ; { WeakSet & set = map -> begin ( ) -> value ; set . add ( IntWrapper :: create ( 103 ) ) ; set . add ( livingInt ) ; EXPECT_EQ ( 2u , set . size ( ) ) ; } map -> add ( OffHeapInt :: create ( 2 ) , WeakSet ( ) ) ; EXPECT_EQ ( 2u , map -> size ( ) ) ; Heap :: collectGarbage ( ThreadState :: NoHeapPointersOnStack ) ; EXPECT_EQ ( 1u , map -> size ( ) ) ; EXPECT_EQ ( 1 , OffHeapInt :: s_destructorCalls ) ; { WeakSet & set = map -> begin ( ) -> value ; EXPECT_EQ ( 1u , set . size ( ) ) ; } livingInt . clear ( ) ; Heap :: collectGarbage ( ThreadState :: NoHeapPointersOnStack ) ; if ( map -> size ( ) == 1u ) { WeakSet & set = map -> begin ( ) -> value ; EXPECT_EQ ( 0u , set . size ( ) ) ; } Heap :: collectGarbage ( ThreadState :: NoHeapPointersOnStack ) ; EXPECT_EQ ( 0u , map -> size ( ) ) ; }
This is an example to show how you can remove entries from a T->WeakSet map
when the weak sets become empty.
This is an example to show how you can remove entries from a T - > WeakSet map when the weak sets become empty .
// Weak set can't hold this long. // This prevents the set from being emptied. // The set we add here is empty, so the entry will be removed from the map // at the next GC. // The one with key 2 was removed. // The weak set can no longer keep the '42' alive now. // If the weak processing for the set ran after the weak processing for // the map, then the set was not empty, and so the entry in the map was // not removed yet.