LCOV - app.info - js/src/jsapi-tests/testHashTable.cpp

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