// Copyright 2023 PingCAP, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include template struct StringHashSetCell : public HashTableCell { using Base = HashTableCell; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; }; template <> struct StringHashSetCell : public HashTableCell { using Base = HashTableCell; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; bool isZero(const HashTableNoState & state) const { return isZero(this->key, state); } // Zero means unoccupied cells in hash table. Use key with last word = 0 as // zero keys, because such keys are unrepresentable (no way to encode length). static bool isZero(const StringKey16 & key_, const HashTableNoState &) { return key_ == 0; } void setZero() { this->key = 0; } }; template <> struct StringHashSetCell : public HashTableCell { using Base = HashTableCell; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; bool isZero(const HashTableNoState & state) const { return isZero(this->key, state); } // Zero means unoccupied cells in hash table. Use key with last word = 0 as // zero keys, because such keys are unrepresentable (no way to encode length). static bool isZero(const StringKey24 & key_, const HashTableNoState &) { return key_.c == 0; } void setZero() { this->key.c = 0; } }; template <> struct StringHashSetCell : public HashSetCellWithSavedHash { using Base = HashSetCellWithSavedHash; using Base::Base; VoidMapped void_map; VoidMapped & getMapped() { return void_map; } const VoidMapped & getMapped() const { return void_map; } static constexpr bool need_zero_value_storage = false; }; template struct StringHashSetSubMaps { using T0 = StringHashTableEmpty>; using T1 = HashSetTable< StringKey8, StringHashSetCell, StringHashTableHash, StringHashTableGrower<>, Allocator>; using T2 = HashSetTable< StringKey16, StringHashSetCell, StringHashTableHash, StringHashTableGrower<>, Allocator>; using T3 = HashSetTable< StringKey24, StringHashSetCell, StringHashTableHash, StringHashTableGrower<>, Allocator>; using Ts = HashSetTable< StringRef, StringHashSetCell, StringHashTableHash, StringHashTableGrower<>, Allocator>; }; template class StringHashSet : public StringHashTable> { public: using Key = StringRef; using Base = StringHashTable>; using Self = StringHashSet; using LookupResult = typename Base::LookupResult; using Base::Base; template void ALWAYS_INLINE emplace(KeyHolder && key_holder, bool & inserted) { LookupResult it; Base::emplace(key_holder, it, inserted); } };