#include "gn/string_atom.h"
#include "util/test/test.h"
#include <algorithm>
#include <array>
#include <set>
#include <string>
#include <vector>
TEST(StringAtomTest, EmptyString) {
StringAtom key1;
StringAtom key2("");
ASSERT_STREQ(key1.str().c_str(), "");
ASSERT_STREQ(key2.str().c_str(), "");
ASSERT_EQ(&key1.str(), &key2.str());
}
TEST(StringAtomTest, Find) {
StringAtom empty;
EXPECT_EQ(empty.str(), std::string());
StringAtom foo("foo");
EXPECT_EQ(foo.str(), std::string("foo"));
StringAtom foo2("foo");
EXPECT_EQ(&foo.str(), &foo2.str());
}
TEST(StringAtomTest, DefaultCompare) {
auto foo = StringAtom("foo");
auto bar = StringAtom("bar");
auto zoo = StringAtom("zoo");
EXPECT_TRUE(bar < foo);
EXPECT_TRUE(foo < zoo);
EXPECT_TRUE(bar < zoo);
}
TEST(StringAtomTest, NormalSet) {
std::set<StringAtom> set;
auto foo_ret = set.insert(std::string_view("foo"));
auto bar_ret = set.insert(std::string_view("bar"));
auto zoo_ret = set.insert(std::string_view("zoo"));
StringAtom foo_key("foo");
EXPECT_EQ(*foo_ret.first, foo_key);
auto foo_it = set.find(foo_key);
EXPECT_NE(foo_it, set.end());
EXPECT_EQ(*foo_it, foo_key);
EXPECT_EQ(set.find(std::string_view("bar")), bar_ret.first);
EXPECT_EQ(set.find(std::string_view("zoo")), zoo_ret.first);
auto it = set.begin();
EXPECT_EQ(it, bar_ret.first);
++it;
EXPECT_EQ(it, foo_ret.first);
++it;
EXPECT_EQ(it, zoo_ret.first);
++it;
EXPECT_EQ(it, set.end());
}
TEST(StringAtomTest, FastSet) {
std::set<StringAtom, StringAtom::PtrCompare> set;
auto foo_ret = set.insert(std::string_view("foo"));
auto bar_ret = set.insert(std::string_view("bar"));
auto zoo_ret = set.insert(std::string_view("zoo"));
auto atom_to_ptr = [](const StringAtom& atom) -> const std::string* {
return &atom.str();
};
EXPECT_TRUE(foo_ret.second);
EXPECT_TRUE(bar_ret.second);
EXPECT_TRUE(zoo_ret.second);
const std::string* foo_ptr = atom_to_ptr(*foo_ret.first);
const std::string* bar_ptr = atom_to_ptr(*bar_ret.first);
const std::string* zoo_ptr = atom_to_ptr(*zoo_ret.first);
StringAtom foo_key("foo");
EXPECT_EQ(foo_ptr, atom_to_ptr(foo_key));
auto foo_it = set.find(foo_key);
EXPECT_NE(foo_it, set.end());
EXPECT_EQ(*foo_it, foo_key);
EXPECT_EQ(set.find(std::string_view("bar")), bar_ret.first);
EXPECT_EQ(set.find(std::string_view("zoo")), zoo_ret.first);
std::array<const std::string*, 3> ptrs = {
foo_ptr,
bar_ptr,
zoo_ptr,
};
std::sort(ptrs.begin(), ptrs.end());
auto it = set.begin();
EXPECT_EQ(atom_to_ptr(*it), ptrs[0]);
++it;
EXPECT_EQ(atom_to_ptr(*it), ptrs[1]);
++it;
EXPECT_EQ(atom_to_ptr(*it), ptrs[2]);
++it;
EXPECT_EQ(it, set.end());
}
TEST(StringAtom, AllocMoreThanASingleSlabOfKeys) {
const size_t kMaxCount = 16384;
std::vector<StringAtom> keys;
auto string_for = [](size_t index) -> std::string {
return std::to_string(index) + "_key";
};
for (size_t nn = 0; nn < kMaxCount; ++nn) {
keys.push_back(StringAtom(string_for(nn)));
}
for (size_t nn = 0; nn < kMaxCount; ++nn) {
ASSERT_EQ(keys[nn].str(), string_for(nn));
}
}