MCPcopy Create free account
hub / github.com/pydata/numexpr / two_way_short_needle

Function two_way_short_needle

numexpr3/string_functions.hpp:225–305  ·  view source on GitHub ↗

Return the first location of non-empty NEEDLE within HAYSTACK, or NULL. HAYSTACK_LEN is the minimum known length of HAYSTACK. This method is optimized for NEEDLE_LEN < LONG_NEEDLE_THRESHOLD. Performance is guaranteed to be linear, with an initialization cost of 2 * NEEDLE_LEN comparisons. If AVAILABLE does not modify HAYSTACK_LEN (as in memmem), then at most 2 * HAYSTACK_LEN -

Source from the content-addressed store, hash-verified

223 If AVAILABLE modifies HAYSTACK_LEN (as in strstr), then at most 3 *
224 HAYSTACK_LEN - NEEDLE_LEN comparisons occur in searching. */
225static RETURN_TYPE
226two_way_short_needle (const unsigned char *haystack, size_t haystack_len,
227 const unsigned char *needle, size_t needle_len)
228{
229 size_t i; /* Index into current byte of NEEDLE. */
230 size_t j; /* Index into current window of HAYSTACK. */
231 size_t period; /* The period of the right half of needle. */
232 size_t suffix; /* The index of the right half of needle. */
233
234 /* Factor the needle into two halves, such that the left half is
235 smaller than the global period, and the right half is
236 periodic (with a period as large as NEEDLE_LEN - suffix). */
237 suffix = critical_factorization (needle, needle_len, &period);
238
239 /* Perform the search. Each iteration compares the right half
240 first. */
241 if (CMP_FUNC (needle, needle + period, suffix) == 0)
242 {
243 /* Entire needle is periodic; a mismatch can only advance by the
244 period, so use memory to avoid rescanning known occurrences
245 of the period. */
246 size_t memory = 0;
247 j = 0;
248 while (AVAILABLE (haystack, haystack_len, j, needle_len))
249 {
250 /* Scan for matches in right half. */
251 i = MAX (suffix, memory);
252 while (i < needle_len && (CANON_ELEMENT (needle[i])
253 == CANON_ELEMENT (haystack[i + j])))
254 ++i;
255 if (needle_len <= i)
256 {
257 /* Scan for matches in left half. */
258 i = suffix - 1;
259 while (memory < i + 1 && (CANON_ELEMENT (needle[i])
260 == CANON_ELEMENT (haystack[i + j])))
261 --i;
262 if (i + 1 < memory + 1)
263 return (RETURN_TYPE) (haystack + j);
264 /* No match, so remember how many repetitions of period
265 on the right half were scanned. */
266 j += period;
267 memory = needle_len - period;
268 }
269 else
270 {
271 j += i - suffix + 1;
272 memory = 0;
273 }
274 }
275 }
276 else
277 {
278 /* The two halves of needle are distinct; no extra memory is
279 required, and any mismatch results in a maximal shift. */
280 period = MAX (suffix, needle_len - suffix) + 1;
281 j = 0;
282 while (AVAILABLE (haystack, haystack_len, j, needle_len))

Callers 1

stringcontainsFunction · 0.85

Calls 1

critical_factorizationFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…