8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.39 2002/06/11 15:41:37 thomas Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.40 2002/06/15 02:49:47 thomas Exp $
12
12
*
13
13
*Alistair Crooks added the code for the regex caching
14
14
*agc - cached the regular expressions used - there's a good chance
@@ -53,7 +53,7 @@ struct cached_re_str
53
53
static int rec = 0 ;/* # of cached re's */
54
54
static struct cached_re_str rev [MAX_CACHED_RES ];/* cached re's */
55
55
static unsigned long lru ;/* system lru tag */
56
- static int pg_lastre = 0 ;
56
+ static int pg_lastrec = 0 ;
57
57
58
58
/* attempt to compile `re' as an re, then match it against text */
59
59
/* cflags - flag to regcomp indicates case sensitivity */
@@ -70,43 +70,46 @@ RE_compile_and_execute(text *text_re, char *text, int cflags,
70
70
re = DatumGetCString (DirectFunctionCall1 (textout ,
71
71
PointerGetDatum (text_re )));
72
72
73
- if ((i = pg_lastre )< rec )
73
+ /* Find a previously compiled regular expression.
74
+ * Run the cache as a ring buffer, starting the search
75
+ * from the previous match if any.
76
+ */
77
+ i = pg_lastrec ;
78
+ while (i < rec )
74
79
{
75
- if (rev [i ].cre_s )
80
+ if (rev [i ].cre_s != NULL )
76
81
{
77
82
if (strcmp (rev [i ].cre_s ,re )== 0 &&
78
83
rev [i ].cre_type == cflags )
79
84
{
85
+ pg_lastrec = i ;
80
86
rev [i ].cre_lru = ++ lru ;
81
87
pfree (re );
82
88
return (pg_regexec (& rev [i ].cre_re ,
83
89
text ,nmatch ,
84
90
pmatch ,0 )== 0 );
85
91
}
86
92
}
87
- }
88
-
89
- /* find a previously compiled regular expression */
90
- for (i = 0 ;i < rec ;i ++ )
91
- {
92
- if (i == pg_lastre )continue ;
93
+ i ++ ;
93
94
94
- if (rev [i ].cre_s )
95
+ /* If we were not at the first slot to start,
96
+ * then think about wrapping if necessary.
97
+ */
98
+ if (pg_lastrec != 0 )
95
99
{
96
- if (strcmp (rev [i ].cre_s ,re )== 0 &&
97
- rev [i ].cre_type == cflags )
100
+ if (i >=rec )
98
101
{
99
- rev [ i ]. cre_lru = ++ lru ;
100
- pfree ( re );
101
- return ( pg_regexec ( & rev [ i ]. cre_re ,
102
- text , nmatch ,
103
- pmatch , 0 ) == 0 ) ;
102
+ i = 0 ;
103
+ }
104
+ else if ( i == pg_lastrec )
105
+ {
106
+ break ;
104
107
}
105
108
}
106
109
}
107
110
108
111
/* we didn't find it - make room in the cache for it */
109
- if (rec = =MAX_CACHED_RES )
112
+ if (rec > =MAX_CACHED_RES )
110
113
{
111
114
/* cache is full - find the oldest entry */
112
115
for (oldest = 0 ,i = 1 ;i < rec ;i ++ )
@@ -116,13 +119,16 @@ RE_compile_and_execute(text *text_re, char *text, int cflags,
116
119
}
117
120
}
118
121
else
122
+ {
119
123
oldest = rec ++ ;
124
+ }
120
125
121
126
/* if there was an old re, then de-allocate the space it used */
122
127
if (rev [oldest ].cre_s != (char * )NULL )
123
128
{
124
129
for (lru = i = 0 ;i < rec ;i ++ )
125
130
{
131
+ /* downweight all of the other cached entries */
126
132
rev [i ].cre_lru = (rev [i ].cre_lru - rev [oldest ].cre_lru ) /2 ;
127
133
if (rev [i ].cre_lru > lru )
128
134
lru = rev [i ].cre_lru ;
@@ -141,6 +147,7 @@ RE_compile_and_execute(text *text_re, char *text, int cflags,
141
147
regcomp_result = pg_regcomp (& rev [oldest ].cre_re ,re ,cflags );
142
148
if (regcomp_result == 0 )
143
149
{
150
+ pg_lastrec = oldest ;
144
151
/*
145
152
* use malloc/free for the cre_s field because the storage has to
146
153
* persist across transactions
@@ -311,7 +318,6 @@ textregexsubstr(PG_FUNCTION_ARGS)
311
318
{
312
319
text * s = PG_GETARG_TEXT_P (0 );
313
320
text * p = PG_GETARG_TEXT_P (1 );
314
- text * result ;
315
321
char * sterm ;
316
322
int len ;
317
323
bool match ;
@@ -339,16 +345,6 @@ textregexsubstr(PG_FUNCTION_ARGS)
339
345
Int32GetDatum (pmatch .rm_so + 1 ),
340
346
Int32GetDatum (pmatch .rm_eo - pmatch .rm_so )));
341
347
}
342
- #if 0
343
- /* otherwise, return a zero-length string */
344
- else
345
- {
346
- result = palloc (VARHDRSZ );
347
- VARATT_SIZEP (result )= VARHDRSZ ;
348
- PG_RETURN_TEXT_P (result );
349
- }
350
- #endif
351
348
352
- /* not reached */
353
349
PG_RETURN_NULL ();
354
350
}