applied significant recursion complexity optimization, based on a patch

Tue Sep 20 13:16:04 2005  Tim Janik  <timj@imendio.com>

        * glib/gpattern.c (g_pattern_ph_match): applied significant recursion
        complexity optimization, based on a patch from Matthias Clasen.

        * tests/patterntest.c: more tests, mostly from matthias.
This commit is contained in:
Tim Janik 2005-09-20 11:20:23 +00:00 committed by Tim Janik
parent 3fef89349b
commit 744a4397ff
5 changed files with 53 additions and 7 deletions

View File

@ -1,3 +1,10 @@
Tue Sep 20 13:16:04 2005 Tim Janik <timj@imendio.com>
* glib/gpattern.c (g_pattern_ph_match): applied significant recursion
complexity optimization, based on a patch from Matthias Clasen.
* tests/patterntest.c: more tests, mostly from matthias.
2005-09-20 Matthias Clasen <mclasen@redhat.com> 2005-09-20 Matthias Clasen <mclasen@redhat.com>
* glib/gqueue.c (g_queue_insert_sorted): Correct the docs. * glib/gqueue.c (g_queue_insert_sorted): Correct the docs.

View File

@ -1,3 +1,10 @@
Tue Sep 20 13:16:04 2005 Tim Janik <timj@imendio.com>
* glib/gpattern.c (g_pattern_ph_match): applied significant recursion
complexity optimization, based on a patch from Matthias Clasen.
* tests/patterntest.c: more tests, mostly from matthias.
2005-09-20 Matthias Clasen <mclasen@redhat.com> 2005-09-20 Matthias Clasen <mclasen@redhat.com>
* glib/gqueue.c (g_queue_insert_sorted): Correct the docs. * glib/gqueue.c (g_queue_insert_sorted): Correct the docs.

View File

@ -1,3 +1,10 @@
Tue Sep 20 13:16:04 2005 Tim Janik <timj@imendio.com>
* glib/gpattern.c (g_pattern_ph_match): applied significant recursion
complexity optimization, based on a patch from Matthias Clasen.
* tests/patterntest.c: more tests, mostly from matthias.
2005-09-20 Matthias Clasen <mclasen@redhat.com> 2005-09-20 Matthias Clasen <mclasen@redhat.com>
* glib/gqueue.c (g_queue_insert_sorted): Correct the docs. * glib/gqueue.c (g_queue_insert_sorted): Correct the docs.

View File

@ -52,10 +52,10 @@ struct _GPatternSpec
/* --- functions --- */ /* --- functions --- */
static inline gboolean static inline gboolean
g_pattern_ph_match (const gchar *match_pattern, g_pattern_ph_match (const gchar *match_pattern,
const gchar *match_string) const gchar *match_string,
gboolean *wildcard_reached_p)
{ {
register const gchar *pattern, *string; register const gchar *pattern, *string;
register gchar ch; register gchar ch;
@ -76,6 +76,7 @@ g_pattern_ph_match (const gchar *match_pattern,
break; break;
case '*': case '*':
*wildcard_reached_p = TRUE;
do do
{ {
ch = *pattern; ch = *pattern;
@ -92,6 +93,7 @@ g_pattern_ph_match (const gchar *match_pattern,
return TRUE; return TRUE;
do do
{ {
gboolean next_wildcard_reached = FALSE;
while (ch != *string) while (ch != *string)
{ {
if (!*string) if (!*string)
@ -99,8 +101,16 @@ g_pattern_ph_match (const gchar *match_pattern,
string = g_utf8_next_char (string); string = g_utf8_next_char (string);
} }
string++; string++;
if (g_pattern_ph_match (pattern, string)) if (g_pattern_ph_match (pattern, string, &next_wildcard_reached))
return TRUE; return TRUE;
if (next_wildcard_reached)
/* the forthcoming pattern substring up to the next wildcard has
* been matched, but a mismatch occoured for the rest of the
* pattern, following the next wildcard.
* there's no need to advance the current match position any
* further if the rest pattern will not match.
*/
return FALSE;
} }
while (*string); while (*string);
break; break;
@ -135,17 +145,18 @@ g_pattern_match (GPatternSpec *pspec,
switch (pspec->match_type) switch (pspec->match_type)
{ {
gboolean dummy;
case G_MATCH_ALL: case G_MATCH_ALL:
return g_pattern_ph_match (pspec->pattern, string); return g_pattern_ph_match (pspec->pattern, string, &dummy);
case G_MATCH_ALL_TAIL: case G_MATCH_ALL_TAIL:
if (string_reversed) if (string_reversed)
return g_pattern_ph_match (pspec->pattern, string_reversed); return g_pattern_ph_match (pspec->pattern, string_reversed, &dummy);
else else
{ {
gboolean result; gboolean result;
gchar *tmp; gchar *tmp;
tmp = g_utf8_strreverse (string, string_length); tmp = g_utf8_strreverse (string, string_length);
result = g_pattern_ph_match (pspec->pattern, tmp); result = g_pattern_ph_match (pspec->pattern, tmp, &dummy);
g_free (tmp); g_free (tmp);
return result; return result;
} }

View File

@ -281,7 +281,21 @@ main (int argc, char** argv)
TEST_MATCH("*fo1*bar", "yyyfoxfo1bar", TRUE); TEST_MATCH("*fo1*bar", "yyyfoxfo1bar", TRUE);
TEST_MATCH("12*fo1g*bar", "12yyyfoxfo1gbar", TRUE); TEST_MATCH("12*fo1g*bar", "12yyyfoxfo1gbar", TRUE);
TEST_MATCH("__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE); TEST_MATCH("__________:*fo1g*bar", "__________:yyyfoxfo1gbar", TRUE);
TEST_MATCH("*abc*cde", "abcde", FALSE);
TEST_MATCH("*abc*cde", "abccde", TRUE);
TEST_MATCH("*abc*cde", "abcxcde", TRUE);
TEST_MATCH("*abc*?cde", "abccde", FALSE);
TEST_MATCH("*abc*?cde", "abcxcde", TRUE);
TEST_MATCH("*abc*def", "abababcdededef", TRUE);
TEST_MATCH("*abc*def", "abcbcbcdededef", TRUE);
TEST_MATCH("*acbc*def", "acbcbcbcdededef", TRUE);
TEST_MATCH("*a?bc*def", "acbcbcbcdededef", TRUE);
TEST_MATCH("*abc*def", "bcbcbcdefdef", FALSE);
TEST_MATCH("*abc*def*ghi", "abcbcbcbcbcbcdefefdefdefghi", TRUE);
TEST_MATCH("*abc*def*ghi", "bcbcbcbcbcbcdefdefdefdefghi", FALSE);
TEST_MATCH("_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_*abc*def*ghi", "_1_2_3_4_5_6_7_8_9_0_1_2_3_4_5_abcbcbcbcbcbcdefefdefdefghi", TRUE);
TEST_MATCH("fooooooo*a*bc", "fooooooo_a_bd_a_bc", TRUE);
verbose ("\n%u tests passed, %u failed\n", passed, failed); verbose ("\n%u tests passed, %u failed\n", passed, failed);
return failed; return failed;