Kajetan Johannes Hammerle il y a 2 mois
Parent
commit
8751750989
2 fichiers modifiés avec 0 ajouts et 712 suppressions
  1. 0 396
      old/HashMapTests.cpp
  2. 0 316
      old/ProbingHashMap.hpp

+ 0 - 396
old/HashMapTests.cpp

@@ -1,396 +0,0 @@
-#include "../Tests.hpp"
-#include "core/data/HashMap.hpp"
-#include "core/data/ProbingHashMap.hpp"
-
-template struct Core::ProbingHashMap<int, int>;
-using ProbingIntMap = Core::ProbingHashMap<int, int>;
-template struct Core::HashMap<int, int>;
-using IntMap = Core::HashMap<int, int>;
-
-constexpr int INVALID = Core::emptyValue<int>();
-
-template<typename T>
-static T getTestIntMap() {
-    T map;
-    map.add(1, 3).add(2, 4).add(3, 5).add(INVALID, 20);
-    return map;
-}
-
-template<typename T>
-static void checkIntMap(T& map) {
-    int* a = map.search(1);
-    int* b = map.search(2);
-    int* c = map.search(3);
-    int* d = map.search(INVALID);
-    if(CORE_TEST_NOT_NULL(a) && CORE_TEST_NOT_NULL(b) &&
-       CORE_TEST_NOT_NULL(c) && CORE_TEST_NOT_NULL(d)) {
-        CORE_TEST_EQUAL(3, *a);
-        CORE_TEST_EQUAL(4, *b);
-        CORE_TEST_EQUAL(5, *c);
-        CORE_TEST_EQUAL(20, *d);
-    }
-}
-
-template<typename T>
-static void testAdd() {
-    T map;
-    map.add(5, 4);
-    int* value = map.search(5);
-    CORE_TEST_NOT_NULL(value);
-    if(value != nullptr) {
-        CORE_TEST_EQUAL(4, *value);
-    }
-}
-
-template<typename T>
-static void testMultipleAdd() {
-    T map = getTestIntMap<T>();
-    CORE_TEST_TRUE(map.contains(1));
-    CORE_TEST_TRUE(map.contains(2));
-    CORE_TEST_TRUE(map.contains(3));
-    checkIntMap(map);
-}
-
-template<typename T>
-static void testSearch() {
-    T map;
-    CORE_TEST_NULL(map.search(6));
-    map.add(5, 4).add(10, 3).add(15, 2);
-    CORE_TEST_NULL(map.search(6));
-}
-
-template<typename T>
-static void testAddReplace() {
-    T map;
-    map.add(5, 4).add(5, 10);
-    CORE_TEST_TRUE(map.contains(5));
-    int* a = map.search(5);
-    if(CORE_TEST_NOT_NULL(a)) {
-        CORE_TEST_EQUAL(10, *a);
-    }
-}
-
-template<typename T>
-static void testClear() {
-    T map;
-    map.add(5, 4).add(4, 10);
-    map.clear();
-    CORE_TEST_FALSE(map.contains(5));
-    CORE_TEST_FALSE(map.contains(4));
-}
-
-template<typename T>
-static void testOverflow(bool light) {
-    int limit = light ? 10'000 : 100'000;
-    T map;
-    map.add(INVALID, 42);
-    for(int i = 0; i < limit; i++) {
-        map.add(i, i);
-    }
-    for(int i = 0; i < limit; i++) {
-        CORE_TEST_TRUE(map.contains(i));
-    }
-    CORE_TEST_TRUE(map.contains(INVALID));
-}
-
-static int aInstances = 0;
-
-struct HashMapTest {
-    int a;
-    int b;
-
-    HashMapTest(int a_, int b_) : a(a_), b(b_) {
-    }
-
-    // none of these should be needed for the hashmap
-    HashMapTest(const HashMapTest&) = delete;
-    HashMapTest(HashMapTest&&) = delete;
-    HashMapTest& operator=(const HashMapTest&) = delete;
-    HashMapTest& operator=(HashMapTest&&) = delete;
-
-    bool operator==(const HashMapTest& other) const {
-        return a == other.a && b == other.b;
-    }
-
-    template<typename String>
-    void toString(String& s) const {
-        s.append("A(").append(a).append(", ").append(b).append(")");
-    }
-};
-
-struct ProbingTest final : public HashMapTest {
-    ProbingTest(int a_, int b_) : HashMapTest(a_, b_) {
-        aInstances++;
-    }
-
-    ProbingTest(const ProbingTest& o) : HashMapTest(o.a, o.b) {
-        aInstances++;
-    }
-
-    ProbingTest(ProbingTest&& o) : HashMapTest(o.a, o.b) {
-        aInstances++;
-    }
-
-    ~ProbingTest() {
-        aInstances--;
-    }
-
-    ProbingTest& operator=(ProbingTest o) {
-        a = o.a;
-        b = o.b;
-        return *this;
-    }
-};
-
-static void testEmplaceProbing() {
-    {
-        Core::ProbingHashMap<int, ProbingTest> map;
-
-        ProbingTest* ar = nullptr;
-        CORE_TEST_TRUE(map.tryEmplace(ar, 0, 3, 4));
-        CORE_TEST_TRUE(map.tryEmplace(ar, 3, 4, 5));
-        CORE_TEST_TRUE(map.tryEmplace(ar, 20, 5, 6));
-        CORE_TEST_FALSE(map.tryEmplace(ar, 3, 6, 7));
-        CORE_TEST_FALSE(map.tryEmplace(ar, 20, 7, 8));
-
-        ProbingTest* a = map.search(0);
-        ProbingTest* b = map.search(3);
-        ProbingTest* c = map.search(20);
-
-        if(CORE_TEST_NOT_NULL(a) && CORE_TEST_NOT_NULL(b) &&
-           CORE_TEST_NOT_NULL(c)) {
-            CORE_TEST_EQUAL(ProbingTest(3, 4), *a);
-            CORE_TEST_EQUAL(ProbingTest(4, 5), *b);
-            CORE_TEST_EQUAL(ProbingTest(5, 6), *c);
-        }
-    }
-    CORE_TEST_EQUAL(0, aInstances);
-}
-
-template<typename T>
-static void testToString() {
-    if constexpr(Core::IsSame<T, IntMap>) {
-        CORE_TEST_STRING(
-            "[1 = 3, 2 = 4, 3 = 5, 2147483647 = 20]", getTestIntMap<T>());
-    } else {
-        CORE_TEST_STRING(
-            "[2 = 4, 1 = 3, 3 = 5, 2147483647 = 20]", getTestIntMap<T>());
-    }
-    CORE_TEST_STRING("[1 = 3]", T().add(1, 3));
-    CORE_TEST_STRING("[]", T());
-}
-
-template<typename T>
-static void testCopy() {
-    T map = getTestIntMap<T>();
-    T copy = map;
-    T copyA;
-    copyA = map;
-    checkIntMap(map);
-    checkIntMap(copy);
-    checkIntMap(copyA);
-    map.add(1, 20).add(2, 30).add(3, 40);
-    checkIntMap(copy);
-    checkIntMap(copyA);
-}
-
-template<typename T>
-static void testMove() {
-    T map = getTestIntMap<T>();
-    T move(Core::move(map));
-    checkIntMap(move);
-}
-
-template<typename T>
-static void testMoveAssignment() {
-    T map = getTestIntMap<T>();
-    T move;
-    move = Core::move(map);
-    checkIntMap(move);
-}
-
-template<typename T>
-static void testEntryForEach() {
-    T map;
-    map.add(5, 4).add(10, 3).add(15, 2);
-
-    int counter = 0;
-    for(auto entry : map) {
-        counter += entry.getKey() + entry.value;
-    }
-    CORE_TEST_EQUAL(39, counter);
-
-    const T& cmap = map;
-    counter = 0;
-    for(auto entry : cmap) {
-        counter += entry.getKey() + entry.value;
-    }
-    CORE_TEST_EQUAL(39, counter);
-}
-
-template<typename T>
-static void testKeyForEach() {
-    T map;
-    map.add(5, 4).add(10, 3).add(15, 2);
-
-    int counter = 0;
-    for(const int& key : map.getKeys()) {
-        counter += key;
-    }
-    CORE_TEST_EQUAL(30, counter);
-
-    const T& cmap = map;
-    counter = 0;
-    for(const int& key : cmap.getKeys()) {
-        counter += key;
-    }
-    CORE_TEST_EQUAL(30, counter);
-}
-
-template<typename T>
-static void testValueForEach() {
-    T map;
-    map.add(5, 4).add(10, 3).add(15, 2);
-
-    int counter = 0;
-    for(int& value : map.getValues()) {
-        counter += value;
-    }
-    CORE_TEST_EQUAL(9, counter);
-
-    const T& cmap = map;
-    counter = 0;
-    for(const int& value : cmap.getValues()) {
-        counter += value;
-    }
-    CORE_TEST_EQUAL(9, counter);
-}
-
-template<typename T>
-static void testType() {
-    Core::ProbingHashMap<T, int> m;
-    m.add(T(), 3);
-}
-
-template<typename T>
-static void testTypes() {
-    testType<char>();
-    testType<signed char>();
-    testType<signed short>();
-    testType<signed int>();
-    testType<signed long>();
-    testType<signed long long>();
-    testType<unsigned char>();
-    testType<unsigned short>();
-    testType<unsigned int>();
-    testType<unsigned long>();
-    testType<unsigned long long>();
-}
-
-template<typename T>
-static void testInvalid() {
-    T map;
-    int* v;
-    CORE_TEST_TRUE(map.tryEmplace(v, INVALID, 2));
-    if(CORE_TEST_NOT_NULL(v)) {
-        CORE_TEST_EQUAL(2, *v);
-    }
-    CORE_TEST_FALSE(map.tryEmplace(v, INVALID, 6));
-    if(CORE_TEST_NOT_NULL(v)) {
-        CORE_TEST_EQUAL(2, *v);
-    }
-    CORE_TEST_EQUAL(3, map.put(INVALID, 3));
-    v = map.search(INVALID);
-    if(CORE_TEST_NOT_NULL(v)) {
-        CORE_TEST_EQUAL(3, *v);
-    }
-    map.clear();
-    CORE_TEST_NULL(map.search(INVALID));
-}
-
-template<typename T>
-static void testInvalidPut() {
-    T map;
-    CORE_TEST_EQUAL(3, map.put(INVALID, 3));
-    int* v = map.search(INVALID);
-    if(CORE_TEST_NOT_NULL(v)) {
-        CORE_TEST_EQUAL(3, *v);
-    }
-}
-
-template<typename T>
-static void testAddCollisions() {
-    T map;
-    for(int i = 0; i < 8; i++) {
-        map.add(i * 16, i);
-    }
-}
-
-template<typename T>
-static void testMap(bool light) {
-    testAdd<T>();
-    testMultipleAdd<T>();
-    testSearch<T>();
-    testAddReplace<T>();
-    testClear<T>();
-    testOverflow<T>(light);
-    testToString<T>();
-    testCopy<T>();
-    testMove<T>();
-    testMoveAssignment<T>();
-    testEntryForEach<T>();
-    testKeyForEach<T>();
-    testValueForEach<T>();
-    testTypes<T>();
-    testInvalid<T>();
-    testInvalidPut<T>();
-    testAddCollisions<T>();
-}
-
-static void testEmplace() {
-    Core::HashMap<int, HashMapTest> map;
-
-    HashMapTest* ar = nullptr;
-    CORE_TEST_TRUE(map.tryEmplace(ar, 0, 3, 4));
-    CORE_TEST_TRUE(map.tryEmplace(ar, 3, 4, 5));
-    CORE_TEST_TRUE(map.tryEmplace(ar, 20, 5, 6));
-    CORE_TEST_FALSE(map.tryEmplace(ar, 3, 6, 7));
-    CORE_TEST_FALSE(map.tryEmplace(ar, 20, 7, 8));
-
-    HashMapTest* a = map.search(0);
-    HashMapTest* b = map.search(3);
-    HashMapTest* c = map.search(20);
-
-    if(CORE_TEST_NOT_NULL(a) && CORE_TEST_NOT_NULL(b) &&
-       CORE_TEST_NOT_NULL(c)) {
-        CORE_TEST_EQUAL(HashMapTest(3, 4), *a);
-        CORE_TEST_EQUAL(HashMapTest(4, 5), *b);
-        CORE_TEST_EQUAL(HashMapTest(5, 6), *c);
-    }
-}
-
-static void testRemove() {
-    IntMap map;
-    map.add(1, 3).add(2, 4).add(3, 5);
-
-    CORE_TEST_TRUE(map.remove(2));
-    CORE_TEST_FALSE(map.remove(7));
-
-    int* a = map.search(1);
-    int* b = map.search(2);
-    int* c = map.search(3);
-
-    CORE_TEST_NULL(b);
-    if(CORE_TEST_NOT_NULL(a) && CORE_TEST_NOT_NULL(c)) {
-        CORE_TEST_EQUAL(3, *a);
-        CORE_TEST_EQUAL(5, *c);
-    }
-}
-
-void Core::testHashMap(bool light) {
-    testMap<ProbingIntMap>(light);
-    testMap<IntMap>(light);
-    testEmplace();
-    testEmplaceProbing();
-    testRemove();
-}

+ 0 - 316
old/ProbingHashMap.hpp

@@ -1,316 +0,0 @@
-#ifndef CORE_PROBING_HASHMAP_HPP
-#define CORE_PROBING_HASHMAP_HPP
-
-#include "core/data/List.hpp"
-#include "core/utils/ArrayString.hpp"
-#include "core/utils/HashCode.hpp"
-#include "core/utils/New.hpp"
-#include "core/utils/Types.hpp"
-
-namespace Core {
-    template<typename K, typename V>
-    struct ProbingHashMap final {
-        template<typename Value>
-        class Node final {
-            friend ProbingHashMap;
-            friend List<Node>;
-            K key;
-
-        public:
-            Value& value;
-
-            const K& getKey() const {
-                return key;
-            }
-
-            void toString(BufferString& s) const {
-                s.append(key).append(" = ").append(value);
-            }
-
-        private:
-            Node(const K& key_, Value& value_) : key(key_), value(value_) {
-            }
-        };
-
-    private:
-        static constexpr K INVALID = emptyValue<K>();
-
-        template<typename Value, typename R, R (*A)(const K&, Value&)>
-        class Iterator final {
-            const K* currentKey;
-            const K* endKey;
-            Value* currentValue;
-
-        public:
-            Iterator(const K* key, const K* endKey_, Value* value)
-                : currentKey(key), endKey(endKey_), currentValue(value) {
-                skip();
-            }
-
-            Iterator& operator++() {
-                ++currentKey;
-                ++currentValue;
-                skip();
-                return *this;
-            }
-
-            bool operator!=(const Iterator& other) const {
-                return currentKey != other.currentKey;
-            }
-
-            R operator*() const {
-                return A(*currentKey, *currentValue);
-            }
-
-        private:
-            void skip() {
-                while(currentKey != endKey && !((*currentKey != INVALID) !=
-                                                (currentKey + 1 == endKey))) {
-                    ++currentKey;
-                    ++currentValue;
-                }
-            }
-        };
-
-        template<typename Value>
-        static Node<Value> access(const K& key, Value& value) {
-            return Node<Value>(key, value);
-        }
-
-        template<typename Value>
-        static Value& accessValue(const K&, Value& value) {
-            return value;
-        }
-
-        static const K& accessKey(const K& key, const V&) {
-            return key;
-        }
-
-        template<typename Value>
-        using BaseEntryIterator = Iterator<Value, Node<Value>, access<Value>>;
-        using EntryIterator = BaseEntryIterator<V>;
-        using ConstEntryIterator = BaseEntryIterator<const V>;
-
-        template<typename Value>
-        using BaseValueIterator = Iterator<Value, Value&, accessValue<Value>>;
-        using ValueIterator = BaseValueIterator<V>;
-        using ConstValueIterator = BaseValueIterator<const V>;
-
-        using ConstKeyIterator = Iterator<const V, const K&, accessKey>;
-
-        template<typename M, typename I>
-        struct IteratorAdapter final {
-            M& map;
-
-            I begin() const {
-                return {map.keys.begin(), map.keys.end(), map.values};
-            }
-
-            I end() const {
-                return {map.keys.end(), map.keys.end(), nullptr};
-            }
-        };
-
-        using ValueIteratorAdapter =
-            IteratorAdapter<ProbingHashMap, ValueIterator>;
-        using ConstValueIteratorAdapter =
-            IteratorAdapter<const ProbingHashMap, ConstValueIterator>;
-
-        using ConstKeyIteratorAdapter =
-            IteratorAdapter<const ProbingHashMap, ConstKeyIterator>;
-
-    private:
-        List<K> keys{};
-        V* values = nullptr;
-        size_t entries = 0;
-
-    public:
-        ProbingHashMap() = default;
-
-        ProbingHashMap(const ProbingHashMap& other) {
-            for(const auto& e : other) {
-                add(e.getKey(), e.value);
-            }
-        }
-
-        ProbingHashMap(ProbingHashMap&& other) {
-            swap(other);
-        }
-
-        ~ProbingHashMap() {
-            size_t length = keys.getLength();
-            if(length > 0) {
-                length--;
-                for(size_t i = 0; i < length; i++) {
-                    if(keys[i] != INVALID) {
-                        values[i].~V();
-                    }
-                }
-                if(keys[length] == INVALID) {
-                    values[length].~V();
-                }
-            }
-            delete[] reinterpret_cast<AlignedType<V>*>(values);
-        }
-
-        ProbingHashMap& operator=(ProbingHashMap other) {
-            swap(other);
-            return *this;
-        }
-
-        void rehash(size_t minCapacity) {
-            if(minCapacity <= keys.getLength()) {
-                return;
-            }
-            ProbingHashMap<K, V> map;
-            size_t l =
-                (1lu << Math::roundUpLog2(Math::max(minCapacity, 8lu))) + 1;
-            map.keys.resize(l, INVALID);
-            map.keys[map.keys.getLength() - 1] = K();
-            map.values = reinterpret_cast<V*>(new(noThrow) AlignedType<V>[l]);
-            size_t length = keys.getLength();
-            if(length > 0) {
-                length--;
-                for(size_t i = 0; i < length; i++) {
-                    if(keys[i] != INVALID) {
-                        map.add(keys[i], values[i]);
-                    }
-                }
-                if(keys[length] == INVALID) {
-                    map.add(keys[length], values[length]);
-                }
-            }
-            swap(map);
-        }
-
-        template<typename... Args>
-        bool tryEmplace(V*& v, const K& key, Args&&... args) {
-            size_t index = searchSlot(key);
-            if(keys[index] == key) {
-                return false;
-            }
-            keys[index] = key;
-            v = new(values + index) V(Core::forward<Args>(args)...);
-            entries++;
-            return true;
-        }
-
-        template<typename VA>
-        V& put(const K& key, VA&& value) {
-            size_t index = searchSlot(key);
-            if(keys[index] == key) {
-                return (values[index] = Core::forward<VA>(value));
-            }
-            new(values + index) V(Core::forward<VA>(value));
-            entries++;
-            keys[index] = key;
-            return values[index];
-        }
-
-        template<typename VA>
-        ProbingHashMap& add(const K& key, VA&& value) {
-            put(key, Core::forward<VA>(value));
-            return *this;
-        }
-
-        const V* search(const K& key) const {
-            return searchValue<const V>(key);
-        }
-
-        V* search(const K& key) {
-            return searchValue<V>(key);
-        }
-
-        bool contains(const K& key) const {
-            return search(key) != nullptr;
-        }
-
-        ProbingHashMap& clear() {
-            ProbingHashMap<K, V> map;
-            swap(map);
-            return *this;
-        }
-
-        ConstKeyIteratorAdapter getKeys() const {
-            return {*this};
-        }
-
-        ValueIteratorAdapter getValues() {
-            return {*this};
-        }
-
-        ConstValueIteratorAdapter getValues() const {
-            return {*this};
-        }
-
-        EntryIterator begin() {
-            return {keys.begin(), keys.end(), values};
-        }
-
-        EntryIterator end() {
-            return {keys.end(), keys.end(), nullptr};
-        }
-
-        ConstEntryIterator begin() const {
-            return {keys.begin(), keys.end(), values};
-        }
-
-        ConstEntryIterator end() const {
-            return {keys.end(), keys.end(), nullptr};
-        }
-
-        void toString(BufferString& s) const {
-            Core::toString(s, *this);
-        }
-
-        void swap(ProbingHashMap& o) {
-            Core::swap(o.keys, keys);
-            Core::swap(o.values, values);
-            Core::swap(o.entries, entries);
-        }
-
-    private:
-        size_t searchSlot(const K& key) {
-            size_t rehashFactor = 2;
-            while(true) {
-                rehash(entries * rehashFactor + 1);
-                if(key == INVALID) {
-                    return keys.getLength() - 1;
-                }
-                size_t baseHash = hashCode(key) * 514685581u;
-                size_t end = keys.getLength() - 2;
-                // rehash on bad clustering
-                for(size_t i = 0; i <= 5; i++) {
-                    size_t hash = (baseHash + i) & end;
-                    if(keys[hash] == INVALID || keys[hash] == key) {
-                        return hash;
-                    }
-                }
-                rehashFactor *= 2;
-            }
-        }
-
-        template<typename Value>
-        Value* searchValue(const K& key) const {
-            if(keys.getLength() != 0) {
-                if(key == INVALID) {
-                    size_t i = keys.getLength() - 1;
-                    return keys[i] == INVALID ? values + i : nullptr;
-                }
-                size_t baseHash = hashCode(key) * 514685581u;
-                size_t end = keys.getLength() - 2;
-                for(size_t i = 0; i <= end; i++) [[unlikely]] {
-                    size_t hash = (baseHash + i) & end;
-                    if(keys[hash] == key) [[likely]] {
-                        return values + hash;
-                    } else if(keys[hash] == INVALID) {
-                        return nullptr;
-                    }
-                }
-            }
-            return nullptr;
-        }
-    };
-}
-
-#endif