LCOV - code coverage report
Current view: directory - js/src/jsapi-tests - testHashTable.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 160 144 90.0 %
Date: 2012-04-07 Functions: 25 22 88.0 %

       1                 : #include "tests.h"
       2                 : 
       3                 : #include "js/HashTable.h"
       4                 : 
       5                 : //#define FUZZ
       6                 : 
       7                 : typedef js::HashMap<uint32_t, uint32_t, js::DefaultHasher<uint32_t>, js::SystemAllocPolicy> IntMap;
       8                 : typedef js::HashSet<uint32_t, js::DefaultHasher<uint32_t>, js::SystemAllocPolicy> IntSet;
       9                 : 
      10                 : /*
      11                 :  * The rekeying test as conducted by adding only keys masked with 0x0000FFFF
      12                 :  * that are unique. We rekey by shifting left 16 bits.
      13                 :  */
      14                 : #ifdef FUZZ
      15                 : const size_t TestSize = 0x0000FFFF / 2;
      16                 : const size_t TestIterations = SIZE_MAX;
      17                 : #else
      18                 : const size_t TestSize = 10000;
      19                 : const size_t TestIterations = 10;
      20                 : #endif
      21                 : 
      22                 : JS_STATIC_ASSERT(TestSize <= 0x0000FFFF / 2);
      23                 : 
      24                 : struct LowToHigh
      25                 : {
      26          470160 :     static uint32_t rekey(uint32_t initial) {
      27          470160 :         if (initial > uint32_t(0x0000FFFF))
      28           70160 :             return initial;
      29          400000 :         return initial << 16;
      30                 :     }
      31                 : 
      32          200000 :     static bool shouldBeRemoved(uint32_t initial) {
      33          200000 :         return false;
      34                 :     }
      35                 : };
      36                 : 
      37                 : struct LowToHighWithRemoval
      38                 : {
      39          231858 :     static uint32_t rekey(uint32_t initial) {
      40          231858 :         if (initial > uint32_t(0x0000FFFF))
      41           31962 :             return initial;
      42          199896 :         return initial << 16;
      43                 :     }
      44                 : 
      45          431962 :     static bool shouldBeRemoved(uint32_t initial) {
      46          431962 :         if (initial >= 0x00010000)
      47           31962 :             return (initial >> 16) % 2 == 0;
      48          400000 :         return initial % 2 == 0;
      49                 :     }
      50                 : };
      51                 : 
      52                 : static bool
      53              40 : MapsAreEqual(IntMap &am, IntMap &bm)
      54                 : {
      55              40 :     bool equal = true;
      56              40 :     if (am.count() != bm.count()) {
      57               0 :         equal = false;
      58               0 :         fprintf(stderr, "A.count() == %u and B.count() == %u\n", am.count(), bm.count());
      59                 :     }
      60          350014 :     for (IntMap::Range r = am.all(); !r.empty(); r.popFront()) {
      61          349974 :         if (!bm.has(r.front().key)) {
      62               0 :             equal = false;
      63               0 :             fprintf(stderr, "B does not have %x which is in A\n", r.front().key);
      64                 :         }
      65                 :     }
      66          350014 :     for (IntMap::Range r = bm.all(); !r.empty(); r.popFront()) {
      67          349974 :         if (!am.has(r.front().key)) {
      68               0 :             equal = false;
      69               0 :             fprintf(stderr, "A does not have %x which is in B\n", r.front().key);
      70                 :         }
      71                 :     }
      72              40 :     return equal;
      73                 : }
      74                 : 
      75                 : static bool
      76              40 : SetsAreEqual(IntSet &am, IntSet &bm)
      77                 : {
      78              40 :     bool equal = true;
      79              40 :     if (am.count() != bm.count()) {
      80               0 :         equal = false;
      81               0 :         fprintf(stderr, "A.count() == %u and B.count() == %u\n", am.count(), bm.count());
      82                 :     }
      83          350014 :     for (IntSet::Range r = am.all(); !r.empty(); r.popFront()) {
      84          349974 :         if (!bm.has(r.front())) {
      85               0 :             equal = false;
      86               0 :             fprintf(stderr, "B does not have %x which is in A\n", r.front());
      87                 :         }
      88                 :     }
      89          350014 :     for (IntSet::Range r = bm.all(); !r.empty(); r.popFront()) {
      90          349974 :         if (!am.has(r.front())) {
      91               0 :             equal = false;
      92               0 :             fprintf(stderr, "A does not have %x which is in B\n", r.front());
      93                 :         }
      94                 :     }
      95              40 :     return equal;
      96                 : }
      97                 : 
      98                 : static bool
      99              20 : AddLowKeys(IntMap *am, IntMap *bm, int seed)
     100                 : {
     101              20 :     size_t i = 0;
     102              20 :     srand(seed);
     103          217022 :     while (i < TestSize) {
     104          216982 :         uint32_t n = rand() & 0x0000FFFF;
     105          216982 :         if (!am->has(n)) {
     106          200000 :             if (bm->has(n))
     107               0 :                 return false;
     108          200000 :             am->putNew(n, n);
     109          200000 :             bm->putNew(n, n);
     110          200000 :             i++;
     111                 :         }
     112                 :     }
     113              20 :     return true;
     114                 : }
     115                 : 
     116                 : static bool
     117              20 : AddLowKeys(IntSet *as, IntSet *bs, int seed)
     118                 : {
     119              20 :     size_t i = 0;
     120              20 :     srand(seed);
     121          217022 :     while (i < TestSize) {
     122          216982 :         uint32_t n = rand() & 0x0000FFFF;
     123          216982 :         if (!as->has(n)) {
     124          200000 :             if (bs->has(n))
     125               0 :                 return false;
     126          200000 :             as->putNew(n);
     127          200000 :             bs->putNew(n);
     128          200000 :             i++;
     129                 :         }
     130                 :     }
     131              20 :     return true;
     132                 : }
     133                 : 
     134                 : template <class NewKeyFunction>
     135                 : static bool
     136              20 : SlowRekey(IntMap *m) {
     137              40 :     IntMap tmp;
     138              20 :     tmp.init();
     139                 : 
     140          200020 :     for (IntMap::Range r = m->all(); !r.empty(); r.popFront()) {
     141          200000 :         if (NewKeyFunction::shouldBeRemoved(r.front().key))
     142           50026 :             continue;
     143          149974 :         uint32_t hi = NewKeyFunction::rekey(r.front().key);
     144          149974 :         if (tmp.has(hi))
     145               0 :             return false;
     146          149974 :         tmp.putNew(hi, r.front().value);
     147                 :     }
     148                 : 
     149              20 :     m->clear();
     150          149994 :     for (IntMap::Range r = tmp.all(); !r.empty(); r.popFront()) {
     151          149974 :         m->putNew(r.front().key, r.front().value);
     152                 :     }
     153                 : 
     154              20 :     return true;
     155                 : }
     156                 : 
     157                 : template <class NewKeyFunction>
     158                 : static bool
     159              20 : SlowRekey(IntSet *s) {
     160              40 :     IntSet tmp;
     161              20 :     tmp.init();
     162                 : 
     163          200020 :     for (IntSet::Range r = s->all(); !r.empty(); r.popFront()) {
     164          200000 :         if (NewKeyFunction::shouldBeRemoved(r.front()))
     165           50026 :             continue;
     166          149974 :         uint32_t hi = NewKeyFunction::rekey(r.front());
     167          149974 :         if (tmp.has(hi))
     168               0 :             return false;
     169          149974 :         tmp.putNew(hi);
     170                 :     }
     171                 : 
     172              20 :     s->clear();
     173          149994 :     for (IntSet::Range r = tmp.all(); !r.empty(); r.popFront()) {
     174          149974 :         s->putNew(r.front());
     175                 :     }
     176                 : 
     177              20 :     return true;
     178                 : }
     179                 : 
     180               4 : BEGIN_TEST(testHashRekeyManual)
     181                 : {
     182               2 :     IntMap am, bm;
     183               1 :     am.init();
     184               1 :     bm.init();
     185              11 :     for (size_t i = 0; i < TestIterations; ++i) {
     186                 : #ifdef FUZZ
     187                 :         fprintf(stderr, "map1: %lu\n", i);
     188                 : #endif
     189              10 :         CHECK(AddLowKeys(&am, &bm, i));
     190              10 :         CHECK(MapsAreEqual(am, bm));
     191                 : 
     192          135090 :         for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
     193          135080 :             uint32_t tmp = LowToHigh::rekey(e.front().key);
     194          135080 :             if (tmp != e.front().key)
     195           99995 :                 e.rekeyFront(tmp);
     196                 :         }
     197              10 :         CHECK(SlowRekey<LowToHigh>(&bm));
     198                 : 
     199              10 :         CHECK(MapsAreEqual(am, bm));
     200              10 :         am.clear();
     201              10 :         bm.clear();
     202                 :     }
     203                 : 
     204               2 :     IntSet as, bs;
     205               1 :     as.init();
     206               1 :     bs.init();
     207              11 :     for (size_t i = 0; i < TestIterations; ++i) {
     208                 : #ifdef FUZZ
     209                 :         fprintf(stderr, "set1: %lu\n", i);
     210                 : #endif
     211              10 :         CHECK(AddLowKeys(&as, &bs, i));
     212              10 :         CHECK(SetsAreEqual(as, bs));
     213                 : 
     214          135090 :         for (IntSet::Enum e(as); !e.empty(); e.popFront()) {
     215          135080 :             uint32_t tmp = LowToHigh::rekey(e.front());
     216          135080 :             if (tmp != e.front())
     217           99995 :                 e.rekeyFront(tmp);
     218                 :         }
     219              10 :         CHECK(SlowRekey<LowToHigh>(&bs));
     220                 : 
     221              10 :         CHECK(SetsAreEqual(as, bs));
     222              10 :         as.clear();
     223              10 :         bs.clear();
     224                 :     }
     225                 : 
     226               1 :     return true;
     227                 : }
     228               1 : END_TEST(testHashRekeyManual)
     229                 : 
     230               4 : BEGIN_TEST(testHashRekeyManualRemoval)
     231                 : {
     232               2 :     IntMap am, bm;
     233               1 :     am.init();
     234               1 :     bm.init();
     235              11 :     for (size_t i = 0; i < TestIterations; ++i) {
     236                 : #ifdef FUZZ
     237                 :         fprintf(stderr, "map2: %lu\n", i);
     238                 : #endif
     239              10 :         CHECK(AddLowKeys(&am, &bm, i));
     240              10 :         CHECK(MapsAreEqual(am, bm));
     241                 : 
     242          115991 :         for (IntMap::Enum e(am); !e.empty(); e.popFront()) {
     243          115981 :             if (LowToHighWithRemoval::shouldBeRemoved(e.front().key)) {
     244           50026 :                 e.removeFront();
     245                 :             } else {
     246           65955 :                 uint32_t tmp = LowToHighWithRemoval::rekey(e.front().key);
     247           65955 :                 if (tmp != e.front().key)
     248           49974 :                     e.rekeyFront(tmp);
     249                 :             }
     250                 :         }
     251              10 :         CHECK(SlowRekey<LowToHighWithRemoval>(&bm));
     252                 : 
     253              10 :         CHECK(MapsAreEqual(am, bm));
     254              10 :         am.clear();
     255              10 :         bm.clear();
     256                 :     }
     257                 : 
     258               2 :     IntSet as, bs;
     259               1 :     as.init();
     260               1 :     bs.init();
     261              11 :     for (size_t i = 0; i < TestIterations; ++i) {
     262                 : #ifdef FUZZ
     263                 :         fprintf(stderr, "set1: %lu\n", i);
     264                 : #endif
     265              10 :         CHECK(AddLowKeys(&as, &bs, i));
     266              10 :         CHECK(SetsAreEqual(as, bs));
     267                 : 
     268          115991 :         for (IntSet::Enum e(as); !e.empty(); e.popFront()) {
     269          115981 :             if (LowToHighWithRemoval::shouldBeRemoved(e.front())) {
     270           50026 :                 e.removeFront();
     271                 :             } else {
     272           65955 :                 uint32_t tmp = LowToHighWithRemoval::rekey(e.front());
     273           65955 :                 if (tmp != e.front())
     274           49974 :                     e.rekeyFront(tmp);
     275                 :             }
     276                 :         }
     277              10 :         CHECK(SlowRekey<LowToHighWithRemoval>(&bs));
     278                 : 
     279              10 :         CHECK(SetsAreEqual(as, bs));
     280              10 :         as.clear();
     281              10 :         bs.clear();
     282                 :     }
     283                 : 
     284               1 :     return true;
     285                 : }
     286               3 : END_TEST(testHashRekeyManualRemoval)
     287                 : 

Generated by: LCOV version 1.7