Skip to content

Commit

Permalink
Improve the interface of SortKey (#555)
Browse files Browse the repository at this point in the history
Add consistent comparison and `starts_with` to get rid of a lot of `.get()` calls.
  • Loading branch information
joka921 committed Jan 27, 2022
1 parent 1c979a8 commit de55d92
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v2

- name: Install dependencies
run: sudo apt-get install -y libicu-dev tzdata gcc-10 libzstd-dev libjemalloc-dev
run: sudo apt update && sudo apt-get install -y libicu-dev tzdata gcc-10 libzstd-dev libjemalloc-dev
- name: Install boost
run : sudo add-apt-repository -y ppa:mhier/libboost-latest && sudo apt update && sudo apt install -y libboost1.74-dev
- name: Install gcc 11
Expand Down
31 changes: 24 additions & 7 deletions src/index/StringSortComparator.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,37 @@ class LocaleManager {
* Wraps a string that contains unicode collation weights for another string
* Only needed for making interfaces explicit and less errorProne
*/
// TODO<GCC12> As soon as we have constexpr std::string, this class can
// become constexpr.
class SortKey {
public:
SortKey() = default;
explicit SortKey(std::string_view contents) : _content(contents) {}
[[nodiscard]] const std::string& get() const { return _content; }
std::string& get() { return _content; }
explicit SortKey(std::string_view sortKey) : _sortKey(sortKey) {}
[[nodiscard]] constexpr const std::string& get() const noexcept {
return _sortKey;
}
constexpr std::string& get() noexcept { return _sortKey; }

// compare according to the byte value
[[nodiscard]] int compare(const SortKey& rhs) const {
return _content.compare(rhs._content);
// Comparison of sort key is done lexicographically on the byte values
// of member `_sortKey`
[[nodiscard]] int compare(const SortKey& rhs) const noexcept {
return _sortKey.compare(rhs._sortKey);
}

auto operator<=>(const SortKey&) const = default;
bool operator==(const SortKey&) const = default;

/// Is this sort key a prefix of another sort key. Note: This does not imply
/// any guarantees on the relation of the underlying strings.
bool starts_with(const SortKey& rhs) const noexcept {
return get().starts_with(rhs.get());
}

/// Return the number of bytes in the `SortKey`
std::string::size_type size() const noexcept { return get().size(); }

private:
std::string _content;
std::string _sortKey;
};

/// Copy constructor
Expand Down
10 changes: 7 additions & 3 deletions test/StringSortComparatorTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,15 @@ TEST(LocaleManager, PrefixSortKey) {
// The words vivæ and vivae compare equal on the primary level, but they
// get different prefixSortKeys for prefix length 4, because "ae" are two
// codepoints, whereas "æ" is one.
auto a = locIgnorePunct.getPrefixSortKey("vivæ", 4).second.get();
auto b = locIgnorePunct.getPrefixSortKey("vivae", 4).second.get();
auto a = locIgnorePunct.getPrefixSortKey("vivæ", 4).second;
auto b = locIgnorePunct.getPrefixSortKey("vivae", 4).second;

ASSERT_GT(a.size(), b.size());
ASSERT_TRUE(ad_utility::startsWith(a, b));
ASSERT_TRUE(a.starts_with(b));
// Also test the defaulted consistent comparison.
ASSERT_GT(a, b);
ASSERT_EQ(a, a);
ASSERT_NE(a, b);
ASSERT_FALSE(comp("vivæ", "vivae", LocaleManager::Level::PRIMARY));
ASSERT_FALSE(comp("vivæ", "vivae", LocaleManager::Level::PRIMARY));
}

0 comments on commit de55d92

Please sign in to comment.