Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Tighter comments
  • Loading branch information
sweeneyde committed Jul 9, 2021
commit 3b8760f8d1b07f94e2c6f0bad1d1587a5259c112
30 changes: 11 additions & 19 deletions Objects/stringlib/fastsearch.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
// See http://www-igm.univ-mlv.fr/~lecroq/string/node26.html#SECTION00260
const Py_ssize_t len_needle = p->len_needle;
const Py_ssize_t cut = p->cut;
const Py_ssize_t period = p->period;
Py_ssize_t period = p->period;
const STRINGLIB_CHAR *const needle = p->needle;
const STRINGLIB_CHAR *window_last = haystack + len_needle - 1;
const STRINGLIB_CHAR *const haystack_end = haystack + len_haystack;
Expand All @@ -387,9 +387,8 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
memory = 0;
shift = table[(*window_last) & TABLE_MASK];
}
// In most cases, this "Horspool" loop is the hot loop.
while (shift > 0 && window_last < haystack_end) {
LOG("Fast Horspool skip.\n");
LOG("Horspool skip.\n");
window_last += shift;
shift = table[(*window_last) & TABLE_MASK];
LOG_LINEUP();
Expand All @@ -401,39 +400,36 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
Py_ssize_t i = Py_MAX(cut, memory);
for (; i < len_needle; i++) {
if (needle[i] != window[i]) {
LOG("Right half does not match. Jump ahead by %zd.\n",
i - cut + 1);
LOG("Right half does not match.\n");
window_last += i - cut + 1;
memory = 0;
goto periodicwindowloop;
}
}
for (i = memory; i < cut; i++) {
if (needle[i] != window[i]) {
LOG("Left half does not match. Jump ahead by period %zd.\n",
period);
LOG("Left half does not match.\n");
window_last += period;
memory = len_needle - period;
goto periodicwindowloop;
}
}
LOG("Left half matches. Returning %zd.\n",
window - haystack);
LOG("Found a match!\n");
return window - haystack;
}
}
else {
Py_ssize_t gap = p->gap;
period = Py_MAX(gap, period);
LOG("Needle is not periodic.\n");
assert(cut < len_needle);
STRINGLIB_CHAR needle_cut = needle[cut];
windowloop:
while (window_last < haystack_end) {
LOG_LINEUP();
Py_ssize_t shift = table[(*window_last) & TABLE_MASK];
// In most cases, this "Horspool" loop is the hot loop.
while (shift > 0 && window_last < haystack_end) {
LOG("Fast Horspool skip.\n");
LOG("Horspool skip.\n");
window_last += shift;
shift = table[(*window_last) & TABLE_MASK];
LOG_LINEUP();
Expand All @@ -445,23 +441,19 @@ STRINGLIB(_two_way)(const STRINGLIB_CHAR *haystack, Py_ssize_t len_haystack,
for (Py_ssize_t i = cut; i < len_needle; i++) {
if (needle[i] != window[i]) {
Py_ssize_t two_way_shift = i - cut + 1;
LOG("Right half does not match. two-way: %zd, gap: %zd "
"--> Advance by %zd\n",
two_way_shift, gap, Py_MAX(two_way_shift, gap));
LOG("Right half does not match.\n");
window_last += Py_MAX(two_way_shift, gap);
goto windowloop;
}
}
for (Py_ssize_t i = 0; i < cut; i++) {
if (needle[i] != window[i]) {
LOG("Left half does not match. period: %zd, gap: %zd)"
"--> Advance by %zd\n",
period, gap, Py_MAX(period, gap));
window_last += Py_MAX(period, gap);
LOG("Left half does not match.\n");
window_last += period;
goto windowloop;
}
}
LOG("Left half matches. Returning %zd.\n", window - haystack);
LOG("Found a match!\n");
return window - haystack;
}
}
Expand Down