[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: memmem issues
From: |
Bruno Haible |
Subject: |
Re: memmem issues |
Date: |
Wed, 26 Dec 2007 16:15:08 +0100 |
User-agent: |
KMail/1.9.1 |
Eric Blake wrote:
> + Fix memmem to avoid O(n^2) worst-case complexity.
> + * lib/memmem.c (knuth_morris_pratt): New function.
> + (memmem): Use it if first few naive iterations fail.
While considering to submit a modified version of this code to glibc
for inclusion, I found it good to make the code adhere better to
GNU coding conventions:
- use lower cased local variable names,
- use tab indentation (my fault).
2007-12-23 Bruno Haible <address@hidden>
* lib/memmem.c (memmem): Use lowercase variable names. Tab
indentation.
*** lib/memmem.c.orig 2007-12-23 21:31:31.000000000 +0100
--- lib/memmem.c 2007-12-23 21:31:03.000000000 +0100
***************
*** 154,167 ****
if NEEDLE_LEN is 0, otherwise NULL if NEEDLE is not found in
HAYSTACK. */
void *
! memmem (const void *haystack, size_t haystack_len,
! const void *needle, size_t needle_len)
{
/* Operating with void * is awkward. */
! const char *Haystack = (const char *) haystack;
! const char *Needle = (const char *) needle;
! const char *last_haystack = Haystack + haystack_len;
! const char *last_needle = Needle + needle_len;
if (needle_len == 0)
/* The first occurrence of the empty string is deemed to occur at
--- 154,167 ----
if NEEDLE_LEN is 0, otherwise NULL if NEEDLE is not found in
HAYSTACK. */
void *
! memmem (const void *haystack_start, size_t haystack_len,
! const void *needle_start, size_t needle_len)
{
/* Operating with void * is awkward. */
! const char *haystack = (const char *) haystack_start;
! const char *needle = (const char *) needle_start;
! const char *last_haystack = haystack + haystack_len;
! const char *last_needle = needle + needle_len;
if (needle_len == 0)
/* The first occurrence of the empty string is deemed to occur at
***************
*** 175,181 ****
/* Use optimizations in memchr when possible. */
if (__builtin_expect (needle_len == 1, 0))
! return memchr (haystack, (unsigned char) *Needle, haystack_len);
/* Minimizing the worst-case complexity:
Let n = haystack_len, m = needle_len.
--- 175,181 ----
/* Use optimizations in memchr when possible. */
if (__builtin_expect (needle_len == 1, 0))
! return memchr (haystack, (unsigned char) *needle, haystack_len);
/* Minimizing the worst-case complexity:
Let n = haystack_len, m = needle_len.
***************
*** 198,252 ****
/* Speed up the following searches of needle by caching its first
byte. */
! char b = *Needle++;
! for (;; Haystack++)
{
! if (Haystack == last_haystack)
! /* No match. */
! return NULL;
!
! /* See whether it's advisable to use an asymptotically faster
! algorithm. */
! if (try_kmp
! && outer_loop_count >= 10
! && comparison_count >= 5 * outer_loop_count)
! {
! /* See if needle + comparison_count now reaches the end of
! needle. */
! if (comparison_count >= needle_len)
! {
! /* Try the Knuth-Morris-Pratt algorithm. */
! const char *result;
! if (knuth_morris_pratt (Haystack, last_haystack,
! Needle - 1, needle_len, &result))
! return (void *) result;
! try_kmp = false;
! }
! }
!
! outer_loop_count++;
! comparison_count++;
! if (*Haystack == b)
! /* The first byte matches. */
! {
! const char *rhaystack = Haystack + 1;
! const char *rneedle = Needle;
!
! for (;; rhaystack++, rneedle++)
! {
! if (rneedle == last_needle)
! /* Found a match. */
! return (void *) Haystack;
! if (rhaystack == last_haystack)
! /* No match. */
! return NULL;
! comparison_count++;
! if (*rhaystack != *rneedle)
! /* Nothing in this round. */
! break;
! }
! }
}
}
--- 198,252 ----
/* Speed up the following searches of needle by caching its first
byte. */
! char b = *needle++;
! for (;; haystack++)
{
! if (haystack == last_haystack)
! /* No match. */
! return NULL;
!
! /* See whether it's advisable to use an asymptotically faster
! algorithm. */
! if (try_kmp
! && outer_loop_count >= 10
! && comparison_count >= 5 * outer_loop_count)
! {
! /* See if needle + comparison_count now reaches the end of
! needle. */
! if (comparison_count >= needle_len)
! {
! /* Try the Knuth-Morris-Pratt algorithm. */
! const char *result;
! if (knuth_morris_pratt (haystack, last_haystack,
! needle - 1, needle_len, &result))
! return (void *) result;
! try_kmp = false;
! }
! }
!
! outer_loop_count++;
! comparison_count++;
! if (*haystack == b)
! /* The first byte matches. */
! {
! const char *rhaystack = haystack + 1;
! const char *rneedle = needle;
!
! for (;; rhaystack++, rneedle++)
! {
! if (rneedle == last_needle)
! /* Found a match. */
! return (void *) haystack;
! if (rhaystack == last_haystack)
! /* No match. */
! return NULL;
! comparison_count++;
! if (*rhaystack != *rneedle)
! /* Nothing in this round. */
! break;
! }
! }
}
}
Re: memmem issues, Bruno Haible, 2007/12/26
Re: memmem issues,
Bruno Haible <=
Re: memmem issues, Bruno Haible, 2007/12/21