Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  TestHashTable.cpp

  Sprache: C
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "mozilla/CompactPair.h"
#include "mozilla/HashTable.h"
#include "mozilla/PairHash.h"

#include <utility>

void TestMoveConstructor() {
  using namespace mozilla;

  HashMap<intint> map;
  MOZ_RELEASE_ASSERT(map.putNew(332));
  MOZ_RELEASE_ASSERT(map.putNew(442));
  MOZ_RELEASE_ASSERT(map.count() == 2);
  MOZ_RELEASE_ASSERT(!map.empty());
  MOZ_RELEASE_ASSERT(!map.lookup(2));
  MOZ_RELEASE_ASSERT(map.lookup(3)->value() == 32);
  MOZ_RELEASE_ASSERT(map.lookup(4)->value() == 42);

  HashMap<intint> moved = std::move(map);
  MOZ_RELEASE_ASSERT(moved.count() == 2);
  MOZ_RELEASE_ASSERT(!moved.empty());
  MOZ_RELEASE_ASSERT(!moved.lookup(2));
  MOZ_RELEASE_ASSERT(moved.lookup(3)->value() == 32);
  MOZ_RELEASE_ASSERT(moved.lookup(4)->value() == 42);

  MOZ_RELEASE_ASSERT(map.empty());
  MOZ_RELEASE_ASSERT(!map.count());
}

void CheckSwapMap1(const mozilla::HashMap<intint>& map1) {
  MOZ_RELEASE_ASSERT(map1.count() == 2);
  MOZ_RELEASE_ASSERT(!map1.empty());
  MOZ_RELEASE_ASSERT(!map1.lookup(3));
  MOZ_RELEASE_ASSERT(!map1.lookup(4));
  MOZ_RELEASE_ASSERT(map1.lookup(1)->value() == 10);
  MOZ_RELEASE_ASSERT(map1.lookup(2)->value() == 20);
}

void CheckSwapMap2(const mozilla::HashMap<intint>& map2) {
  MOZ_RELEASE_ASSERT(map2.count() == 2);
  MOZ_RELEASE_ASSERT(!map2.empty());
  MOZ_RELEASE_ASSERT(!map2.lookup(1));
  MOZ_RELEASE_ASSERT(!map2.lookup(2));
  MOZ_RELEASE_ASSERT(map2.lookup(3)->value() == 30);
  MOZ_RELEASE_ASSERT(map2.lookup(4)->value() == 40);
}

void TestSwap() {
  using namespace mozilla;

  HashMap<intint> map1;
  MOZ_RELEASE_ASSERT(map1.putNew(110));
  MOZ_RELEASE_ASSERT(map1.putNew(220));
  CheckSwapMap1(map1);

  HashMap<intint> map2;
  MOZ_RELEASE_ASSERT(map2.putNew(330));
  MOZ_RELEASE_ASSERT(map2.putNew(440));
  CheckSwapMap2(map2);

  map1.swap(map2);
  CheckSwapMap2(map1);
  CheckSwapMap1(map2);
}

enum SimpleEnum { SIMPLE_1, SIMPLE_2 };

enum class ClassEnum : int {
  CLASS_ENUM_1,
  CLASS_ENUM_2,
};

void TestEnumHash() {
  using namespace mozilla;

  HashMap<SimpleEnum, int> map;
  MOZ_RELEASE_ASSERT(map.put(SIMPLE_1, 1));
  MOZ_RELEASE_ASSERT(map.put(SIMPLE_2, 2));

  MOZ_RELEASE_ASSERT(map.lookup(SIMPLE_1)->value() == 1);
  MOZ_RELEASE_ASSERT(map.lookup(SIMPLE_2)->value() == 2);

  HashMap<ClassEnum, int> map2;
  MOZ_RELEASE_ASSERT(map2.put(ClassEnum::CLASS_ENUM_1, 1));
  MOZ_RELEASE_ASSERT(map2.put(ClassEnum::CLASS_ENUM_2, 2));

  MOZ_RELEASE_ASSERT(map2.lookup(ClassEnum::CLASS_ENUM_1)->value() == 1);
  MOZ_RELEASE_ASSERT(map2.lookup(ClassEnum::CLASS_ENUM_2)->value() == 2);
}

void TestHashPair() {
  using namespace mozilla;

  // Test with std::pair
  {
    HashMap<std::pair<intbool>, int, PairHasher<intbool>> map;
    std::pair<intbool> key1 = std::make_pair(1, true);
    MOZ_RELEASE_ASSERT(map.putNew(key1, 1));
    MOZ_RELEASE_ASSERT(map.has(key1));
    std::pair<intbool> key2 = std::make_pair(1false);
    MOZ_RELEASE_ASSERT(map.putNew(key2, 1));
    std::pair<intbool> key3 = std::make_pair(2false);
    MOZ_RELEASE_ASSERT(map.putNew(key3, 2));
    MOZ_RELEASE_ASSERT(map.has(key3));

    MOZ_RELEASE_ASSERT(map.lookup(key1)->value() == 1);
    MOZ_RELEASE_ASSERT(map.lookup(key2)->value() == 1);
    MOZ_RELEASE_ASSERT(map.lookup(key3)->value() == 2);
  }
  // Test wtih compact pair
  {
    HashMap<mozilla::CompactPair<intbool>, int, CompactPairHasher<intbool>>
        map;
    mozilla::CompactPair<intbool> key1 = mozilla::MakeCompactPair(1, true);
    MOZ_RELEASE_ASSERT(map.putNew(key1, 1));
    MOZ_RELEASE_ASSERT(map.has(key1));
    mozilla::CompactPair<intbool> key2 = mozilla::MakeCompactPair(1false);
    MOZ_RELEASE_ASSERT(map.putNew(key2, 1));
    mozilla::CompactPair<intbool> key3 = mozilla::MakeCompactPair(2false);
    MOZ_RELEASE_ASSERT(map.putNew(key3, 2));
    MOZ_RELEASE_ASSERT(map.has(key3));

    MOZ_RELEASE_ASSERT(map.lookup(key1)->value() == 1);
    MOZ_RELEASE_ASSERT(map.lookup(key2)->value() == 1);
    MOZ_RELEASE_ASSERT(map.lookup(key3)->value() == 2);
  }
}

void TestRekey() {
  using namespace mozilla;

  HashMap<intint> map;
  MOZ_RELEASE_ASSERT(map.putNew(110));
  MOZ_RELEASE_ASSERT(map.putNew(220));
  MOZ_RELEASE_ASSERT(map.putNew(330));

  // rekeyIfMoved: same key is a no-op.
  map.rekeyIfMoved(11);
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(map.lookup(1)->value() == 10);

  // rekeyIfMoved: replace an existing key.
  map.rekeyIfMoved(111);
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(1));
  MOZ_RELEASE_ASSERT(map.lookup(11)->value() == 10);

  // rekeyIfMoved on a missing key is a no-op.
  map.rekeyIfMoved(99100);
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(99));
  MOZ_RELEASE_ASSERT(!map.lookup(100));

  // rekeyAs: returns true and replaces key when present.
  MOZ_RELEASE_ASSERT(map.rekeyAs(22222));
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(2));
  MOZ_RELEASE_ASSERT(map.lookup(22)->value() == 20);

  // rekeyAs: returns false when the old key is absent.
  MOZ_RELEASE_ASSERT(!map.rekeyAs(22323));
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(23));

  // Other entries are unaffected.
  MOZ_RELEASE_ASSERT(map.lookup(3)->value() == 30);
}

// A structure that holds an int and supports move semantics but not copy
// semantics.
struct WrappedInt {
  int mValue;

  explicit WrappedInt(int v) : mValue(v) {}

  WrappedInt(const WrappedInt&) = delete;
  WrappedInt& operator=(const WrappedInt&) = delete;

  WrappedInt(WrappedInt&& aOther) : mValue(aOther.mValue) { aOther.mValue = 0; }
  WrappedInt& operator=(WrappedInt&& aOther) {
    mValue = aOther.mValue;
    aOther.mValue = 0;
    return *this;
  }

  struct HashPolicy {
    using Key = WrappedInt;
    using Lookup = int;

    static mozilla::HashNumber hash(Lookup aLookup) { return aLookup; }

    static bool match(const Key& aKey, Lookup aLookup) {
      return aKey.mValue == aLookup;
    }

    static void rekey(Key& aKey, Key&& aNewKey) { aKey = std::move(aNewKey); }
  };
};

void TestRekeyWithRValue() {
  using namespace mozilla;

  HashMap<WrappedInt, int, WrappedInt::HashPolicy> map;
  MOZ_RELEASE_ASSERT(map.putNew(110));
  MOZ_RELEASE_ASSERT(map.putNew(220));
  MOZ_RELEASE_ASSERT(map.putNew(330));

  // rekeyAs: replace an existing key.
  map.rekeyAs(111, WrappedInt(11));
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(1));
  MOZ_RELEASE_ASSERT(map.lookup(11)->value() == 10);

  // rekeyAs on a missing key is a no-op.
  MOZ_RELEASE_ASSERT(!map.rekeyAs(99100, WrappedInt(100)));
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(99));
  MOZ_RELEASE_ASSERT(!map.lookup(100));

  // rekeyAs: returns true and replaces key when present.
  MOZ_RELEASE_ASSERT(map.rekeyAs(222, WrappedInt(22)));
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(2));
  MOZ_RELEASE_ASSERT(map.lookup(22)->value() == 20);

  // rekeyAs: returns false when the old key is absent.
  MOZ_RELEASE_ASSERT(!map.rekeyAs(223, WrappedInt(23)));
  MOZ_RELEASE_ASSERT(map.count() == 3);
  MOZ_RELEASE_ASSERT(!map.lookup(23));

  // Other entries are unaffected.
  MOZ_RELEASE_ASSERT(map.lookup(3)->value() == 30);
}

void TestModIteratorRekey() {
  using namespace mozilla;

  // Rekey one entry found during iteration.
  {
    HashMap<intint> map;
    MOZ_RELEASE_ASSERT(map.putNew(110));
    MOZ_RELEASE_ASSERT(map.putNew(220));
    MOZ_RELEASE_ASSERT(map.putNew(330));

    for (auto iter = map.modIter(); !iter.done(); iter.next()) {
      if (iter.get().key() == 2) {
        iter.rekey(22);
      }
    }

    MOZ_RELEASE_ASSERT(map.count() == 3);
    MOZ_RELEASE_ASSERT(!map.lookup(2));
    MOZ_RELEASE_ASSERT(map.lookup(22)->value() == 20);
    MOZ_RELEASE_ASSERT(map.lookup(1)->value() == 10);
    MOZ_RELEASE_ASSERT(map.lookup(3)->value() == 30);
  }

  // Rekey multiple entries.
  {
    HashMap<intint> map;
    MOZ_RELEASE_ASSERT(map.putNew(110));
    MOZ_RELEASE_ASSERT(map.putNew(220));
    MOZ_RELEASE_ASSERT(map.putNew(330));

    for (auto iter = map.modIter(); !iter.done(); iter.next()) {
      int key = iter.get().key();
      if (key > 0) {
        iter.rekey(-key);
      }
    }

    MOZ_RELEASE_ASSERT(map.count() == 3);
    MOZ_RELEASE_ASSERT(!map.lookup(1));
    MOZ_RELEASE_ASSERT(!map.lookup(2));
    MOZ_RELEASE_ASSERT(!map.lookup(3));
    MOZ_RELEASE_ASSERT(map.lookup(-1)->value() == 10);
    MOZ_RELEASE_ASSERT(map.lookup(-2)->value() == 20);
    MOZ_RELEASE_ASSERT(map.lookup(-3)->value() == 30);
  }
}

void TestCapacityAfterRemove() {
  mozilla::HashMap<intint> map;
  MOZ_RELEASE_ASSERT(map.count() == 0);
  MOZ_RELEASE_ASSERT(map.capacity() == 0);

  MOZ_RELEASE_ASSERT(map.putNew(11));
  MOZ_RELEASE_ASSERT(map.count() == 1);
  MOZ_RELEASE_ASSERT(map.capacity() != 0);

  map.remove(1);
  MOZ_RELEASE_ASSERT(map.count() == 0);
  MOZ_RELEASE_ASSERT(map.capacity() != 0);

  map.compact();
  MOZ_RELEASE_ASSERT(map.count() == 0);
  MOZ_RELEASE_ASSERT(map.capacity() == 0);

  MOZ_RELEASE_ASSERT(map.putNew(11));
  MOZ_RELEASE_ASSERT(map.count() == 1);
  MOZ_RELEASE_ASSERT(map.capacity() != 0);

  {
    auto iter = map.modIter();
    MOZ_RELEASE_ASSERT(!iter.done());
    iter.remove();
  }
  MOZ_RELEASE_ASSERT(map.count() == 0);
  MOZ_RELEASE_ASSERT(map.capacity() != 0);

  map.compact();
  MOZ_RELEASE_ASSERT(map.count() == 0);
  MOZ_RELEASE_ASSERT(map.capacity() == 0);
}

int main() {
  TestMoveConstructor();
  TestEnumHash();
  TestHashPair();
  TestRekey();
  TestRekeyWithRValue();
  TestModIteratorRekey();
  TestCapacityAfterRemove();
  return 0;
}

Messung V0.5 in Prozent
C=95 H=93 G=93

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002