1 2 /** 3 * Copyright (C) 2018-present MongoDB, Inc. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the Server Side Public License, version 1, 7 * as published by MongoDB, Inc. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Server Side Public License for more details. 13 * 14 * You should have received a copy of the Server Side Public License 15 * along with this program. If not, see 16 * <http://www.mongodb.com/licensing/server-side-public-license>. 17 * 18 * As a special exception, the copyright holders give permission to link the 19 * code of portions of this program with the OpenSSL library under certain 20 * conditions as described in each individual source file and distribute 21 * linked combinations including the program with the OpenSSL library. You 22 * must comply with the Server Side Public License in all respects for 23 * all of the code used other than as permitted herein. If you modify file(s) 24 * with this exception, you may extend this exception to your version of the 25 * file(s), but you are not obligated to do so. If you do not wish to do so, 26 * delete this exception statement from your version. If you delete this 27 * exception statement from all source files in the program, then also delete 28 * it in the license file. 29 */ 30 31 #pragma once 32 33 #include "mongo/base/disallow_copying.h" 34 #include "mongo/stdx/unordered_map.h" 35 #include "mongo/stdx/unordered_set.h" 36 #include "string_data.h" 37 38 namespace mongo { 39 40 /** 41 * A StringData::ComparatorInterface is an abstract class for comparing StringData objects. 42 */ 43 class StringData::ComparatorInterface { 44 MONGO_DISALLOW_COPYING(ComparatorInterface); 45 46 public: 47 /** 48 * Functor for checking string equality under this comparator. Compatible for use with unordered 49 * STL containers. 50 */ 51 class EqualTo { 52 public: EqualTo(const ComparatorInterface * stringComparator)53 explicit EqualTo(const ComparatorInterface* stringComparator) 54 : _stringComparator(stringComparator) {} 55 operator()56 bool operator()(StringData lhs, StringData rhs) const { 57 return _stringComparator->compare(lhs, rhs) == 0; 58 } 59 60 private: 61 const ComparatorInterface* _stringComparator; 62 }; 63 64 /** 65 * Functor for hashing strings under this comparator. Compatible for use with unordered STL 66 * containers. 67 */ 68 class Hasher { 69 public: Hasher(const ComparatorInterface * stringComparator)70 explicit Hasher(const ComparatorInterface* stringComparator) 71 : _stringComparator(stringComparator) {} 72 operator()73 size_t operator()(StringData stringToHash) const { 74 return _stringComparator->hash(stringToHash); 75 } 76 77 private: 78 const ComparatorInterface* _stringComparator; 79 }; 80 81 using StringDataUnorderedSet = stdx::unordered_set<StringData, Hasher, EqualTo>; 82 83 template <typename T> 84 using StringDataUnorderedMap = stdx::unordered_map<StringData, T, Hasher, EqualTo>; 85 86 ComparatorInterface() = default; 87 88 virtual ~ComparatorInterface() = default; 89 90 /** 91 * Compares two StringData objects. 92 */ 93 virtual int compare(StringData left, StringData right) const = 0; 94 95 /** 96 * Hash a StringData in a way that respects this comparator. 97 */ hash(StringData stringToHash)98 size_t hash(StringData stringToHash) const { 99 size_t seed = 0; 100 hash_combine(seed, stringToHash); 101 return seed; 102 } 103 104 /** 105 * Hash a StringData in a way that respects this comparator, and return the result in the 'seed' 106 * in-out parameter. 107 */ 108 virtual void hash_combine(size_t& seed, StringData stringToHash) const = 0; 109 110 /** 111 * Returns a function object which can evaluate string equality according to this comparator. 112 * This comparator must outlive the returned function object. 113 */ makeEqualTo()114 EqualTo makeEqualTo() const { 115 return EqualTo(this); 116 } 117 118 /** 119 * Returns a function object which can hash strings according to this comparator. This 120 * comparator must outlive the returned function object. 121 */ makeHasher()122 Hasher makeHasher() const { 123 return Hasher(this); 124 } 125 126 /** 127 * Construct an empty unordered set of StringData whose equivalence classes are given by this 128 * comparator. This comparator must outlive the returned set. 129 */ makeStringDataUnorderedSet()130 StringDataUnorderedSet makeStringDataUnorderedSet() const { 131 return StringDataUnorderedSet(0, makeHasher(), makeEqualTo()); 132 } 133 134 /** 135 * Construct an empty unordered map from StringData to type T whose equivalence classes are 136 * given by this comparator. This comparator must outlive the returned set. 137 */ 138 template <typename T> makeStringDataUnorderedMap()139 StringDataUnorderedMap<T> makeStringDataUnorderedMap() const { 140 return StringDataUnorderedMap<T>(0, makeHasher(), makeEqualTo()); 141 } 142 }; 143 144 using StringDataUnorderedSet = StringData::ComparatorInterface::StringDataUnorderedSet; 145 146 template <typename T> 147 using StringDataUnorderedMap = StringData::ComparatorInterface::StringDataUnorderedMap<T>; 148 149 } // namespace mongo 150