MCPcopy Create free account
hub / github.com/apache/impala / JaroSimilarity

Method JaroSimilarity

be/src/exprs/string-functions-ir.cc:1639–1725  ·  view source on GitHub ↗

Based on https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance Implements Jaro similarity

Source from the content-addressed store, hash-verified

1637// Based on https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance
1638// Implements Jaro similarity
1639DoubleVal StringFunctions::JaroSimilarity(
1640 FunctionContext* ctx, const StringVal& s1, const StringVal& s2) {
1641
1642 int s1len = s1.len;
1643 int s2len = s2.len;
1644
1645 // error if either input exceeds 255 characters
1646 if (s1len > 255 || s2len > 255) {
1647 ctx->SetError("jaro argument exceeds maximum length of 255 characters");
1648 return DoubleVal(-1.0);
1649 }
1650
1651 // short cut cases:
1652 // - null strings
1653 // - zero length strings
1654 // - identical length and value strings
1655 if (s1.is_null || s2.is_null) return DoubleVal::null();
1656 if (s1len == 0 && s2len == 0) return DoubleVal(1.0);
1657 if (s1len == 0 || s2len == 0) return DoubleVal(0.0);
1658 if (s1len == s2len && memcmp(s1.ptr, s2.ptr, s1len) == 0) return DoubleVal(1.0);
1659
1660 // the window size to search for matches in the other string
1661 int max_range = std::max(0, std::max(s1len, s2len) / 2 - 1);
1662
1663 int* s1_matching = reinterpret_cast<int*>(ctx->Allocate(sizeof(int) * (s1len)));
1664 if (UNLIKELY(s1_matching == nullptr)) {
1665 DCHECK(!ctx->impl()->state()->GetQueryStatus().ok());
1666 return DoubleVal::null();
1667 }
1668
1669 int* s2_matching = reinterpret_cast<int*>(ctx->Allocate(sizeof(int) * (s2len)));
1670 if (UNLIKELY(s2_matching == nullptr)) {
1671 ctx->Free(reinterpret_cast<uint8_t*>(s1_matching));
1672 DCHECK(!ctx->impl()->state()->GetQueryStatus().ok());
1673 return DoubleVal::null();
1674 }
1675
1676 std::fill_n(s1_matching, s1len, -1);
1677 std::fill_n(s2_matching, s2len, -1);
1678
1679 // calculate matching characters
1680 int matching_characters = 0;
1681 for (int i = 0; i < s1len; i++) {
1682 // matching window
1683 int min_index = std::max(i - max_range, 0);
1684 int max_index = std::min(i + max_range + 1, s2len);
1685 if (min_index >= max_index) break;
1686
1687 for (int j = min_index; j < max_index; j++) {
1688 if (s2_matching[j] == -1 && s1.ptr[i] == s2.ptr[j]) {
1689 s1_matching[i] = i;
1690 s2_matching[j] = j;
1691 matching_characters++;
1692 break;
1693 }
1694 }
1695 }
1696

Callers

nothing calls this directly

Calls 10

DoubleValClass · 0.85
maxFunction · 0.85
minFunction · 0.85
implMethod · 0.80
SetErrorMethod · 0.45
AllocateMethod · 0.45
okMethod · 0.45
GetQueryStatusMethod · 0.45
stateMethod · 0.45
FreeMethod · 0.45

Tested by

no test coverage detected