Skip to content

Commit

Permalink
refactor: score dispatch
Browse files Browse the repository at this point in the history
  • Loading branch information
ii14 committed Apr 23, 2024
1 parent 8b64903 commit e4126ad
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 212 deletions.
58 changes: 1 addition & 57 deletions src/fzx/query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,63 +100,7 @@ Score Query::score(std::string_view s) const
continue;
switch (item.mType) {
case MatchType::kFuzzy:
switch (item.mText.size()) {
default:
sum += fzx::score(item.mText, s);
break;
case 1:
sum += fzx::score1(item.mText, s);
break;
#if defined(FZX_SSE2)
case 2:
case 3:
case 4:
sum += fzx::scoreSSE<4>(item.mText, s);
break;
case 5:
case 6:
case 7:
case 8:
sum += fzx::scoreSSE<8>(item.mText, s);
break;
case 9:
case 10:
case 11:
case 12:
sum += fzx::scoreSSE<12>(item.mText, s);
break;
case 13:
case 14:
case 15:
case 16:
sum += fzx::scoreSSE<16>(item.mText, s);
break;
#elif defined(FZX_NEON)
case 2:
case 3:
case 4:
sum += fzx::scoreNeon<4>(item.mText, s);
break;
case 5:
case 6:
case 7:
case 8:
sum += fzx::scoreNeon<8>(item.mText, s);
break;
case 9:
case 10:
case 11:
case 12:
sum += fzx::scoreNeon<12>(item.mText, s);
break;
case 13:
case 14:
case 15:
case 16:
sum += fzx::scoreNeon<16>(item.mText, s);
break;
#endif
}
sum += fzx::score(item.mText, s);
++div;
break;
case MatchType::kSubstr:
Expand Down
39 changes: 36 additions & 3 deletions src/fzx/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ void MatchStruct::matchRow(int row,

} // namespace

Score score(const String& needle, std::string_view haystack) noexcept
Score scoreNaive(const String& needle, std::string_view haystack) noexcept
{
if (needle.empty())
return kScoreMin;
Expand Down Expand Up @@ -189,6 +189,8 @@ Score score(const String& needle, std::string_view haystack) noexcept
return lastM[match.mHaystackLen - 1];
}

namespace {

Score score1(const String& needle, std::string_view haystack) noexcept
{
DEBUG_ASSERT(needle.size() == 1);
Expand Down Expand Up @@ -229,12 +231,10 @@ Score score1(const String& needle, std::string_view haystack) noexcept
}

#if defined(FZX_SSE2) || defined(FZX_NEON)
namespace {
alignas(32) constexpr Score kGapTable[7] {
kScoreGapInner, kScoreGapInner, kScoreGapTrailing, kScoreGapInner,
kScoreGapInner, kScoreGapInner, kScoreGapTrailing,
};
} // namespace
#endif

#if defined(FZX_SSE2)
Expand Down Expand Up @@ -596,6 +596,39 @@ template Score scoreNeon<16>(const String& needle, std::string_view haystack) no

#endif // defined(FZX_NEON)

} // namespace

Score score(const String& needle, std::string_view haystack) noexcept
{
switch (needle.size()) {
// clang-format off
case 1:
return score1(needle, haystack);
#if defined(FZX_SSE2)
case 2: case 3: case 4:
return scoreSSE<4>(needle, haystack);
case 5: case 6: case 7: case 8:
return scoreSSE<8>(needle, haystack);
case 9: case 10: case 11: case 12:
return scoreSSE<12>(needle, haystack);
case 13: case 14: case 15: case 16:
return scoreSSE<16>(needle, haystack);
#elif defined(FZX_NEON)
case 2: case 3: case 4:
return scoreNeon<4>(needle, haystack);
case 5: case 6: case 7: case 8:
return scoreNeon<8>(needle, haystack);
case 9: case 10: case 11: case 12:
return scoreNeon<12>(needle, haystack);
case 13: case 14: case 15: case 16:
return scoreNeon<16>(needle, haystack);
#endif
default:
return scoreNaive(needle, haystack);
// clang-format on
}
}

Score matchPositions(std::string_view needle,
std::string_view haystack,
std::vector<bool>* positions)
Expand Down
22 changes: 1 addition & 21 deletions src/fzx/score.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,28 +60,8 @@ static constexpr Score kScoreMatchDot = 120;
static constexpr Score kScoreMax = std::numeric_limits<Score>::infinity();
static constexpr Score kScoreMin = -std::numeric_limits<Score>::infinity();


Score scoreNaive(const String& needle, std::string_view haystack) noexcept;
Score score(const String& needle, std::string_view haystack) noexcept;
Score score1(const String& needle, std::string_view haystack) noexcept;

#if defined(FZX_SSE2)
template <size_t N>
Score scoreSSE(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreSSE<4>(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreSSE<8>(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreSSE<12>(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreSSE<16>(const String& needle, std::string_view haystack) noexcept;
#endif // defined(FZX_SSE2)

#if defined(FZX_NEON)
template <size_t N>
Score scoreNeon(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreNeon<4>(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreNeon<8>(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreNeon<12>(const String& needle, std::string_view haystack) noexcept;
extern template Score scoreNeon<16>(const String& needle, std::string_view haystack) noexcept;
#endif // defined(FZX_NEON)

Score matchPositions(std::string_view needle,
std::string_view haystack,
std::vector<bool>* positions);
Expand Down
181 changes: 50 additions & 131 deletions test/fzx/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,140 +224,59 @@ TEST_CASE("fzx::score", "[score]")
true,
});
}
}

#if defined(FZX_SSE2)
TEST_CASE("fzx::scoreSse", "[score]")
{
auto h = "/Lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit/"
"Maecenas/mollis/odio/semper/nunc/convallis/accumsan/"_s;

const std::vector<std::string_view> kTestCases {
"/"sv,
"//"sv,
"///"sv,
"////"sv,
"/////"sv,
"//////"sv,
"///////"sv,
"////////"sv,
"/////////"sv,
"//////////"sv,
"///////////"sv,
"////////////"sv,
"/////////////"sv,
"//////////////"sv,
"///////////////"sv,
"////////////////"sv,
"l"sv,
"li"sv,
"lid"sv,
"lids"sv,
"lidsa"sv,
"lidsac"sv,
"lidsaca"sv,
"lidsacae"sv,
"lidsacaem"sv,
"lidsacaemm"sv,
"lidsacaemmo"sv,
"lidsacaemmos"sv,
"lidsacaemmosn"sv,
"lidsacaemmosnc"sv,
"lidsacaemmosnca"sv,
"co"sv,
"con"sv,
"cons"sv,
"conse"sv,
"consec"sv,
"consect"sv,
"consecte"sv,
"consectet"sv,
"consectetu"sv,
"consectetur"sv,
};

for (auto t : kTestCases) {
CAPTURE(t);
fzx::String n { t };
if (!t.empty() && t.size() <= 4) {
CHECK(Approx(score(n, h)) == scoreSSE<4>(n, h));
} else if (t.size() >= 5 && t.size() <= 8) {
CHECK(Approx(score(n, h)) == scoreSSE<8>(n, h));
} else if (t.size() >= 9 && t.size() <= 12) {
CHECK(Approx(score(n, h)) == scoreSSE<12>(n, h));
} else if (t.size() >= 13 && t.size() <= 16) {
CHECK(Approx(score(n, h)) == scoreSSE<16>(n, h));
} else {
FAIL("invalid needle size");
}
}
}
#endif

#if defined(FZX_NEON)
TEST_CASE("fzx::scoreNeon", "[score]")
{
auto h = "/Lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit/"
"Maecenas/mollis/odio/semper/nunc/convallis/accumsan/"_s;
SECTION("simd") {
auto h = "/Lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit/"
"Maecenas/mollis/odio/semper/nunc/convallis/accumsan/"_s;

const std::vector<std::string_view> kTestCases {
"/"sv,
"//"sv,
"///"sv,
"////"sv,
"/////"sv,
"//////"sv,
"///////"sv,
"////////"sv,
"/////////"sv,
"//////////"sv,
"///////////"sv,
"////////////"sv,
"/////////////"sv,
"//////////////"sv,
"///////////////"sv,
"////////////////"sv,
"l"sv,
"li"sv,
"lid"sv,
"lids"sv,
"lidsa"sv,
"lidsac"sv,
"lidsaca"sv,
"lidsacae"sv,
"lidsacaem"sv,
"lidsacaemm"sv,
"lidsacaemmo"sv,
"lidsacaemmos"sv,
"lidsacaemmosn"sv,
"lidsacaemmosnc"sv,
"lidsacaemmosnca"sv,
"co"sv,
"con"sv,
"cons"sv,
"conse"sv,
"consec"sv,
"consect"sv,
"consecte"sv,
"consectet"sv,
"consectetu"sv,
"consectetur"sv,
};
const std::vector<std::string_view> kTestCases {
"/"sv,
"//"sv,
"///"sv,
"////"sv,
"/////"sv,
"//////"sv,
"///////"sv,
"////////"sv,
"/////////"sv,
"//////////"sv,
"///////////"sv,
"////////////"sv,
"/////////////"sv,
"//////////////"sv,
"///////////////"sv,
"////////////////"sv,
"l"sv,
"li"sv,
"lid"sv,
"lids"sv,
"lidsa"sv,
"lidsac"sv,
"lidsaca"sv,
"lidsacae"sv,
"lidsacaem"sv,
"lidsacaemm"sv,
"lidsacaemmo"sv,
"lidsacaemmos"sv,
"lidsacaemmosn"sv,
"lidsacaemmosnc"sv,
"lidsacaemmosnca"sv,
"co"sv,
"con"sv,
"cons"sv,
"conse"sv,
"consec"sv,
"consect"sv,
"consecte"sv,
"consectet"sv,
"consectetu"sv,
"consectetur"sv,
};

for (auto t : kTestCases) {
CAPTURE(t);
fzx::String n { t };
if (!t.empty() && t.size() <= 4) {
CHECK(Approx(score(n, h)) == scoreNeon<4>(n, h));
} else if (t.size() >= 5 && t.size() <= 8) {
CHECK(Approx(score(n, h)) == scoreNeon<8>(n, h));
} else if (t.size() >= 9 && t.size() <= 12) {
CHECK(Approx(score(n, h)) == scoreNeon<12>(n, h));
} else if (t.size() >= 13 && t.size() <= 16) {
CHECK(Approx(score(n, h)) == scoreNeon<16>(n, h));
} else {
FAIL("invalid needle size");
for (auto t : kTestCases) {
CAPTURE(t);
fzx::String n { t };
CHECK(Approx(scoreNaive(n, h)) == score(n, h));
}
}
}
#endif

0 comments on commit e4126ad

Please sign in to comment.