/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 **/

#ifndef QUICKSTEP_STORAGE_TESTS_HASHTABLE_UNITTEST_COMMON_HPP_
#define QUICKSTEP_STORAGE_TESTS_HASHTABLE_UNITTEST_COMMON_HPP_

#include <algorithm>
#include <atomic>
#include <bitset>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <sstream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "gtest/gtest.h"

#include "catalog/CatalogTypedefs.hpp"
#include "storage/HashTable.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageConstants.hpp"
#include "storage/StorageManager.hpp"
#include "threading/Thread.hpp"
#include "types/Type.hpp"
#include "types/TypeFactory.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.hpp"
#include "types/containers/ColumnVector.hpp"
#include "types/containers/ColumnVectorsValueAccessor.hpp"
#include "utility/Macros.hpp"
#include "utility/ScopedBuffer.hpp"

// NetBSD's libc has atoll, but it doesn't show up in the std namespace for
// C++.
#ifndef __NetBSD__
using std::atoll;
#endif

namespace quickstep {

constexpr std::int64_t kNumSampleKeys = 1024;
// Not exactly aligned to word size so we can make sure there are no alignment
// problems for arbitrary-length types.
constexpr std::size_t kStringLengthParam = 18;
constexpr std::size_t kNumConcurrentThreads = 8;

class TestHashPayload {
 public:
  explicit TestHashPayload(const int payload)
      : internal_int_(payload) {
  }

  TestHashPayload(const TestHashPayload &orig)
      : internal_int_(orig.internal_int_.load()) {
  }

  std::atomic<int>* accessInternalInt() {
    return &internal_int_;
  }

  int loadInternalInt() const {
    return internal_int_.load(std::memory_order_relaxed);
  }

 private:
  std::atomic<int> internal_int_;
};

class NonTriviallyDestructibleTestHashPayload {
 public:
  NonTriviallyDestructibleTestHashPayload()
      : destruct_count_(nullptr) {
  }

  explicit NonTriviallyDestructibleTestHashPayload(std::atomic<int> *destruct_count)
      : destruct_count_(destruct_count) {
  }

  void clearDestructCountPtr() {
    destruct_count_ = nullptr;
  }

  ~NonTriviallyDestructibleTestHashPayload() {
    if (destruct_count_ != nullptr) {
      destruct_count_->fetch_add(1, std::memory_order_relaxed);
    }
  }

 private:
  std::atomic<int> *destruct_count_;
};

// Insertion functor that creates a TestHashPayload containing the tuple_id for
// each tuple visited in a ValueAccessor.
class TestInserter {
 public:
  template <typename ValueAccessorT>
  TestHashPayload operator()(const ValueAccessorT &accessor) {
    return TestHashPayload(accessor.getCurrentPosition());
  }
};

// Simple upserter that just atomically increments a TestHashPayload's value.
class TestUpserter {
 public:
  TestUpserter()
      : call_count_(0) {
  }

  void operator()(TestHashPayload *value) {
    ++call_count_;
    value->accessInternalInt()->fetch_add(1, std::memory_order_relaxed);
  }

  template <typename ValueAccessorT>
  void operator()(const ValueAccessorT &accessor, TestHashPayload *value) {
    ++call_count_;
    value->accessInternalInt()->fetch_add(1, std::memory_order_relaxed);
  }

  std::size_t call_count() const {
    return call_count_;
  }

 private:
  std::size_t call_count_;
};

// Visitor to test HashTable::forEach() and HashTable::forEachCompositeKey().
// For each key-value pair, extracts and remembers the key's original seed and
// the value stored in the TestHashPayload which it maps to.
class TestVisitor {
 public:
  TestVisitor()
      : test_key_type_id_(kNumTypeIDs) {
  }

  explicit TestVisitor(const TypeID test_key_type_id)
      : test_key_type_id_(test_key_type_id) {
  }

  void operator()(const TypedValue &key, const TestHashPayload &payload) {
    internal_map_.emplace(extractScalarSeed(key), payload.loadInternalInt());
  }

  void operator()(const std::vector<TypedValue> &key, const TestHashPayload &payload) {
    internal_map_.emplace(extractCompositeSeed(key), payload.loadInternalInt());
  }

  template <typename ValueAccessorT>
  void operator()(const ValueAccessorT &accessor, const TestHashPayload &payload) {
    std::vector<TypedValue> composite_key;
    composite_key.emplace_back(accessor.getTypedValue(0));
    composite_key.emplace_back(accessor.getTypedValue(1));
    composite_key.emplace_back(accessor.getTypedValue(2));

    internal_map_.emplace(extractCompositeSeed(composite_key),
                          payload.loadInternalInt());
  }

  const std::unordered_multimap<std::int64_t, int>& internal_map() const {
    return internal_map_;
  }

 private:
  std::int64_t extractScalarSeed(const TypedValue &key) {
    switch (test_key_type_id_) {
      case TypeID::kLong: {
        EXPECT_EQ(TypeID::kLong, key.getTypeID());
        return key.getLiteral<std::int64_t>();
      }
      case TypeID::kChar: {
        EXPECT_EQ(TypeID::kChar, key.getTypeID());
        return atoll(static_cast<const char*>(key.getDataPtr()));
      }
      case TypeID::kVarChar: {
        EXPECT_EQ(TypeID::kVarChar, key.getTypeID());
        return atoll(static_cast<const char*>(key.getDataPtr()));
      }
      default:
        FATAL_ERROR("TypeID not covered\n");
    }
  }

  std::int64_t extractCompositeSeed(const std::vector<TypedValue> &key) {
    EXPECT_EQ(3u, key.size());

    EXPECT_EQ(TypeID::kLong, key[0].getTypeID());
    const std::int64_t seed = key[0].getLiteral<std::int64_t>();

    EXPECT_EQ(TypeID::kChar, key[1].getTypeID());
    EXPECT_EQ(seed, atoll(static_cast<const char*>(key[1].getDataPtr())));

    EXPECT_EQ(TypeID::kVarChar, key[2].getTypeID());
    EXPECT_EQ(seed, atoll(static_cast<const char*>(key[2].getDataPtr())));

    return seed;
  }

  const TypeID test_key_type_id_;
  std::unordered_multimap<std::int64_t, int> internal_map_;
};

template <typename HashTableImpl>
class HashTableTest : public ::testing::Test {
 protected:
  class InserterThread : public Thread {
   public:
    InserterThread(const int my_id,
                   const std::vector<TypedValue> &keys,
                   HashTableImpl *hash_table)
        : my_id_(my_id),
          keys_(keys),
          hash_table_(hash_table),
          insert_succeeded_(keys.size(), false) {
      // Randomize insert order.
      for (std::vector<TypedValue>::size_type i = 0;
           i < keys_.size();
           ++i) {
        insert_order_.push_back(i);
      }
      std::random_shuffle(insert_order_.begin(), insert_order_.end());
    }

    int getID() const {
      return my_id_;
    }

    const std::vector<bool>& insert_succeeded() const {
      return insert_succeeded_;
    }

   protected:
    void run() override {
      for (const std::vector<TypedValue>::size_type i : insert_order_) {
        TestHashPayload value(i * kNumSampleKeys + my_id_);
        insert_succeeded_[i] = hash_table_->put(keys_[i], value) == HashTablePutResult::kOK;
      }
    }

   private:
    const int my_id_;
    const std::vector<TypedValue> &keys_;
    HashTableImpl *hash_table_;
    std::vector<std::vector<TypedValue>::size_type> insert_order_;
    std::vector<bool> insert_succeeded_;
  };

  class CompositeKeyInserterThread : public Thread {
   public:
    CompositeKeyInserterThread(const int my_id,
                               const std::vector<std::vector<TypedValue>> &keys,
                               HashTableImpl *hash_table)
        : my_id_(my_id),
          keys_(keys),
          hash_table_(hash_table),
          insert_succeeded_(keys.size(), false) {
      // Randomize insert order.
      for (std::vector<TypedValue>::size_type i = 0;
           i < keys_.size();
           ++i) {
        insert_order_.push_back(i);
      }
      std::random_shuffle(insert_order_.begin(), insert_order_.end());
    }

    int getID() const {
      return my_id_;
    }

    const std::vector<bool>& insert_succeeded() const {
      return insert_succeeded_;
    }

   protected:
    void run() override {
      for (const std::vector<std::vector<TypedValue>>::size_type i : insert_order_) {
        TestHashPayload value(i * kNumSampleKeys + my_id_);
        insert_succeeded_[i]
            = hash_table_->putCompositeKey(keys_[i], value) == HashTablePutResult::kOK;
      }
    }

   private:
    const int my_id_;
    const std::vector<std::vector<TypedValue>> &keys_;
    HashTableImpl *hash_table_;
    std::vector<std::vector<std::vector<TypedValue>>::size_type> insert_order_;
    std::vector<bool> insert_succeeded_;
  };

  virtual void SetUp() {
    storage_manager_.reset(new StorageManager("./test_data/"));
  }

  static std::vector<const Type*> SetupScalarKeyType(const TypeID type_id) {
    std::vector<const Type*> key_type_vec;
    switch (type_id) {
      case kLong:
        key_type_vec.push_back(&TypeFactory::GetType(kLong, false));
        break;
      case kChar:
        key_type_vec.push_back(&TypeFactory::GetType(kChar, kStringLengthParam, false));
        break;
      case kVarChar:
        key_type_vec.push_back(&TypeFactory::GetType(kVarChar, kStringLengthParam, false));
        break;
      default:
        FATAL_ERROR("TypeID not covered\n");
    }
    return key_type_vec;
  }

  static std::vector<const Type*> SetupCompositeKeyType() {
    std::vector<const Type*> key_type_vec;
    key_type_vec.push_back(&TypeFactory::GetType(kLong, false));
    key_type_vec.push_back(&TypeFactory::GetType(kChar, kStringLengthParam, false));
    key_type_vec.push_back(&TypeFactory::GetType(kVarChar, kStringLengthParam, false));
    return key_type_vec;
  }

  void createResizableHashTable(const std::vector<const Type*> &key_types,
                                const std::size_t num_entries) {
    hash_table_.reset(new HashTableImpl(key_types,
                                        num_entries,
                                        storage_manager_.get()));
  }

  void createNonresizableHashTable(const std::vector<const Type*> &key_types,
                                   const std::size_t buffer_size,
                                   const std::size_t offset_in_buffer) {
    assert(offset_in_buffer < buffer_size);
    memory_buffer_.reset(new ScopedBuffer(buffer_size, kCacheLineBytes));
    hash_table_.reset(new HashTableImpl(
        key_types,
        static_cast<char*>(memory_buffer_->get()) + offset_in_buffer,
        buffer_size - offset_in_buffer,
        true,
        false));
  }

  void createHashTableSimple(const std::vector<const Type*> &key_types,
                             const std::size_t num_entries) {
    if (HashTableImpl::template_resizable) {
      createResizableHashTable(key_types, num_entries);
    } else {
      // Allocate space for 'num_entries' generously.
      std::size_t key_size = 0;
      for (const Type *type : key_types) {
        key_size += type->maximumByteLength();
      }
      createNonresizableHashTable(
          key_types,
          256 + num_entries * 8 * (key_size + sizeof(typename HashTableImpl::value_type)),
          0);
    }
  }

  TypedValue createLongKey(const std::int64_t seed) const {
    return TypedValue(seed);
  }

  TypedValue createCharKey(const std::int64_t seed) {
    std::ostringstream stream;
    stream << seed;
    external_strings_.emplace_back(stream.str().size() + 1);
    std::memcpy(external_strings_.back().get(),
                stream.str().c_str(),
                stream.str().size() + 1);
    return TypeFactory::GetType(kChar, kStringLengthParam, false).makeValue(external_strings_.back().get(),
                                                                     stream.str().size() + 1);
  }

  TypedValue createVarCharKey(const std::int64_t seed) {
    std::ostringstream stream;
    stream << seed;
    external_strings_.emplace_back(stream.str().size() + 1);
    std::memcpy(external_strings_.back().get(),
                stream.str().c_str(),
                stream.str().size() + 1);
    return TypeFactory::GetType(kVarChar, kStringLengthParam, false).makeValue(external_strings_.back().get(),
                                                                        stream.str().size() + 1);
  }

  TypedValue createScalarKey(const TypeID test_key_type_id,
                             const std::int64_t seed) {
    switch (test_key_type_id) {
      case TypeID::kLong:
        return createLongKey(seed);
      case TypeID::kChar:
        return createCharKey(seed);
      case TypeID::kVarChar:
        return createVarCharKey(seed);
      default:
        FATAL_ERROR("TypeID not covered\n");
    }
  }

  std::vector<TypedValue> createCompositeKey(const std::int64_t seed) {
    std::vector<TypedValue> key;
    key.emplace_back(createLongKey(seed));
    key.emplace_back(createCharKey(seed));
    key.emplace_back(createVarCharKey(seed));
    return key;
  }

  ColumnVectorsValueAccessor* createSampleValueAccessor() {
    // Create a ColumnVectorsValueAccessor to simulate a table with 3 columns:
    // Long, Char, & VarChar.
    ColumnVectorsValueAccessor *accessor = new ColumnVectorsValueAccessor();

    NativeColumnVector *long_column
        = new NativeColumnVector(TypeFactory::GetType(kLong, true),
                                 kNumSampleKeys + 1);
    NativeColumnVector *char_column
        = new NativeColumnVector(TypeFactory::GetType(kChar, kStringLengthParam, true),
                                 kNumSampleKeys + 1);
    IndirectColumnVector *varchar_column
        = new IndirectColumnVector(TypeFactory::GetType(kVarChar, kStringLengthParam, true),
                                   kNumSampleKeys + 1);

    for (std::int64_t i = 0; i < kNumSampleKeys / 2; ++i) {
      long_column->appendTypedValue(createScalarKey(kLong, i * (i + 1)));
      char_column->appendTypedValue(createScalarKey(kChar, i * (i + 1)));
      varchar_column->appendTypedValue(createScalarKey(kVarChar, i * (i + 1)));
    }

    // Put some nulls in the middle of each column.
    long_column->appendTypedValue(TypedValue(kLong));
    char_column->appendTypedValue(TypedValue(kChar));
    varchar_column->appendTypedValue(TypedValue(kVarChar));

    // Finish filling the columns.
    for (std::int64_t i = kNumSampleKeys / 2;
         i < kNumSampleKeys;
         ++i) {
      long_column->appendTypedValue(createScalarKey(kLong, i * (i + 1)));
      char_column->appendTypedValue(createScalarKey(kChar, i * (i + 1)));
      varchar_column->appendTypedValue(createScalarKey(kVarChar, i * (i + 1)));
    }

    accessor->addColumn(long_column);
    accessor->addColumn(char_column);
    accessor->addColumn(varchar_column);

    return accessor;
  }

  void runScalarKeyPutAndGetTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys);

    // Insert some key/value pairs.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      TestHashPayload value(i);
      EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, value));
    }

    // Read them back out.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      std::vector<TypedValue> key_vec(1, key);

      // Use getSingle() if duplicate keys are not allowed.
      if (!HashTableImpl::template_allow_duplicate_keys) {
        const TestHashPayload *value = hash_table_->getSingle(key);
        ASSERT_NE(nullptr, value);
        EXPECT_EQ(i, value->loadInternalInt());

        value = hash_table_->getSingleCompositeKey(key_vec);
        ASSERT_NE(nullptr, value);
        EXPECT_EQ(i, value->loadInternalInt());
      }

      // Test getAll() in all cases.
      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(i, matches.front()->loadInternalInt());

      matches.clear();
      hash_table_->getAllCompositeKey(key_vec, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(i, matches.front()->loadInternalInt());
    }

    // Check a nonexistent key.
    TypedValue nonexistent_key(createScalarKey(test_key_type_id,
                                               kNumSampleKeys * kNumSampleKeys * kNumSampleKeys));
    if (!HashTableImpl::template_allow_duplicate_keys) {
      const TestHashPayload *nonexistent_value = hash_table_->getSingle(nonexistent_key);
      EXPECT_EQ(nullptr, nonexistent_value);
    }
    std::vector<const TestHashPayload*> nonexistent_matches;
    hash_table_->getAll(nonexistent_key, &nonexistent_matches);
    EXPECT_TRUE(nonexistent_matches.empty());

    // Also test forEach().
    TestVisitor visitor(test_key_type_id);
    EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys),
              hash_table_->forEach(&visitor));
    EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys),
              visitor.internal_map().size());
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      ASSERT_EQ(1u, visitor.internal_map().count(i * (i + 1)));
      EXPECT_EQ(i, visitor.internal_map().find(i * (i + 1))->second);
    }
  }

  void runDuplicateScalarKeysPutAndGetTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys * 2);

    // Attempt to insert 1-3 values for each distinct key.
    std::size_t total_inserted = 0;
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      TestHashPayload first_value(i * kNumSampleKeys);
      EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, first_value));
      ++total_inserted;

      for (int extra_value_num = 1;
           extra_value_num <= i % 3;
           ++extra_value_num) {
        TestHashPayload additional_value(i * kNumSampleKeys + extra_value_num);
        if (HashTableImpl::template_allow_duplicate_keys) {
          EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, additional_value));
          ++total_inserted;
        } else {
          EXPECT_EQ(HashTablePutResult::kDuplicateKey, hash_table_->put(key, additional_value));
        }
      }
    }

    // Read them back out.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      std::vector<TypedValue> key_vec(1, key);

      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      if (HashTableImpl::template_allow_duplicate_keys) {
        EXPECT_EQ(static_cast<std::size_t>((i % 3) + 1), matches.size());
        std::bitset<3> value_found;
        for (const TestHashPayload *match : matches) {
          ASSERT_LE(match->loadInternalInt() - i * kNumSampleKeys, 3);
          EXPECT_FALSE(value_found[match->loadInternalInt() - i * kNumSampleKeys]);
          value_found.set(match->loadInternalInt() - i * kNumSampleKeys, true);
        }
        EXPECT_TRUE(value_found[0]);
        if (i % 3 > 0) {
          EXPECT_TRUE(value_found[1]);
        } else {
          EXPECT_FALSE(value_found[1]);
        }
        if (i % 3 > 1) {
          EXPECT_TRUE(value_found[2]);
        } else {
          EXPECT_FALSE(value_found[2]);
        }
      } else {
        ASSERT_EQ(1u, matches.size());
        EXPECT_EQ(i * kNumSampleKeys,
                  matches.front()->loadInternalInt());
      }
    }

    // Check a nonexistent key.
    TypedValue nonexistent_key(createScalarKey(test_key_type_id,
                                               kNumSampleKeys * kNumSampleKeys * kNumSampleKeys));
    std::vector<const TestHashPayload*> nonexistent_matches;
    hash_table_->getAll(nonexistent_key, &nonexistent_matches);
    EXPECT_TRUE(nonexistent_matches.empty());

    // Also test forEach().
    TestVisitor visitor(test_key_type_id);
    EXPECT_EQ(total_inserted, hash_table_->forEach(&visitor));
    EXPECT_EQ(total_inserted, visitor.internal_map().size());
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      if (HashTableImpl::template_allow_duplicate_keys) {
        ASSERT_EQ(static_cast<std::size_t>(1 + (i % 3)),
                  visitor.internal_map().count(i * (i + 1)));
        std::bitset<3> value_found;
        std::pair<std::unordered_multimap<std::int64_t, int>::const_iterator,
                  std::unordered_multimap<std::int64_t, int>::const_iterator> match_range
            = visitor.internal_map().equal_range(i * (i + 1));
        for (std::unordered_multimap<std::int64_t, int>::const_iterator match_it = match_range.first;
             match_it != match_range.second;
             ++match_it) {
          ASSERT_LE(match_it->second - i * kNumSampleKeys, 3);
          EXPECT_FALSE(value_found[match_it->second - i * kNumSampleKeys]);
          value_found.set(match_it->second - i * kNumSampleKeys, true);
        }

        EXPECT_TRUE(value_found[0]);
        if (i % 3 > 0) {
          EXPECT_TRUE(value_found[1]);
        } else {
          EXPECT_FALSE(value_found[1]);
        }
        if (i % 3 > 1) {
          EXPECT_TRUE(value_found[2]);
        } else {
          EXPECT_FALSE(value_found[2]);
        }
      } else {
        ASSERT_EQ(1u, visitor.internal_map().count(i * (i + 1)));
        EXPECT_EQ(i * kNumSampleKeys,
                  visitor.internal_map().find(i * (i + 1))->second);
      }
    }
  }

  void runScalarKeyPutAndGetFromValueAccessorTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys);

    std::unique_ptr<ColumnVectorsValueAccessor> accessor(createSampleValueAccessor());

    attribute_id key_attr_id;
    switch (test_key_type_id) {
      case kLong:
        key_attr_id = 0;
        break;
      case kChar:
        key_attr_id = 1;
        break;
      case kVarChar:
        key_attr_id = 2;
        break;
      default:
        FATAL_ERROR("TypeID not covered\n");
    }

    // Vectorized insert, skipping over null keys.
    TestInserter inserter;
    EXPECT_EQ(HashTablePutResult::kOK, hash_table_->putValueAccessor(accessor.get(),
                                                                     key_attr_id,
                                                                     true,
                                                                     &inserter));

    // Read values back out.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(i + (i >= kNumSampleKeys / 2),
                matches.front()->loadInternalInt());
    }

    // Also read the values out using the vectorized interface.
    accessor->beginIteration();
    TestVisitor visitor;
    hash_table_->getAllFromValueAccessor(accessor.get(),
                                         key_attr_id,
                                         true,
                                         &visitor);
    EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys),
              visitor.internal_map().size());
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      ASSERT_EQ(1u, visitor.internal_map().count(i * (i + 1)));
      EXPECT_EQ(i + (i >= kNumSampleKeys / 2),
                visitor.internal_map().find(i * (i + 1))->second);
    }
  }

  void runScalarKeyClearTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys);

    // Insert some key/value pairs.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      TestHashPayload value(i);
      EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, value));
    }

    // Clear out the HashTable.
    hash_table_->clear();

    // Make sure entries are cleared out.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));

      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      EXPECT_TRUE(matches.empty());
    }

    // Also make sure that forEach() sees an empty HashTable.
    TestVisitor visitor(test_key_type_id);
    EXPECT_EQ(0u, hash_table_->forEach(&visitor));
    EXPECT_EQ(0u, visitor.internal_map().size());
  }

  void runScalarKeyResizeTest(const TypeID test_key_type_id) {
    // Try to trigger a resize by substantially under-provisioning storage.
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createResizableHashTable(key_types, 1);

    const block_id original_blob_id = hash_table_->getBlobId();

    // Insert at least enough values to exhaust the space in the smallest
    // possible StorageBlob.
    for (std::int64_t i = 0;
         i < static_cast<std::int64_t>(
                 kSlotSizeBytes / (sizeof(std::size_t) + sizeof(TestHashPayload)));
         ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      TestHashPayload value(i);
      EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, value));
    }

    // If a resize occured, the block ID should be different now.
    EXPECT_NE(original_blob_id, hash_table_->getBlobId());

    // Read out the values.
    for (std::int64_t i = 0; i < 2 * kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));

      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(i, matches.front()->loadInternalInt());
    }
  }

  void runScalarKeyExhaustSpaceTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);

    // Under-provision storage and insert entries until we run out of space.
    const std::size_t buffer_size
        = kNumSampleKeys * (key_types.front()->maximumByteLength() + sizeof(typename HashTableImpl::value_type))
          / 4;
    createNonresizableHashTable(key_types, buffer_size, 0);

    std::int64_t i;
    for (i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      TestHashPayload value(i);
      HashTablePutResult result = hash_table_->put(key, value);
      if (result != HashTablePutResult::kOK) {
        EXPECT_EQ(HashTablePutResult::kOutOfSpace, result);
        break;
      }
    }

    EXPECT_LT(i, kNumSampleKeys);

    // Check the entries that we were able to insert.
    for (std::int64_t j = 0; j < i; ++j) {
      TypedValue key(createScalarKey(test_key_type_id, j * (j + 1)));

      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(j, matches.front()->loadInternalInt());
    }

    // Check that the entry we failed to insert is not present.
    TypedValue failed_key(createScalarKey(test_key_type_id, i * (i + 1)));
    std::vector<const TestHashPayload*> failed_matches;
    hash_table_->getAll(failed_key, &failed_matches);
    EXPECT_TRUE(failed_matches.empty());
  }

  void runScalarKeyUpsertTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys);

    // Upsert some key/value pairs.
    TestHashPayload initial_value(42);
    TestUpserter upserter;
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      EXPECT_TRUE(hash_table_->upsert(key, initial_value, &upserter));
    }
    EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys), upserter.call_count());

    // Visit every other value a second time.
    for (std::int64_t i = 0; i < kNumSampleKeys; i += 2) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      EXPECT_TRUE(hash_table_->upsert(key, initial_value, &upserter));
    }
    EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys + (kNumSampleKeys / 2)),
              upserter.call_count());

    // Read out the values and check that they are as expected (initial value
    // for each was set to 42, and each call to TestUpserter increments by 1).
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));

      const TestHashPayload *value = hash_table_->getSingle(key);
      ASSERT_NE(nullptr, value);
      EXPECT_EQ(44 - (i % 2), value->loadInternalInt());
    }
  }

  void runScalarKeyUpsertValueAccessorTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys);

    std::unique_ptr<ColumnVectorsValueAccessor> accessor(createSampleValueAccessor());

    attribute_id key_attr_id;
    switch (test_key_type_id) {
      case kLong:
        key_attr_id = 0;
        break;
      case kChar:
        key_attr_id = 1;
        break;
      case kVarChar:
        key_attr_id = 2;
        break;
      default:
        FATAL_ERROR("TypeID not covered\n");
    }

    // Vectorized upsert, skipping over null keys.
    TestHashPayload initial_value(42);
    TestUpserter upserter;
    EXPECT_TRUE(hash_table_->upsertValueAccessor(accessor.get(),
                                                 key_attr_id,
                                                 true,
                                                 initial_value,
                                                 &upserter));
    EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys), upserter.call_count());

    // Read values out and check that they are as expected.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(43, matches.front()->loadInternalInt());
    }
  }

  void runScalarKeySerializationTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    // Set up a shared memory buffer which will hold both the external keys
    // and the hash table.
    const std::size_t buffer_size
        = kNumSampleKeys * key_types.front()->maximumByteLength()
          + 8 * kNumSampleKeys * (key_types.front()->maximumByteLength() + sizeof(typename HashTableImpl::value_type));
    createNonresizableHashTable(key_types,
                                buffer_size,
                                kNumSampleKeys * key_types.front()->maximumByteLength());

    // Create external keys in the first part of the buffer.
    char *key_ptr = static_cast<char*>(memory_buffer_->get());
    std::vector<std::size_t> key_sizes;
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      key.copyInto(key_ptr);
      key_sizes.push_back(key.getDataSize());
      key_ptr += key.getDataSize();
    }

    // Now actually insert.
    key_ptr = static_cast<char*>(memory_buffer_->get());
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(key_types.front()->makeValue(key_ptr, key_sizes[i]));
      TestHashPayload value(i);
      EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, value));
      key_ptr += key_sizes[i];
    }

    // Destroy the HashTable object and copy the underlying memory.
    hash_table_.reset(nullptr);
    ScopedBuffer moved_buffer(buffer_size, kCacheLineBytes);
    std::memcpy(moved_buffer.get(), memory_buffer_->get(), buffer_size);
    memory_buffer_.reset(nullptr);

    // Recreate the HashTable at the new location.
    hash_table_.reset(new HashTableImpl(
        key_types,
        static_cast<char*>(moved_buffer.get()) + kNumSampleKeys * key_types.front()->maximumByteLength(),
        buffer_size - kNumSampleKeys * key_types.front()->maximumByteLength(),
        false,
        false));

    // If duplicate keys are not allowed, make sure we can't insert a
    // duplicate.
    if (!HashTableImpl::template_allow_duplicate_keys) {
      TypedValue key(key_types.front()->makeValue(moved_buffer.get(), key_sizes[0]));
      TestHashPayload value(123);
      EXPECT_EQ(HashTablePutResult::kDuplicateKey, hash_table_->put(key, value));
    }

    // Read the inserted values back out.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));

      // Test getAll() in all cases.
      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(i, matches.front()->loadInternalInt());
    }

    // Check a nonexistent key.
    TypedValue nonexistent_key(createScalarKey(test_key_type_id,
                                               kNumSampleKeys * kNumSampleKeys * kNumSampleKeys));
    std::vector<const TestHashPayload*> nonexistent_matches;
    hash_table_->getAll(nonexistent_key, &nonexistent_matches);
    EXPECT_TRUE(nonexistent_matches.empty());
  }

  void runScalarKeyThreadedPutTest(const TypeID test_key_type_id,
                                   const bool test_resize) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    if (HashTableImpl::template_allow_duplicate_keys) {
      if (test_resize) {
        createHashTableSimple(key_types, 1);
      } else {
        createHashTableSimple(key_types, kNumSampleKeys * kNumConcurrentThreads);
      }
    } else {
      if (test_resize) {
        createHashTableSimple(key_types, 1);
      } else {
        createHashTableSimple(key_types, kNumSampleKeys);
      }
    }

    // If testing multithreaded resize, record the original ID of the
    // underlying blob.
    block_id original_blob_id = 0;
    if (test_resize) {
      original_blob_id = hash_table_->getBlobId();
    }

    // Setup keys ahead of time.
    const std::size_t num_keys = test_resize
        ? (kSlotSizeBytes / (sizeof(std::size_t) + sizeof(TestHashPayload)))
            / (HashTableImpl::template_allow_duplicate_keys ? kNumConcurrentThreads : 1)
        : kNumSampleKeys;
    std::vector<TypedValue> keys;
    for (std::int64_t i = 0; i < static_cast<std::int64_t>(num_keys); ++i) {
      keys.emplace_back(createScalarKey(test_key_type_id, i * (i + 1)));
    }

    // Setup threads.
    std::vector<std::unique_ptr<InserterThread>> threads;
    for (std::size_t thread_num = 0; thread_num < kNumConcurrentThreads; ++thread_num) {
      threads.emplace_back(new InserterThread(thread_num, keys, hash_table_.get()));
    }

    // Run threads and join them.
    for (std::unique_ptr<InserterThread> &thread : threads) {
      thread->start();
    }
    for (std::unique_ptr<InserterThread> &thread : threads) {
      thread->join();
    }

    // If a resize occured, the block ID should be different now.
    if (test_resize) {
      EXPECT_NE(original_blob_id, hash_table_->getBlobId());
    }

    // Check that everything was inserted properly.
    for (std::int64_t i = 0; i < static_cast<std::int64_t>(num_keys); ++i) {
      std::size_t successful_inserts = 0;
      for (const std::unique_ptr<InserterThread> &thread : threads) {
        if (thread->insert_succeeded()[i]) {
          ++successful_inserts;
        }
      }
      if (HashTableImpl::template_allow_duplicate_keys) {
        EXPECT_EQ(kNumConcurrentThreads, successful_inserts);
      } else {
        EXPECT_EQ(1u, successful_inserts);
      }

      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));

      std::vector<const TestHashPayload*> matches;
      hash_table_->getAll(key, &matches);
      if (HashTableImpl::template_allow_duplicate_keys) {
        EXPECT_EQ(kNumConcurrentThreads, matches.size());
        std::vector<bool> found_value(kNumConcurrentThreads, false);
        for (const TestHashPayload *payload : matches) {
          const int payload_value = payload->loadInternalInt();
          ASSERT_GE(payload_value, i * kNumSampleKeys);
          ASSERT_LT(payload_value,
                    i * kNumSampleKeys + static_cast<std::int64_t>(kNumConcurrentThreads));
          EXPECT_FALSE(found_value[payload_value - i * kNumSampleKeys]);
          found_value[payload_value - i * kNumSampleKeys] = true;
        }
        for (const bool found : found_value) {
          EXPECT_TRUE(found);
        }
      } else {
        ASSERT_EQ(1u, matches.size());
        for (const std::unique_ptr<InserterThread> &thread : threads) {
          if (thread->insert_succeeded()[i]) {
            EXPECT_EQ(i * kNumSampleKeys + thread->getID(),
                      matches.front()->loadInternalInt());
          }
        }
      }
    }
  }

  void runCompositeKeyThreadedPutTest(const bool test_resize) {
    std::vector<const Type*> key_types = SetupCompositeKeyType();
    if (HashTableImpl::template_allow_duplicate_keys) {
      if (test_resize) {
        createHashTableSimple(key_types, 1);
      } else {
        createHashTableSimple(key_types, kNumSampleKeys * kNumConcurrentThreads);
      }
    } else {
      if (test_resize) {
        createHashTableSimple(key_types, 1);
      } else {
        createHashTableSimple(key_types, kNumSampleKeys);
      }
    }

    // If testing multithreaded resize, record the original ID of the
    // underlying blob.
    block_id original_blob_id = 0;
    if (test_resize) {
      original_blob_id = hash_table_->getBlobId();
    }

    // Setup keys ahead of time.
    const std::size_t num_keys = test_resize
        ? (kSlotSizeBytes / (sizeof(std::size_t) + sizeof(TestHashPayload)))
            / (HashTableImpl::template_allow_duplicate_keys ? kNumConcurrentThreads : 1)
        : kNumSampleKeys;
    std::vector<std::vector<TypedValue>> keys;
    for (std::int64_t i = 0; i < static_cast<std::int64_t>(num_keys); ++i) {
      keys.emplace_back(createCompositeKey(i * (i + 1)));
    }

    // Setup threads.
    std::vector<std::unique_ptr<CompositeKeyInserterThread>> threads;
    for (std::size_t thread_num = 0; thread_num < kNumConcurrentThreads; ++thread_num) {
      threads.emplace_back(new CompositeKeyInserterThread(thread_num, keys, hash_table_.get()));
    }

    // Run threads and join them.
    for (std::unique_ptr<CompositeKeyInserterThread> &thread : threads) {
      thread->start();
    }
    for (std::unique_ptr<CompositeKeyInserterThread> &thread : threads) {
      thread->join();
    }

    // If a resize occured, the block ID should be different now.
    if (test_resize) {
      EXPECT_NE(original_blob_id, hash_table_->getBlobId());
    }

    // Check that everything was inserted properly.
    for (std::int64_t i = 0; i < static_cast<std::int64_t>(num_keys); ++i) {
      std::size_t successful_inserts = 0;
      for (const std::unique_ptr<CompositeKeyInserterThread> &thread : threads) {
        if (thread->insert_succeeded()[i]) {
          ++successful_inserts;
        }
      }
      if (HashTableImpl::template_allow_duplicate_keys) {
        EXPECT_EQ(kNumConcurrentThreads, successful_inserts);
      } else {
        EXPECT_EQ(1u, successful_inserts);
      }

      std::vector<TypedValue> key(createCompositeKey(i * (i + 1)));

      std::vector<const TestHashPayload*> matches;
      hash_table_->getAllCompositeKey(key, &matches);
      if (HashTableImpl::template_allow_duplicate_keys) {
        EXPECT_EQ(kNumConcurrentThreads, matches.size());
        std::vector<bool> found_value(kNumConcurrentThreads, false);
        for (const TestHashPayload *payload : matches) {
          const int payload_value = payload->loadInternalInt();
          ASSERT_GE(payload_value, i * kNumSampleKeys);
          ASSERT_LT(payload_value,
                    i * kNumSampleKeys + static_cast<std::int64_t>(kNumConcurrentThreads));
          EXPECT_FALSE(found_value[payload_value - i * kNumSampleKeys]);
          found_value[payload_value - i * kNumSampleKeys] = true;
        }
        for (const bool found : found_value) {
          EXPECT_TRUE(found);
        }
      } else {
        ASSERT_EQ(1u, matches.size());
        for (const std::unique_ptr<CompositeKeyInserterThread> &thread : threads) {
          if (thread->insert_succeeded()[i]) {
            EXPECT_EQ(i * kNumSampleKeys + thread->getID(),
                      matches.front()->loadInternalInt());
          }
        }
      }
    }
  }

  std::unique_ptr<StorageManager> storage_manager_;
  std::unique_ptr<ScopedBuffer> memory_buffer_;
  std::unique_ptr<HashTableImpl> hash_table_;
  std::vector<ScopedBuffer> external_strings_;
};
TYPED_TEST_CASE_P(HashTableTest);

template <typename HashTableImpl> using HashTableTestLongOnly
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(HashTableTestLongOnly);

// Alias for tests which only apply to resizable hash tables.
template <typename HashTableImpl> using ResizableHashTableTest
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(ResizableHashTableTest);

template <typename HashTableImpl> using ResizableHashTableTestLongOnly
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(ResizableHashTableTestLongOnly);

// Alias for tests which only apply to non-resizable hash tables.
template <typename HashTableImpl> using NonResizableHashTableTest
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(NonResizableHashTableTest);

template <typename HashTableImpl> using NonResizableHashTableTestLongOnly
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(NonResizableHashTableTestLongOnly);

// Alias for tests which only apply to hash tables which do not allow duplicate
// keys.
template <typename HashTableImpl> using DuplicateKeysForbiddenHashTableTest
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(DuplicateKeysForbiddenHashTableTest);

template <typename HashTableImpl> using DuplicateKeysForbiddenHashTableTestLongOnly
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(DuplicateKeysForbiddenHashTableTestLongOnly);

// Alias for tests which only apply to hash tables which are fixed-size and
// serializable.
template <typename HashTableImpl> using FixedSizeSerializableHashTableTest
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(FixedSizeSerializableHashTableTest);

template <typename HashTableImpl> using FixedSizeSerializableHashTableTestLongOnly
    = HashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(FixedSizeSerializableHashTableTestLongOnly);

// We use a separate test fixture here, since the regular HashTableTest assumes
// that HashTableImpl::value_type is TestHashPayload.
template <typename HashTableImpl>
class NonTriviallyDestructibleValueHashTableTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    storage_manager_.reset(new StorageManager("./test_data/"));
  }

  static std::vector<const Type*> SetupScalarKeyType(const TypeID type_id) {
    std::vector<const Type*> key_type_vec;
    switch (type_id) {
      case kLong:
        key_type_vec.push_back(&TypeFactory::GetType(kLong, false));
        break;
      case kChar:
        key_type_vec.push_back(&TypeFactory::GetType(kChar, kStringLengthParam, false));
        break;
      case kVarChar:
        key_type_vec.push_back(&TypeFactory::GetType(kVarChar, kStringLengthParam, false));
        break;
      default:
        FATAL_ERROR("TypeID not covered\n");
    }
    return key_type_vec;
  }

  static std::vector<const Type*> SetupCompositeKeyType() {
    std::vector<const Type*> key_type_vec;
    key_type_vec.push_back(&TypeFactory::GetType(kLong, false));
    key_type_vec.push_back(&TypeFactory::GetType(kChar, kStringLengthParam, false));
    key_type_vec.push_back(&TypeFactory::GetType(kVarChar, kStringLengthParam, false));
    return key_type_vec;
  }

  void createResizableHashTable(const std::vector<const Type*> &key_types,
                                const std::size_t num_entries) {
    hash_table_.reset(new HashTableImpl(key_types,
                                        num_entries,
                                        storage_manager_.get()));
  }

  void createNonresizableHashTable(const std::vector<const Type*> &key_types,
                                   const std::size_t buffer_size,
                                   const std::size_t offset_in_buffer) {
    assert(offset_in_buffer < buffer_size);
    memory_buffer_.reset(new ScopedBuffer(buffer_size, kCacheLineBytes));
    hash_table_.reset(new HashTableImpl(
        key_types,
        static_cast<char*>(memory_buffer_->get()) + offset_in_buffer,
        buffer_size - offset_in_buffer,
        true,
        false));
  }

  void createHashTableSimple(const std::vector<const Type*> &key_types,
                             const std::size_t num_entries) {
    if (HashTableImpl::template_resizable) {
      createResizableHashTable(key_types, num_entries);
    } else {
      // Allocate space for 'num_entries' generously.
      std::size_t key_size = 0;
      for (const Type *type : key_types) {
        key_size += type->maximumByteLength();
      }
      createNonresizableHashTable(
          key_types,
          num_entries * 8 * (key_size + sizeof(typename HashTableImpl::value_type)),
          0);
    }
  }

  TypedValue createLongKey(const std::int64_t seed) const {
    return TypedValue(seed);
  }

  TypedValue createCharKey(const std::int64_t seed) {
    std::ostringstream stream;
    stream << seed;
    external_strings_.emplace_back(stream.str().size() + 1);
    std::memcpy(external_strings_.back().get(),
                stream.str().c_str(),
                stream.str().size() + 1);
    return TypeFactory::GetType(kChar, kStringLengthParam, false).makeValue(external_strings_.back().get(),
                                                                     stream.str().size() + 1);
  }

  TypedValue createVarCharKey(const std::int64_t seed) {
    std::ostringstream stream;
    stream << seed;
    external_strings_.emplace_back(stream.str().size() + 1);
    std::memcpy(external_strings_.back().get(),
                stream.str().c_str(),
                stream.str().size() + 1);
    return TypeFactory::GetType(kVarChar, kStringLengthParam, false).makeValue(external_strings_.back().get(),
                                                                        stream.str().size() + 1);
  }

  TypedValue createScalarKey(const TypeID test_key_type_id,
                             const std::int64_t seed) {
    switch (test_key_type_id) {
      case TypeID::kLong:
        return createLongKey(seed);
      case TypeID::kChar:
        return createCharKey(seed);
      case TypeID::kVarChar:
        return createVarCharKey(seed);
      default:
        FATAL_ERROR("TypeID not covered\n");
    }
  }

  std::vector<TypedValue> createCompositeKey(const std::int64_t seed) {
    std::vector<TypedValue> key;
    key.emplace_back(createLongKey(seed));
    key.emplace_back(createCharKey(seed));
    key.emplace_back(createVarCharKey(seed));
    return key;
  }

  void runScalarKeyDestroyValueTest(const TypeID test_key_type_id) {
    std::vector<const Type*> key_types = SetupScalarKeyType(test_key_type_id);
    createHashTableSimple(key_types, kNumSampleKeys);

    std::atomic<int> destruct_count(0);

    // Insert some key/value pairs.
    for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
      TypedValue key(createScalarKey(test_key_type_id, i * (i + 1)));
      NonTriviallyDestructibleTestHashPayload value(&destruct_count);
      EXPECT_EQ(HashTablePutResult::kOK, hash_table_->put(key, value));
      value.clearDestructCountPtr();
    }

    // Destroy the hash table and check that the destructors of inserted values
    // were invoked.
    hash_table_.reset(nullptr);
    EXPECT_EQ(kNumSampleKeys,
              destruct_count.load(std::memory_order_relaxed));
  }

  std::unique_ptr<StorageManager> storage_manager_;
  std::unique_ptr<ScopedBuffer> memory_buffer_;
  std::unique_ptr<HashTableImpl> hash_table_;
  std::vector<ScopedBuffer> external_strings_;
};
TYPED_TEST_CASE_P(NonTriviallyDestructibleValueHashTableTest);

template <typename HashTableImpl> using NonTriviallyDestructibleValueHashTableTestLongOnly
    = NonTriviallyDestructibleValueHashTableTest<HashTableImpl>;
TYPED_TEST_CASE_P(NonTriviallyDestructibleValueHashTableTestLongOnly);

TYPED_TEST_P(HashTableTestLongOnly, LongKeyPutAndGetTest) {
  this->runScalarKeyPutAndGetTest(TypeID::kLong);
}

TYPED_TEST_P(HashTableTest, CharKeyPutAndGetTest) {
  this->runScalarKeyPutAndGetTest(TypeID::kChar);
}

TYPED_TEST_P(HashTableTest, VarCharKeyPutAndGetTest) {
  this->runScalarKeyPutAndGetTest(TypeID::kVarChar);
}

TYPED_TEST_P(HashTableTest, CompositeKeyPutAndGetTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys);

  // Insert some key/value pairs.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    TestHashPayload value(i);
    EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->putCompositeKey(key, value));
  }

  // Read them back out.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    // Use getSingleCompositeKey() if duplicate keys are not allowed.
    if (!TypeParam::template_allow_duplicate_keys) {
      const TestHashPayload *value = this->hash_table_->getSingleCompositeKey(key);
      ASSERT_NE(nullptr, value);
      EXPECT_EQ(i, value->loadInternalInt());
    }

    // Test getAllCompositeKey() in all cases.
    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    ASSERT_EQ(1u, matches.size());
    EXPECT_EQ(i, matches.front()->loadInternalInt());
  }

  // Check a nonexistent key.
  std::vector<TypedValue> nonexistent_key(
      this->createCompositeKey(kNumSampleKeys * kNumSampleKeys * kNumSampleKeys));
  if (!TypeParam::template_allow_duplicate_keys) {
    const TestHashPayload *nonexistent_value
        = this->hash_table_->getSingleCompositeKey(nonexistent_key);
    EXPECT_EQ(nullptr, nonexistent_value);
  }
  std::vector<const TestHashPayload*> nonexistent_matches;
  this->hash_table_->getAllCompositeKey(nonexistent_key, &nonexistent_matches);
  EXPECT_TRUE(nonexistent_matches.empty());

  // Check a nonexistent key that only differs from an existing key in one
  // component.
  nonexistent_key.clear();
  nonexistent_key.emplace_back(this->createLongKey(0));
  nonexistent_key.emplace_back(this->createCharKey(0));
  nonexistent_key.emplace_back(this->createVarCharKey(1));
  if (!TypeParam::template_allow_duplicate_keys) {
    const TestHashPayload *nonexistent_value
        = this->hash_table_->getSingleCompositeKey(nonexistent_key);
    EXPECT_EQ(nullptr, nonexistent_value);
  }
  nonexistent_matches.clear();
  this->hash_table_->getAllCompositeKey(nonexistent_key, &nonexistent_matches);
  EXPECT_TRUE(nonexistent_matches.empty());

  // Also test forEach().
  TestVisitor visitor;
  EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys),
            this->hash_table_->forEachCompositeKey(&visitor));
  EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys),
            visitor.internal_map().size());
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    ASSERT_EQ(1u, visitor.internal_map().count(i * (i + 1)));
    EXPECT_EQ(i, visitor.internal_map().find(i * (i + 1))->second);
  }
}

TYPED_TEST_P(HashTableTest, SpecialHashesPutAndGetTest) {
  std::vector<const Type*> key_types = this->SetupScalarKeyType(kLong);
  this->createHashTableSimple(key_types, 4);

  // Insert Long values that hash to "special" reserved values in HashTable.
  TypedValue empty_hash_key(
      this->createScalarKey(kLong, static_cast<std::int64_t>(TypeParam::kEmptyHash)));
  TestHashPayload empty_hash_value(42);
  EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->put(empty_hash_key, empty_hash_value));

  TypedValue pending_hash_key(
      this->createScalarKey(kLong, static_cast<std::int64_t>(TypeParam::kPendingHash)));
  TestHashPayload pending_hash_value(85);
  EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->put(pending_hash_key, pending_hash_value));

  // Also try values whose natural hashes are the same as the adjusted hashes
  // of the values above (causing spurious hash collisions).
  TypedValue adjusted_empty_hash_key(
      this->createScalarKey(kLong, static_cast<std::int64_t>(TypeParam::kEmptyHash + 1)));
  TestHashPayload adjusted_empty_hash_value(123);
  EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->put(adjusted_empty_hash_key,
                                                            adjusted_empty_hash_value));

  TypedValue adjusted_pending_hash_key(
      this->createScalarKey(kLong, static_cast<std::int64_t>(TypeParam::kPendingHash - 1)));
  TestHashPayload adjusted_pending_hash_value(456);
  EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->put(adjusted_pending_hash_key,
                                                            adjusted_pending_hash_value));

  // Read values back out.
  std::vector<const TestHashPayload*> values;
  this->hash_table_->getAll(empty_hash_key, &values);
  ASSERT_EQ(1u, values.size());
  EXPECT_EQ(42, values.front()->loadInternalInt());
  values.clear();

  this->hash_table_->getAll(pending_hash_key, &values);
  ASSERT_EQ(1u, values.size());
  EXPECT_EQ(85, values.front()->loadInternalInt());
  values.clear();

  this->hash_table_->getAll(adjusted_empty_hash_key, &values);
  ASSERT_EQ(1u, values.size());
  EXPECT_EQ(123, values.front()->loadInternalInt());
  values.clear();

  this->hash_table_->getAll(adjusted_pending_hash_key, &values);
  ASSERT_EQ(1u, values.size());
  EXPECT_EQ(456, values.front()->loadInternalInt());
  values.clear();
}

TYPED_TEST_P(HashTableTestLongOnly, LongKeyPutDuplicateKeysTest) {
  this->runDuplicateScalarKeysPutAndGetTest(TypeID::kLong);
}

TYPED_TEST_P(HashTableTest, CharKeyPutDuplicateKeysTest) {
  this->runDuplicateScalarKeysPutAndGetTest(TypeID::kChar);
}

TYPED_TEST_P(HashTableTest, VarCharKeyPutDuplicateKeysTest) {
  this->runDuplicateScalarKeysPutAndGetTest(TypeID::kVarChar);
}

TYPED_TEST_P(HashTableTest, CompositeKeyPutDuplicateKeysTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys * 2);

  // Attempt to insert 1-3 values for each distinct key.
  std::size_t total_inserted = 0;
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    TestHashPayload first_value(i * kNumSampleKeys);
    EXPECT_EQ(HashTablePutResult::kOK,
              this->hash_table_->putCompositeKey(key, first_value));
    ++total_inserted;

    for (int extra_value_num = 1;
         extra_value_num <= i % 3;
         ++extra_value_num) {
      TestHashPayload additional_value(i * kNumSampleKeys + extra_value_num);
      if (TypeParam::template_allow_duplicate_keys) {
        EXPECT_EQ(HashTablePutResult::kOK,
                  this->hash_table_->putCompositeKey(key, additional_value));
        ++total_inserted;
      } else {
        EXPECT_EQ(HashTablePutResult::kDuplicateKey,
                  this->hash_table_->putCompositeKey(key, additional_value));
      }
    }
  }

  // Read them back out.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    if (TypeParam::template_allow_duplicate_keys) {
      EXPECT_EQ(static_cast<std::size_t>((i % 3) + 1), matches.size());
      std::bitset<3> value_found;
      for (const TestHashPayload *match : matches) {
        ASSERT_LE(match->loadInternalInt() - i * kNumSampleKeys, 3);
        EXPECT_FALSE(value_found[match->loadInternalInt() - i * kNumSampleKeys]);
        value_found.set(match->loadInternalInt() - i * kNumSampleKeys, true);
      }
      EXPECT_TRUE(value_found[0]);
      if (i % 3 > 0) {
        EXPECT_TRUE(value_found[1]);
      } else {
        EXPECT_FALSE(value_found[1]);
      }
      if (i % 3 > 1) {
        EXPECT_TRUE(value_found[2]);
      } else {
        EXPECT_FALSE(value_found[2]);
      }
    } else {
      ASSERT_EQ(1u, matches.size());
      EXPECT_EQ(i * kNumSampleKeys,
                matches.front()->loadInternalInt());
    }
  }

  // Check a nonexistent key.
  std::vector<TypedValue> nonexistent_key(
      this->createCompositeKey(kNumSampleKeys * kNumSampleKeys * kNumSampleKeys));
  std::vector<const TestHashPayload*> nonexistent_matches;
  this->hash_table_->getAllCompositeKey(nonexistent_key, &nonexistent_matches);
  EXPECT_TRUE(nonexistent_matches.empty());

  // Check a nonexistent key that only differs from an existing key in one
  // component.
  nonexistent_key.clear();
  nonexistent_key.emplace_back(this->createLongKey(0));
  nonexistent_key.emplace_back(this->createCharKey(0));
  nonexistent_key.emplace_back(this->createVarCharKey(1));
  if (!TypeParam::template_allow_duplicate_keys) {
    const TestHashPayload *nonexistent_value
        = this->hash_table_->getSingleCompositeKey(nonexistent_key);
    EXPECT_EQ(nullptr, nonexistent_value);
  }
  nonexistent_matches.clear();
  this->hash_table_->getAllCompositeKey(nonexistent_key, &nonexistent_matches);
  EXPECT_TRUE(nonexistent_matches.empty());

  // Also test forEach().
  TestVisitor visitor;
  EXPECT_EQ(total_inserted, this->hash_table_->forEachCompositeKey(&visitor));
  EXPECT_EQ(total_inserted, visitor.internal_map().size());
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    if (TypeParam::template_allow_duplicate_keys) {
      ASSERT_EQ(static_cast<std::size_t>(1 + (i % 3)),
                visitor.internal_map().count(i * (i + 1)));
      std::bitset<3> value_found;
      std::pair<std::unordered_multimap<std::int64_t, int>::const_iterator,
                std::unordered_multimap<std::int64_t, int>::const_iterator> match_range
          = visitor.internal_map().equal_range(i * (i + 1));
      for (std::unordered_multimap<std::int64_t, int>::const_iterator match_it = match_range.first;
           match_it != match_range.second;
           ++match_it) {
        ASSERT_LE(match_it->second - i * kNumSampleKeys, 3);
        EXPECT_FALSE(value_found[match_it->second - i * kNumSampleKeys]);
        value_found.set(match_it->second - i * kNumSampleKeys, true);
      }

      EXPECT_TRUE(value_found[0]);
      if (i % 3 > 0) {
        EXPECT_TRUE(value_found[1]);
      } else {
        EXPECT_FALSE(value_found[1]);
      }
      if (i % 3 > 1) {
        EXPECT_TRUE(value_found[2]);
      } else {
        EXPECT_FALSE(value_found[2]);
      }
    } else {
      ASSERT_EQ(1u, visitor.internal_map().count(i * (i + 1)));
      EXPECT_EQ(i * kNumSampleKeys,
                visitor.internal_map().find(i * (i + 1))->second);
    }
  }
}

TYPED_TEST_P(HashTableTestLongOnly, LongKeyPutAndGetFromValueAccessorTest) {
  this->runScalarKeyPutAndGetFromValueAccessorTest(TypeID::kLong);
}

TYPED_TEST_P(HashTableTest, CharKeyPutAndGetFromValueAccessorTest) {
  this->runScalarKeyPutAndGetFromValueAccessorTest(TypeID::kChar);
}

TYPED_TEST_P(HashTableTest, VarCharKeyPutAndGetFromValueAccessorTest) {
  this->runScalarKeyPutAndGetFromValueAccessorTest(TypeID::kVarChar);
}

TYPED_TEST_P(HashTableTest, CompositeKeyPutAndGetFromValueAccessorTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys);

  std::unique_ptr<ColumnVectorsValueAccessor> accessor(this->createSampleValueAccessor());

  std::vector<attribute_id> key_attr_ids;
  key_attr_ids.push_back(0);
  key_attr_ids.push_back(1);
  key_attr_ids.push_back(2);

  // Vectorized insert, skipping over null keys.
  TestInserter inserter;
  EXPECT_EQ(HashTablePutResult::kOK,
            this->hash_table_->putValueAccessorCompositeKey(accessor.get(),
                                                            key_attr_ids,
                                                            true,
                                                            &inserter));

  // Read values back out.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    ASSERT_EQ(1u, matches.size());
    EXPECT_EQ(i + (i >= kNumSampleKeys / 2),
              matches.front()->loadInternalInt());
  }

  // Also read the values out using the vectorized interface.
  accessor->beginIteration();
  TestVisitor visitor;
  this->hash_table_->getAllFromValueAccessorCompositeKey(accessor.get(),
                                                         key_attr_ids,
                                                         true,
                                                         &visitor);
  EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys), visitor.internal_map().size());
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    ASSERT_EQ(1u, visitor.internal_map().count(i * (i + 1)));
    EXPECT_EQ(i + (i >= kNumSampleKeys / 2),
              visitor.internal_map().find(i * (i + 1))->second);
  }
}

TYPED_TEST_P(HashTableTestLongOnly, LongKeyThreadedPutTest) {
  this->runScalarKeyThreadedPutTest(TypeID::kLong, false);
}

TYPED_TEST_P(HashTableTest, CharKeyThreadedPutTest) {
  this->runScalarKeyThreadedPutTest(TypeID::kChar, false);
}

TYPED_TEST_P(HashTableTest, VarCharKeyThreadedPutTest) {
  this->runScalarKeyThreadedPutTest(TypeID::kVarChar, false);
}

TYPED_TEST_P(HashTableTest, CompositeKeyThreadedPutTest) {
  this->runCompositeKeyThreadedPutTest(false);
}

TYPED_TEST_P(HashTableTestLongOnly, LongKeyClearTest) {
  this->runScalarKeyClearTest(TypeID::kLong);
}

TYPED_TEST_P(HashTableTest, CharKeyClearTest) {
  this->runScalarKeyClearTest(TypeID::kChar);
}

TYPED_TEST_P(HashTableTest, VarCharKeyClearTest) {
  this->runScalarKeyClearTest(TypeID::kVarChar);
}

TYPED_TEST_P(HashTableTest, CompositeKeyClearTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys);

  // Insert some key/value pairs.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    TestHashPayload value(i);
    EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->putCompositeKey(key, value));
  }

  // Clear out the HashTable.
  this->hash_table_->clear();

  // Make sure entries are cleared out.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));

    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    EXPECT_TRUE(matches.empty());
  }

  // Also make sure that forEach() sees an empty HashTable.
  TestVisitor visitor;
  EXPECT_EQ(0u, this->hash_table_->forEachCompositeKey(&visitor));
  EXPECT_EQ(0u, visitor.internal_map().size());
}

TYPED_TEST_P(ResizableHashTableTestLongOnly, LongKeyResizeTest) {
  this->runScalarKeyResizeTest(TypeID::kLong);
}

TYPED_TEST_P(ResizableHashTableTest, CharKeyResizeTest) {
  this->runScalarKeyResizeTest(TypeID::kChar);
}

TYPED_TEST_P(ResizableHashTableTest, VarCharKeyResizeTest) {
  this->runScalarKeyResizeTest(TypeID::kVarChar);
}

TYPED_TEST_P(ResizableHashTableTest, CompositeKeyResizeTest) {
  // Try to trigger a resize by substantially under-provisioning storage.
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createResizableHashTable(key_types, 1);

  const block_id original_blob_id = this->hash_table_->getBlobId();

  for (std::int64_t i = 0;
       i < static_cast<std::int64_t>(
               kSlotSizeBytes / (sizeof(std::size_t) + sizeof(TestHashPayload)));
       ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    TestHashPayload value(i);
    EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->putCompositeKey(key, value));
  }

  // If a resize occured, the block ID should be different now.
  EXPECT_NE(original_blob_id, this->hash_table_->getBlobId());

  // Read out the values.
  for (std::int64_t i = 0; i < 2 * kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));

    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    ASSERT_EQ(1u, matches.size());
    EXPECT_EQ(i, matches.front()->loadInternalInt());
  }
}

TYPED_TEST_P(ResizableHashTableTestLongOnly, LongKeyThreadedResizeTest) {
  this->runScalarKeyThreadedPutTest(TypeID::kLong, true);
}

TYPED_TEST_P(ResizableHashTableTest, CharKeyThreadedResizeTest) {
  this->runScalarKeyThreadedPutTest(TypeID::kChar, true);
}

TYPED_TEST_P(ResizableHashTableTest, VarCharKeyThreadedResizeTest) {
  this->runScalarKeyThreadedPutTest(TypeID::kVarChar, true);
}

TYPED_TEST_P(ResizableHashTableTest, CompositeKeyThreadedResizeTest) {
  this->runCompositeKeyThreadedPutTest(true);
}

TYPED_TEST_P(NonResizableHashTableTestLongOnly, LongKeyExhaustSpaceTest) {
  this->runScalarKeyExhaustSpaceTest(TypeID::kLong);
}

TYPED_TEST_P(NonResizableHashTableTest, CharKeyExhaustSpaceTest) {
  this->runScalarKeyExhaustSpaceTest(TypeID::kChar);
}

TYPED_TEST_P(NonResizableHashTableTest, VarCharKeyExhaustSpaceTest) {
  this->runScalarKeyExhaustSpaceTest(TypeID::kVarChar);
}

TYPED_TEST_P(NonResizableHashTableTest, CompositeKeyExhaustSpaceTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();

  // Under-provision storage and insert entries until we run out of space.
  const std::size_t buffer_size
      = kNumSampleKeys * (key_types.front()->maximumByteLength() + sizeof(typename TypeParam::value_type))
        / 4;
  this->createNonresizableHashTable(key_types, buffer_size, 0);

  std::int64_t i;
  for (i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    TestHashPayload value(i);
    HashTablePutResult result = this->hash_table_->putCompositeKey(key, value);
    if (result != HashTablePutResult::kOK) {
      EXPECT_EQ(HashTablePutResult::kOutOfSpace, result);
      break;
    }
  }

  EXPECT_LT(i, kNumSampleKeys);

  // Check the entries that we were able to insert.
  for (std::int64_t j = 0; j < i; ++j) {
    std::vector<TypedValue> key(this->createCompositeKey(j * (j + 1)));

    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    ASSERT_EQ(1u, matches.size());
    EXPECT_EQ(j, matches.front()->loadInternalInt());
  }

  // Check that the entry we failed to insert is not present.
  std::vector<TypedValue> failed_key(this->createCompositeKey(i * (i + 1)));
  std::vector<const TestHashPayload*> failed_matches;
  this->hash_table_->getAllCompositeKey(failed_key, &failed_matches);
  EXPECT_TRUE(failed_matches.empty());
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTestLongOnly, LongKeyUpsertTest) {
  this->runScalarKeyUpsertTest(TypeID::kLong);
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTest, CharKeyUpsertTest) {
  this->runScalarKeyUpsertTest(TypeID::kChar);
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTest, VarCharKeyUpsertTest) {
  this->runScalarKeyUpsertTest(TypeID::kVarChar);
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTest, CompositeKeyUpsertTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys);

  // Upsert some key/value pairs.
  TestHashPayload initial_value(42);
  TestUpserter upserter;
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    EXPECT_TRUE(this->hash_table_->upsertCompositeKey(key, initial_value, &upserter));
  }
  EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys), upserter.call_count());

  // Visit every other value a second time.
  for (std::int64_t i = 0; i < kNumSampleKeys; i += 2) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    EXPECT_TRUE(this->hash_table_->upsertCompositeKey(key, initial_value, &upserter));
  }
  EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys + (kNumSampleKeys / 2)),
            upserter.call_count());

  // Read out the values and check that they are as expected (initial value
  // for each was set to 42, and each call to TestUpserter increments by 1).
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));

    const TestHashPayload *value = this->hash_table_->getSingleCompositeKey(key);
    ASSERT_NE(nullptr, value);
    EXPECT_EQ(44 - (i % 2), value->loadInternalInt());
  }
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTestLongOnly, LongKeyUpsertValueAccessorTest) {
  this->runScalarKeyUpsertValueAccessorTest(TypeID::kLong);
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTest, CharKeyUpsertValueAccessorTest) {
  this->runScalarKeyUpsertValueAccessorTest(TypeID::kChar);
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTest, VarCharKeyUpsertValueAccessorTest) {
  this->runScalarKeyUpsertValueAccessorTest(TypeID::kVarChar);
}

TYPED_TEST_P(DuplicateKeysForbiddenHashTableTest, CompositeKeyUpsertValueAccessorTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys);

  std::unique_ptr<ColumnVectorsValueAccessor> accessor(this->createSampleValueAccessor());

  std::vector<attribute_id> key_attr_ids;
  key_attr_ids.push_back(0);
  key_attr_ids.push_back(1);
  key_attr_ids.push_back(2);

  // Vectorized upsert, skipping over null keys.
  TestHashPayload initial_value(42);
  TestUpserter upserter;
  EXPECT_TRUE(this->hash_table_->upsertValueAccessorCompositeKey(accessor.get(),
                                                                 key_attr_ids,
                                                                 true,
                                                                 initial_value,
                                                                 &upserter));
  EXPECT_EQ(static_cast<std::size_t>(kNumSampleKeys), upserter.call_count());

  // Read values out and check that they are as expected.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    ASSERT_EQ(1u, matches.size());
    EXPECT_EQ(43, matches.front()->loadInternalInt());
  }
}

TYPED_TEST_P(FixedSizeSerializableHashTableTestLongOnly, LongKeySerializationTest) {
  this->runScalarKeySerializationTest(TypeID::kLong);
}

TYPED_TEST_P(FixedSizeSerializableHashTableTest, CharKeySerializationTest) {
  this->runScalarKeySerializationTest(TypeID::kChar);
}

TYPED_TEST_P(FixedSizeSerializableHashTableTest, VarCharKeySerializationTest) {
  this->runScalarKeySerializationTest(TypeID::kVarChar);
}

TYPED_TEST_P(FixedSizeSerializableHashTableTest, CompositeKeySerializationTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  std::size_t maximum_key_size = 0;
  for (const Type *type : key_types) {
    maximum_key_size += type->maximumByteLength();
  }
  // Set up a shared memory buffer which will hold both the external keys and
  // the hash table.
  const std::size_t buffer_size
      = kNumSampleKeys * maximum_key_size
        + 8 * kNumSampleKeys * (maximum_key_size + sizeof(typename TypeParam::value_type));
  this->createNonresizableHashTable(key_types,
                                    buffer_size,
                                    kNumSampleKeys * maximum_key_size);

  // Create external keys in the first part of the buffer.
  char *key_ptr = static_cast<char*>(this->memory_buffer_->get());
  std::vector<std::vector<std::size_t>> key_sizes;
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    std::vector<std::size_t> component_sizes;
    for (const TypedValue &key_component : key) {
      key_component.copyInto(key_ptr);
      component_sizes.push_back(key_component.getDataSize());
      key_ptr += key_component.getDataSize();
    }
    key_sizes.emplace_back(component_sizes);
  }

  // Now actually insert.
  key_ptr = static_cast<char*>(this->memory_buffer_->get());
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key;
    for (std::size_t component_idx = 0;
         component_idx < key_types.size();
         ++component_idx) {
      key.emplace_back(key_types[component_idx]->makeValue(key_ptr, key_sizes[i][component_idx]));
      key_ptr += key_sizes[i][component_idx];
    }
    TestHashPayload value(i);
    EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->putCompositeKey(key, value));
  }

  // Destroy the HashTable object and copy the underlying memory.
  this->hash_table_.reset(nullptr);
  ScopedBuffer moved_buffer(buffer_size, kCacheLineBytes);
  std::memcpy(moved_buffer.get(), this->memory_buffer_->get(), buffer_size);
  this->memory_buffer_.reset(nullptr);

  // Recreate the HashTable at the new location.
  this->hash_table_.reset(new TypeParam(
      key_types,
      static_cast<char*>(moved_buffer.get()) + kNumSampleKeys * maximum_key_size,
      buffer_size - kNumSampleKeys * maximum_key_size,
      false,
      false));

  // If duplicate keys are not allowed, make sure we can't insert a
  // duplicate.
  if (!TypeParam::template_allow_duplicate_keys) {
    std::vector<TypedValue> key;
    key_ptr = static_cast<char*>(moved_buffer.get());
    for (std::size_t component_idx = 0;
         component_idx < key_types.size();
         ++component_idx) {
      key.emplace_back(key_types[component_idx]->makeValue(key_ptr, key_sizes[0][component_idx]));
      key_ptr += key_sizes[0][component_idx];
    }
    TestHashPayload value(123);
    EXPECT_EQ(HashTablePutResult::kDuplicateKey, this->hash_table_->putCompositeKey(key, value));
  }

  // Read the inserted values back out.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));

    // Test getAll() in all cases.
    std::vector<const TestHashPayload*> matches;
    this->hash_table_->getAllCompositeKey(key, &matches);
    ASSERT_EQ(1u, matches.size());
    EXPECT_EQ(i, matches.front()->loadInternalInt());
  }

  // Check a nonexistent key.
  std::vector<TypedValue> nonexistent_key(
      this->createCompositeKey(kNumSampleKeys * kNumSampleKeys * kNumSampleKeys));
  std::vector<const TestHashPayload*> nonexistent_matches;
  this->hash_table_->getAllCompositeKey(nonexistent_key, &nonexistent_matches);
  EXPECT_TRUE(nonexistent_matches.empty());
}

TYPED_TEST_P(NonTriviallyDestructibleValueHashTableTestLongOnly, LongKeyDestroyValueTest) {
  this->runScalarKeyDestroyValueTest(TypeID::kLong);
}

TYPED_TEST_P(NonTriviallyDestructibleValueHashTableTest, CharKeyDestroyValueTest) {
  this->runScalarKeyDestroyValueTest(TypeID::kChar);
}

TYPED_TEST_P(NonTriviallyDestructibleValueHashTableTest, VarCharKeyDestroyValueTest) {
  this->runScalarKeyDestroyValueTest(TypeID::kVarChar);
}

TYPED_TEST_P(NonTriviallyDestructibleValueHashTableTest, CompositeKeyDestroyValueTest) {
  std::vector<const Type*> key_types = this->SetupCompositeKeyType();
  this->createHashTableSimple(key_types, kNumSampleKeys);

  std::atomic<int> destruct_count(0);

  // Insert some key/value pairs.
  for (std::int64_t i = 0; i < kNumSampleKeys; ++i) {
    std::vector<TypedValue> key(this->createCompositeKey(i * (i + 1)));
    NonTriviallyDestructibleTestHashPayload value(&destruct_count);
    EXPECT_EQ(HashTablePutResult::kOK, this->hash_table_->putCompositeKey(key, value));
    value.clearDestructCountPtr();
  }

  // Destroy the hash table and check that the destructors of inserted values
  // were invoked.
  this->hash_table_.reset(nullptr);
  EXPECT_EQ(kNumSampleKeys, destruct_count.load(std::memory_order_relaxed));
}

REGISTER_TYPED_TEST_CASE_P(HashTableTestLongOnly,
                           LongKeyPutAndGetTest,
                           LongKeyPutDuplicateKeysTest,
                           LongKeyPutAndGetFromValueAccessorTest,
                           LongKeyThreadedPutTest,
                           LongKeyClearTest);

REGISTER_TYPED_TEST_CASE_P(HashTableTest,
                           CharKeyPutAndGetTest,
                           VarCharKeyPutAndGetTest,
                           CompositeKeyPutAndGetTest,
                           SpecialHashesPutAndGetTest,
                           CharKeyPutDuplicateKeysTest,
                           VarCharKeyPutDuplicateKeysTest,
                           CompositeKeyPutDuplicateKeysTest,
                           CharKeyPutAndGetFromValueAccessorTest,
                           VarCharKeyPutAndGetFromValueAccessorTest,
                           CompositeKeyPutAndGetFromValueAccessorTest,
                           CharKeyThreadedPutTest,
                           VarCharKeyThreadedPutTest,
                           CompositeKeyThreadedPutTest,
                           CharKeyClearTest,
                           VarCharKeyClearTest,
                           CompositeKeyClearTest);

REGISTER_TYPED_TEST_CASE_P(ResizableHashTableTestLongOnly,
                           LongKeyResizeTest,
                           LongKeyThreadedResizeTest);

REGISTER_TYPED_TEST_CASE_P(ResizableHashTableTest,
                           CharKeyResizeTest,
                           VarCharKeyResizeTest,
                           CompositeKeyResizeTest,
                           CharKeyThreadedResizeTest,
                           VarCharKeyThreadedResizeTest,
                           CompositeKeyThreadedResizeTest);

REGISTER_TYPED_TEST_CASE_P(NonResizableHashTableTestLongOnly,
                           LongKeyExhaustSpaceTest);

REGISTER_TYPED_TEST_CASE_P(NonResizableHashTableTest,
                           CharKeyExhaustSpaceTest,
                           VarCharKeyExhaustSpaceTest,
                           CompositeKeyExhaustSpaceTest);

REGISTER_TYPED_TEST_CASE_P(DuplicateKeysForbiddenHashTableTestLongOnly,
                           LongKeyUpsertTest,
                           LongKeyUpsertValueAccessorTest);

REGISTER_TYPED_TEST_CASE_P(DuplicateKeysForbiddenHashTableTest,
                           CharKeyUpsertTest,
                           VarCharKeyUpsertTest,
                           CompositeKeyUpsertTest,
                           CharKeyUpsertValueAccessorTest,
                           VarCharKeyUpsertValueAccessorTest,
                           CompositeKeyUpsertValueAccessorTest);

REGISTER_TYPED_TEST_CASE_P(FixedSizeSerializableHashTableTestLongOnly,
                           LongKeySerializationTest);

REGISTER_TYPED_TEST_CASE_P(FixedSizeSerializableHashTableTest,
                           CharKeySerializationTest,
                           VarCharKeySerializationTest,
                           CompositeKeySerializationTest);

REGISTER_TYPED_TEST_CASE_P(NonTriviallyDestructibleValueHashTableTestLongOnly,
                           LongKeyDestroyValueTest);

REGISTER_TYPED_TEST_CASE_P(NonTriviallyDestructibleValueHashTableTest,
                           CharKeyDestroyValueTest,
                           VarCharKeyDestroyValueTest,
                           CompositeKeyDestroyValueTest);

}  // namespace quickstep

// Macro to automatically instantiate tests for all the different flavors of
// the specificied HashTable implementation template.
#define QUICKSTEP_TEST_HASHTABLE_IMPL(HashTableImpl)                        \
namespace quickstep {                                                       \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, false, false, false>,             \
    HashTableImpl<TestHashPayload, false, false, false, true>,              \
    HashTableImpl<TestHashPayload, false, false, true, false>,              \
    HashTableImpl<TestHashPayload, false, false, true, true>,               \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, true>,               \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, false, true, true, true>,                \
    HashTableImpl<TestHashPayload, true, false, false, false>,              \
    HashTableImpl<TestHashPayload, true, false, false, true>,               \
    HashTableImpl<TestHashPayload, true, false, true, false>,               \
    HashTableImpl<TestHashPayload, true, false, true, true>,                \
    HashTableImpl<TestHashPayload, true, true, true, false>,                \
    HashTableImpl<TestHashPayload, true, true, true, true>>                 \
        _CommonTestTypes;                                                   \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              HashTableTestLongOnly,                        \
                              _CommonTestTypes);                            \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              HashTableTest,                                \
                              _CommonTestTypes);                            \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, true, false, false, false>,              \
    HashTableImpl<TestHashPayload, true, false, false, true>,               \
    HashTableImpl<TestHashPayload, true, false, true, false>,               \
    HashTableImpl<TestHashPayload, true, false, true, true>,                \
    HashTableImpl<TestHashPayload, true, true, true, false>,                \
    HashTableImpl<TestHashPayload, true, true, true, true>>                 \
        _ResizableTestTypes;                                                \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              ResizableHashTableTestLongOnly,               \
                              _ResizableTestTypes);                         \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              ResizableHashTableTest,                       \
                              _ResizableTestTypes);                         \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, false, false, false>,             \
    HashTableImpl<TestHashPayload, false, false, false, true>,              \
    HashTableImpl<TestHashPayload, false, false, true, false>,              \
    HashTableImpl<TestHashPayload, false, false, true, true>,               \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, true>,               \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, false, true, true, true>>                \
        _NonResizableTestTypes;                                             \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              NonResizableHashTableTestLongOnly,            \
                              _NonResizableTestTypes);                      \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              NonResizableHashTableTest,                    \
                              _NonResizableTestTypes);                      \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, false, false, false>,             \
    HashTableImpl<TestHashPayload, false, false, true, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, true, false, false, false>,              \
    HashTableImpl<TestHashPayload, true, false, true, false>,               \
    HashTableImpl<TestHashPayload, true, true, true, false>>                \
        _DuplicateKeysForbiddenTypes;                                       \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              DuplicateKeysForbiddenHashTableTestLongOnly,  \
                              _DuplicateKeysForbiddenTypes);                \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              DuplicateKeysForbiddenHashTableTest,          \
                              _DuplicateKeysForbiddenTypes);                \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, true>,               \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, false, true, true, true>>                \
        _FixedSizeSerializableTestTypes;                                    \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              FixedSizeSerializableHashTableTestLongOnly,   \
                              _FixedSizeSerializableTestTypes);             \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              FixedSizeSerializableHashTableTest,           \
                              _FixedSizeSerializableTestTypes);             \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, false, false>,                              \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, false, true>,                               \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, true, false>,                               \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, true, true>,                                \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, false, false>,                               \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, false, true>,                                \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, true, false>,                                \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, true, true>>                                 \
        _NonTriviallyDestructibleNonSerializableTestTypes;                  \
INSTANTIATE_TYPED_TEST_CASE_P(                                              \
    HashTableImpl,                                                          \
    NonTriviallyDestructibleValueHashTableTestLongOnly,                     \
    _NonTriviallyDestructibleNonSerializableTestTypes);                     \
INSTANTIATE_TYPED_TEST_CASE_P(                                              \
    HashTableImpl,                                                          \
    NonTriviallyDestructibleValueHashTableTest,                             \
    _NonTriviallyDestructibleNonSerializableTestTypes);                     \
                                                                            \
}  /* namespace quickstep */                                                \
struct quickstep_hashtable_test_dummy  /* NOLINT(build/class) */

// Similar to QUICKSTEP_TEST_HASHTABLE_IMPL(), but only instantiates test cases
// that use LONG keys.
#define QUICKSTEP_TEST_HASHTABLE_IMPL_LONG_ONLY(HashTableImpl)              \
namespace quickstep {                                                       \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, false, false, false>,             \
    HashTableImpl<TestHashPayload, false, false, false, true>,              \
    HashTableImpl<TestHashPayload, false, false, true, false>,              \
    HashTableImpl<TestHashPayload, false, false, true, true>,               \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, true>,               \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, false, true, true, true>,                \
    HashTableImpl<TestHashPayload, true, false, false, false>,              \
    HashTableImpl<TestHashPayload, true, false, false, true>,               \
    HashTableImpl<TestHashPayload, true, false, true, false>,               \
    HashTableImpl<TestHashPayload, true, false, true, true>,                \
    HashTableImpl<TestHashPayload, true, true, true, false>,                \
    HashTableImpl<TestHashPayload, true, true, true, true>>                 \
        _CommonTestTypes;                                                   \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              HashTableTestLongOnly,                        \
                              _CommonTestTypes);                            \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, true, false, false, false>,              \
    HashTableImpl<TestHashPayload, true, false, false, true>,               \
    HashTableImpl<TestHashPayload, true, false, true, false>,               \
    HashTableImpl<TestHashPayload, true, false, true, true>,                \
    HashTableImpl<TestHashPayload, true, true, true, false>,                \
    HashTableImpl<TestHashPayload, true, true, true, true>>                 \
        _ResizableTestTypes;                                                \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              ResizableHashTableTestLongOnly,               \
                              _ResizableTestTypes);                         \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, false, false, false>,             \
    HashTableImpl<TestHashPayload, false, false, false, true>,              \
    HashTableImpl<TestHashPayload, false, false, true, false>,              \
    HashTableImpl<TestHashPayload, false, false, true, true>,               \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, true>,               \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, false, true, true, true>>                \
        _NonResizableTestTypes;                                             \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              NonResizableHashTableTestLongOnly,            \
                              _NonResizableTestTypes);                      \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, false, false, false>,             \
    HashTableImpl<TestHashPayload, false, false, true, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, true, false, false, false>,              \
    HashTableImpl<TestHashPayload, true, false, true, false>,               \
    HashTableImpl<TestHashPayload, true, true, true, false>>                \
        _DuplicateKeysForbiddenTypes;                                       \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              DuplicateKeysForbiddenHashTableTestLongOnly,  \
                              _DuplicateKeysForbiddenTypes);                \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<TestHashPayload, false, true, false, false>,              \
    HashTableImpl<TestHashPayload, false, true, false, true>,               \
    HashTableImpl<TestHashPayload, false, true, true, false>,               \
    HashTableImpl<TestHashPayload, false, true, true, true>>                \
        _FixedSizeSerializableTestTypes;                                    \
INSTANTIATE_TYPED_TEST_CASE_P(HashTableImpl,                                \
                              FixedSizeSerializableHashTableTestLongOnly,   \
                              _FixedSizeSerializableTestTypes);             \
                                                                            \
typedef ::testing::Types<                                                   \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, false, false>,                              \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, false, true>,                               \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, true, false>,                               \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  false, false, true, true>,                                \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, false, false>,                               \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, false, true>,                                \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, true, false>,                                \
    HashTableImpl<NonTriviallyDestructibleTestHashPayload,                  \
                  true, false, true, true>>                                 \
        _NonTriviallyDestructibleNonSerializableTestTypes;                  \
INSTANTIATE_TYPED_TEST_CASE_P(                                              \
    HashTableImpl,                                                          \
    NonTriviallyDestructibleValueHashTableTestLongOnly,                     \
    _NonTriviallyDestructibleNonSerializableTestTypes);                     \
                                                                            \
}  /* namespace quickstep */                                                \
struct quickstep_hashtable_test_dummy  /* NOLINT(build/class) */

#endif  // QUICKSTEP_STORAGE_TESTS_HASHTABLE_UNITTEST_COMMON_HPP_
