1e735f23018b398f45bd052b63616d7a45e29515bJeff Brown/* 2e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * Copyright (C) 2011 The Android Open Source Project 3e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * 4e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * you may not use this file except in compliance with the License. 6e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * You may obtain a copy of the License at 7e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * 8e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * 10e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * Unless required by applicable law or agreed to in writing, software 11e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * See the License for the specific language governing permissions and 14e735f23018b398f45bd052b63616d7a45e29515bJeff Brown * limitations under the License. 15e735f23018b398f45bd052b63616d7a45e29515bJeff Brown */ 16e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 17e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#define LOG_TAG "BasicHashtable_test" 18e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 19e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#include <utils/BasicHashtable.h> 20e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#include <cutils/log.h> 21e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#include <gtest/gtest.h> 22e735f23018b398f45bd052b63616d7a45e29515bJeff Brown#include <unistd.h> 23e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 2427d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albertnamespace { 25e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 26e735f23018b398f45bd052b63616d7a45e29515bJeff Browntypedef int SimpleKey; 27e735f23018b398f45bd052b63616d7a45e29515bJeff Browntypedef int SimpleValue; 2827d166cb3aecc003b2ea576ec23695aff78de1a5Dan Alberttypedef android::key_value_pair_t<SimpleKey, SimpleValue> SimpleEntry; 2927d166cb3aecc003b2ea576ec23695aff78de1a5Dan Alberttypedef android::BasicHashtable<SimpleKey, SimpleEntry> SimpleHashtable; 30e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 31e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstruct ComplexKey { 32e735f23018b398f45bd052b63616d7a45e29515bJeff Brown int k; 33e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 34e735f23018b398f45bd052b63616d7a45e29515bJeff Brown explicit ComplexKey(int k) : k(k) { 35e735f23018b398f45bd052b63616d7a45e29515bJeff Brown instanceCount += 1; 36e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 37e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 38e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexKey(const ComplexKey& other) : k(other.k) { 39e735f23018b398f45bd052b63616d7a45e29515bJeff Brown instanceCount += 1; 40e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 41e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 42e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ~ComplexKey() { 43e735f23018b398f45bd052b63616d7a45e29515bJeff Brown instanceCount -= 1; 44e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 45e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 46e735f23018b398f45bd052b63616d7a45e29515bJeff Brown bool operator ==(const ComplexKey& other) const { 47e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return k == other.k; 48e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 49e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 50e735f23018b398f45bd052b63616d7a45e29515bJeff Brown bool operator !=(const ComplexKey& other) const { 51e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return k != other.k; 52e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 53e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 54e735f23018b398f45bd052b63616d7a45e29515bJeff Brown static ssize_t instanceCount; 55e735f23018b398f45bd052b63616d7a45e29515bJeff Brown}; 56e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 57e735f23018b398f45bd052b63616d7a45e29515bJeff Brownssize_t ComplexKey::instanceCount = 0; 58e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 59e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstruct ComplexValue { 60e735f23018b398f45bd052b63616d7a45e29515bJeff Brown int v; 61e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 62e735f23018b398f45bd052b63616d7a45e29515bJeff Brown explicit ComplexValue(int v) : v(v) { 63e735f23018b398f45bd052b63616d7a45e29515bJeff Brown instanceCount += 1; 64e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 65e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 66e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexValue(const ComplexValue& other) : v(other.v) { 67e735f23018b398f45bd052b63616d7a45e29515bJeff Brown instanceCount += 1; 68e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 69e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 70e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ~ComplexValue() { 71e735f23018b398f45bd052b63616d7a45e29515bJeff Brown instanceCount -= 1; 72e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 73e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 74e735f23018b398f45bd052b63616d7a45e29515bJeff Brown static ssize_t instanceCount; 75e735f23018b398f45bd052b63616d7a45e29515bJeff Brown}; 76e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 77e735f23018b398f45bd052b63616d7a45e29515bJeff Brownssize_t ComplexValue::instanceCount = 0; 78e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 7927d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert} // namespace 8027d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 8127d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 8227d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albertnamespace android { 8327d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 84e735f23018b398f45bd052b63616d7a45e29515bJeff Browntypedef key_value_pair_t<ComplexKey, ComplexValue> ComplexEntry; 85e735f23018b398f45bd052b63616d7a45e29515bJeff Browntypedef BasicHashtable<ComplexKey, ComplexEntry> ComplexHashtable; 86e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 8727d166cb3aecc003b2ea576ec23695aff78de1a5Dan Alberttemplate<> inline hash_t hash_type(const ComplexKey& value) { 8827d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert return hash_type(value.k); 8927d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert} 9027d166cb3aecc003b2ea576ec23695aff78de1a5Dan Albert 91e735f23018b398f45bd052b63616d7a45e29515bJeff Brownclass BasicHashtableTest : public testing::Test { 92e735f23018b398f45bd052b63616d7a45e29515bJeff Brownprotected: 93e735f23018b398f45bd052b63616d7a45e29515bJeff Brown virtual void SetUp() { 94e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexKey::instanceCount = 0; 95e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexValue::instanceCount = 0; 96e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 97e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 98e735f23018b398f45bd052b63616d7a45e29515bJeff Brown virtual void TearDown() { 99e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 100e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 101e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 102e735f23018b398f45bd052b63616d7a45e29515bJeff Brown void assertInstanceCount(ssize_t keys, ssize_t values) { 103e735f23018b398f45bd052b63616d7a45e29515bJeff Brown if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) { 104e735f23018b398f45bd052b63616d7a45e29515bJeff Brown FAIL() << "Expected " << keys << " keys and " << values << " values " 105e735f23018b398f45bd052b63616d7a45e29515bJeff Brown "but there were actually " << ComplexKey::instanceCount << " keys and " 106e735f23018b398f45bd052b63616d7a45e29515bJeff Brown << ComplexValue::instanceCount << " values"; 107e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 108e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 109e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 110e735f23018b398f45bd052b63616d7a45e29515bJeff Brownpublic: 111e735f23018b398f45bd052b63616d7a45e29515bJeff Brown template <typename TKey, typename TEntry> 112e735f23018b398f45bd052b63616d7a45e29515bJeff Brown static void cookieAt(const BasicHashtable<TKey, TEntry>& h, size_t index, 113e735f23018b398f45bd052b63616d7a45e29515bJeff Brown bool* collision, bool* present, hash_t* hash) { 114e735f23018b398f45bd052b63616d7a45e29515bJeff Brown uint32_t cookie = h.cookieAt(index); 115e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *collision = cookie & BasicHashtable<TKey, TEntry>::Bucket::COLLISION; 116e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *present = cookie & BasicHashtable<TKey, TEntry>::Bucket::PRESENT; 117e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *hash = cookie & BasicHashtable<TKey, TEntry>::Bucket::HASH_MASK; 118e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 119e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 120e735f23018b398f45bd052b63616d7a45e29515bJeff Brown template <typename TKey, typename TEntry> 121e735f23018b398f45bd052b63616d7a45e29515bJeff Brown static const void* getBuckets(const BasicHashtable<TKey, TEntry>& h) { 122e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return h.mBuckets; 123e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 124e735f23018b398f45bd052b63616d7a45e29515bJeff Brown}; 125e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 126e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TKey, typename TValue> 127e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstatic size_t add(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h, 128e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const TKey& key, const TValue& value) { 129e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return h.add(hash_type(key), key_value_pair_t<TKey, TValue>(key, value)); 130e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 131e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 132e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TKey, typename TValue> 133e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstatic ssize_t find(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h, 134e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index, const TKey& key) { 135e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return h.find(index, hash_type(key), key); 136e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 137e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 138e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TKey, typename TValue> 139e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstatic bool remove(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h, 140e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const TKey& key) { 141e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index = find(h, -1, key); 142e735f23018b398f45bd052b63616d7a45e29515bJeff Brown if (index >= 0) { 143e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.removeAt(index); 144e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return true; 145e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 146e735f23018b398f45bd052b63616d7a45e29515bJeff Brown return false; 147e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 148e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 149e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TEntry> 150e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstatic void getKeyValue(const TEntry& entry, int* key, int* value); 151e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 152e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <> void getKeyValue(const SimpleEntry& entry, int* key, int* value) { 153e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *key = entry.key; 154e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *value = entry.value; 155e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 156e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 157e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <> void getKeyValue(const ComplexEntry& entry, int* key, int* value) { 158e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *key = entry.key.k; 159e735f23018b398f45bd052b63616d7a45e29515bJeff Brown *value = entry.value.v; 160e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 161e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 162e735f23018b398f45bd052b63616d7a45e29515bJeff Browntemplate <typename TKey, typename TValue> 163e735f23018b398f45bd052b63616d7a45e29515bJeff Brownstatic void dump(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h) { 164eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("hashtable %p, size=%u, capacity=%u, bucketCount=%u", 165e735f23018b398f45bd052b63616d7a45e29515bJeff Brown &h, h.size(), h.capacity(), h.bucketCount()); 166e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t i = 0; i < h.bucketCount(); i++) { 167e735f23018b398f45bd052b63616d7a45e29515bJeff Brown bool collision, present; 168e735f23018b398f45bd052b63616d7a45e29515bJeff Brown hash_t hash; 169e735f23018b398f45bd052b63616d7a45e29515bJeff Brown BasicHashtableTest::cookieAt(h, i, &collision, &present, &hash); 170e735f23018b398f45bd052b63616d7a45e29515bJeff Brown if (present) { 171e735f23018b398f45bd052b63616d7a45e29515bJeff Brown int key, value; 172e735f23018b398f45bd052b63616d7a45e29515bJeff Brown getKeyValue(h.entryAt(i), &key, &value); 173eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD(" [%3u] = collision=%d, present=%d, hash=0x%08x, key=%3d, value=%3d, " 174e735f23018b398f45bd052b63616d7a45e29515bJeff Brown "hash_type(key)=0x%08x", 175e735f23018b398f45bd052b63616d7a45e29515bJeff Brown i, collision, present, hash, key, value, hash_type(key)); 176e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } else { 177eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD(" [%3u] = collision=%d, present=%d", 178e735f23018b398f45bd052b63616d7a45e29515bJeff Brown i, collision, present); 179e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 180e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 181e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 182e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 183e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, DefaultConstructor_WithDefaultProperties) { 184e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 185e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 186e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 187e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 188e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 189e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 190e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 191e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 192e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Constructor_WithNonUnityLoadFactor) { 193e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h(52, 0.8f); 194e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 195e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 196e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(77U, h.capacity()); 197e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(97U, h.bucketCount()); 198e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.8f, h.loadFactor()); 199e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 200e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 201e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndExactCapacity) { 202e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h(46, 1.0f); 203e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 204e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 205e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f 206e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(47U, h.bucketCount()); 207e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(1.0f, h.loadFactor()); 208e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 209e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 210e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndInexactCapacity) { 211e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h(42, 1.0f); 212e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 213e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 214e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f 215e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(47U, h.bucketCount()); 216e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(1.0f, h.loadFactor()); 217e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 218e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 219e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, FindAddFindRemoveFind_OneEntry) { 220e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 221e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index = find(h, -1, 8); 222e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 223e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 224e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = add(h, 8, 1); 225e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(1U, h.size()); 226e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 227e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(index, find(h, -1, 8)); 228e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(8, h.entryAt(index).key); 229e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(1, h.entryAt(index).value); 230e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 231e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, index, 8); 232e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 233e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 234e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_TRUE(remove(h, 8)); 235e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(0U, h.size()); 236e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 237e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, -1, 8); 238e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 239e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 240e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 241e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithUniqueKey) { 242e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const size_t N = 11; 243e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 244e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 245e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t i = 0; i < N; i++) { 246e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index = find(h, -1, int(i)); 247e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 248e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 249e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = add(h, int(i), int(i * 10)); 250e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(i + 1, h.size()); 251e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 252e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(index, find(h, -1, int(i))); 253e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(int(i), h.entryAt(index).key); 254e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(int(i * 10), h.entryAt(index).value); 255e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 256e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, index, int(i)); 257e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 258e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 259e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 260e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t i = N; --i > 0; ) { 261e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_TRUE(remove(h, int(i))) << "i = " << i; 262e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(i, h.size()); 263e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 264e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index = find(h, -1, int(i)); 265e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 266e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 267e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 268e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 269e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithDuplicateKey) { 270e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const size_t N = 11; 271e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const int K = 1; 272e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 273e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 274e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t i = 0; i < N; i++) { 275e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index = find(h, -1, K); 276e735f23018b398f45bd052b63616d7a45e29515bJeff Brown if (i == 0) { 277e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 278e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } else { 279e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE(-1, index); 280e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 281e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 282e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, K, int(i)); 283e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(i + 1, h.size()); 284e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 285e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = -1; 286e735f23018b398f45bd052b63616d7a45e29515bJeff Brown int values = 0; 287e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t j = 0; j <= i; j++) { 288e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, index, K); 289e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_GE(index, 0); 290e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(K, h.entryAt(index).key); 291e735f23018b398f45bd052b63616d7a45e29515bJeff Brown values |= 1 << h.entryAt(index).value; 292e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 293e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(values, (1 << (i + 1)) - 1); 294e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 295e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, index, K); 296e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 297e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 298e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 299e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t i = N; --i > 0; ) { 300e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_TRUE(remove(h, K)) << "i = " << i; 301e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(i, h.size()); 302e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 303e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index = -1; 304e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t j = 0; j < i; j++) { 305e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, index, K); 306e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_GE(index, 0); 307e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(K, h.entryAt(index).key); 308e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 309e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 310e735f23018b398f45bd052b63616d7a45e29515bJeff Brown index = find(h, index, K); 311e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, index); 312e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 313e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 314e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 315e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Clear_WhenAlreadyEmpty_DoesNothing) { 316e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 317e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.clear(); 318e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 319e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 320e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 321e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 322e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 323e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 324e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 325e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Clear_AfterElementsAdded_RemovesThem) { 326e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 327e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, 0, 0); 328e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, 1, 0); 329e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.clear(); 330e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 331e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 332e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 333e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 334e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 335e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 336e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 337e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Clear_AfterElementsAdded_DestroysThem) { 338e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h; 339e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(0), ComplexValue(0)); 340e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(1), ComplexValue(0)); 341e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 342e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 343e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.clear(); 344e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 345e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 346e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 347e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 348e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 349e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 350e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 351e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 352e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Remove_AfterElementsAdded_DestroysThem) { 353e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h; 354e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(0), ComplexValue(0)); 355e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(1), ComplexValue(0)); 356e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 357e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 358e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_TRUE(remove(h, ComplexKey(0))); 359e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1)); 360e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 361e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_TRUE(remove(h, ComplexKey(1))); 362e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 363e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 364e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 365e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 366e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 367e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 368e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 369e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 370e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Destructor_AfterElementsAdded_DestroysThem) { 371e735f23018b398f45bd052b63616d7a45e29515bJeff Brown { 372e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h; 373e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(0), ComplexValue(0)); 374e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(1), ComplexValue(0)); 375e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 376e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } // h is destroyed here 377e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 378e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 379e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 380e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 381e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Next_WhenEmpty_ReturnsMinusOne) { 382e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 383e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 384e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(-1, h.next(-1)); 385e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 386e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 387e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Next_WhenNonEmpty_IteratesOverAllEntries) { 388e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const int N = 88; 389e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 390e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 391e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (int i = 0; i < N; i++) { 392e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, i, i * 10); 393e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 394e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 395e735f23018b398f45bd052b63616d7a45e29515bJeff Brown bool set[N]; 396e735f23018b398f45bd052b63616d7a45e29515bJeff Brown memset(set, 0, sizeof(bool) * N); 397e735f23018b398f45bd052b63616d7a45e29515bJeff Brown int count = 0; 398e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (ssize_t index = -1; (index = h.next(index)) != -1; ) { 399e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_GE(index, 0); 400e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_LT(size_t(index), h.bucketCount()); 401e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 402e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const SimpleEntry& entry = h.entryAt(index); 403e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_GE(entry.key, 0); 404e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_LT(entry.key, N); 405cdc1cfb3e51f3caddc1f290b46dc789c036f22edSasha Levitskiy ASSERT_FALSE(set[entry.key]); 406e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(entry.key * 10, entry.value); 407e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 408e735f23018b398f45bd052b63616d7a45e29515bJeff Brown set[entry.key] = true; 409e735f23018b398f45bd052b63616d7a45e29515bJeff Brown count += 1; 410e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 411e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(N, count); 412e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 413e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 414e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Add_RehashesOnDemand) { 415e735f23018b398f45bd052b63616d7a45e29515bJeff Brown SimpleHashtable h; 416e735f23018b398f45bd052b63616d7a45e29515bJeff Brown size_t initialCapacity = h.capacity(); 417e735f23018b398f45bd052b63616d7a45e29515bJeff Brown size_t initialBucketCount = h.bucketCount(); 418e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 419e735f23018b398f45bd052b63616d7a45e29515bJeff Brown for (size_t i = 0; i < initialCapacity; i++) { 420e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, int(i), 0); 421e735f23018b398f45bd052b63616d7a45e29515bJeff Brown } 422e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 423e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(initialCapacity, h.size()); 424e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(initialCapacity, h.capacity()); 425e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(initialBucketCount, h.bucketCount()); 426e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 427e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, -1, -1); 428e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 429e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(initialCapacity + 1, h.size()); 430e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_GT(h.capacity(), initialCapacity); 431e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_GT(h.bucketCount(), initialBucketCount); 432e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_GT(h.bucketCount(), h.capacity()); 433e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 434e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 435e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Rehash_WhenCapacityAndBucketCountUnchanged_DoesNothing) { 436e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h; 437e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(0), ComplexValue(0)); 438e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const void* oldBuckets = getBuckets(h); 439e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE((void*)NULL, oldBuckets); 440e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1)); 441e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 442e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.rehash(h.capacity(), h.loadFactor()); 443e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 444e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(oldBuckets, getBuckets(h)); 445e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1)); 446e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 447e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 448e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasNoBuckets_ButDoesNotAllocateBuckets) { 449e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h; 450e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ((void*)NULL, getBuckets(h)); 451e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 452e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 453e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.rehash(9, 1.0f); 454e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 455e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 456e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(10U, h.capacity()); 457e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(11U, h.bucketCount()); 458e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(1.0f, h.loadFactor()); 459e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ((void*)NULL, getBuckets(h)); 460e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 461e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 462e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 463e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasBuckets_ReleasesBucketsAndSetsCapacity) { 464e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h(10); 465e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(0), ComplexValue(0)); 466e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_TRUE(remove(h, ComplexKey(0))); 467e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE((void*)NULL, getBuckets(h)); 468e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 469e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 470e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.rehash(0, 0.75f); 471e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 472e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h.size()); 473e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 474e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 475e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 476e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ((void*)NULL, getBuckets(h)); 477e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0)); 478e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 479e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 480e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, Rehash_WhenLessThanCurrentCapacity_ShrinksBuckets) { 481e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h(10); 482e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(0), ComplexValue(0)); 483e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h, ComplexKey(1), ComplexValue(1)); 484e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const void* oldBuckets = getBuckets(h); 485e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 486e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 487e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h.rehash(0, 0.75f); 488e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 489e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(2U, h.size()); 490e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h.capacity()); 491e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(5U, h.bucketCount()); 492e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0.75f, h.loadFactor()); 493e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_NE(oldBuckets, getBuckets(h)); 494e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 495e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 496e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 497e735f23018b398f45bd052b63616d7a45e29515bJeff BrownTEST_F(BasicHashtableTest, CopyOnWrite) { 498e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h1; 499e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h1, ComplexKey(0), ComplexValue(0)); 500e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h1, ComplexKey(1), ComplexValue(1)); 501e735f23018b398f45bd052b63616d7a45e29515bJeff Brown const void* originalBuckets = getBuckets(h1); 502e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 503e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ssize_t index0 = find(h1, -1, ComplexKey(0)); 504e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_GE(index0, 0); 505e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 506e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // copy constructor acquires shared reference 507e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h2(h1); 508e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 509e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(originalBuckets, getBuckets(h2)); 510e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.size(), h2.size()); 511e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.capacity(), h2.capacity()); 512e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.bucketCount(), h2.bucketCount()); 513e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.loadFactor(), h2.loadFactor()); 514e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(index0, find(h2, -1, ComplexKey(0))); 515e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 516e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // operator= acquires shared reference 517e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ComplexHashtable h3; 518e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h3 = h2; 519e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 520e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(originalBuckets, getBuckets(h3)); 521e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.size(), h3.size()); 522e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.capacity(), h3.capacity()); 523e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.bucketCount(), h3.bucketCount()); 524e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h1.loadFactor(), h3.loadFactor()); 525e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(index0, find(h3, -1, ComplexKey(0))); 526e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 527e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // editEntryAt copies shared contents 528e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h1.editEntryAt(index0).value.v = 42; 529e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4)); 530e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE(originalBuckets, getBuckets(h1)); 531e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(42, h1.entryAt(index0).value.v); 532e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0, h2.entryAt(index0).value.v); 533e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0, h3.entryAt(index0).value.v); 534e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 535e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // clear releases reference to shared contents 536e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h2.clear(); 537e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4)); 538e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h2.size()); 539e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE(originalBuckets, getBuckets(h2)); 540e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 541e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // operator= acquires shared reference, destroys unshared contents 542e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h1 = h3; 543e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 544e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(originalBuckets, getBuckets(h1)); 545e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h3.size(), h1.size()); 546e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h3.capacity(), h1.capacity()); 547e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h3.bucketCount(), h1.bucketCount()); 548e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(h3.loadFactor(), h1.loadFactor()); 549e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(index0, find(h1, -1, ComplexKey(0))); 550e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 551e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // add copies shared contents 552e735f23018b398f45bd052b63616d7a45e29515bJeff Brown add(h1, ComplexKey(2), ComplexValue(2)); 553e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(5, 5)); 554e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE(originalBuckets, getBuckets(h1)); 555e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(3U, h1.size()); 556e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h2.size()); 557e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(2U, h3.size()); 558e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 559e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // remove copies shared contents 560e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h1 = h3; 561e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 562e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(originalBuckets, getBuckets(h1)); 563e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h1.removeAt(index0); 564e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(3, 3)); 565e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE(originalBuckets, getBuckets(h1)); 566e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(1U, h1.size()); 567e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h2.size()); 568e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(2U, h3.size()); 569e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 570e735f23018b398f45bd052b63616d7a45e29515bJeff Brown // rehash copies shared contents 571e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h1 = h3; 572e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2)); 573e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_EQ(originalBuckets, getBuckets(h1)); 574e735f23018b398f45bd052b63616d7a45e29515bJeff Brown h1.rehash(10, 1.0f); 575e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4)); 576e735f23018b398f45bd052b63616d7a45e29515bJeff Brown ASSERT_NE(originalBuckets, getBuckets(h1)); 577e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(2U, h1.size()); 578e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(0U, h2.size()); 579e735f23018b398f45bd052b63616d7a45e29515bJeff Brown EXPECT_EQ(2U, h3.size()); 580e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} 581e735f23018b398f45bd052b63616d7a45e29515bJeff Brown 582e735f23018b398f45bd052b63616d7a45e29515bJeff Brown} // namespace android 583