summaryrefslogtreecommitdiff
path: root/ext/pcre/php_pcre.c
diff options
context:
space:
mode:
authorAndrei Zmievski <andrei@php.net>2004-08-24 20:58:59 +0000
committerAndrei Zmievski <andrei@php.net>2004-08-24 20:58:59 +0000
commitf30355a7df3913916ce3708b6d181a455927d055 (patch)
tree62a48a88740fe3342c630961a3533000662fd39f /ext/pcre/php_pcre.c
parent87187da0662c5a669e1c64b7ce83781e26da83e7 (diff)
downloadphp-git-f30355a7df3913916ce3708b6d181a455927d055.tar.gz
MFB.
Diffstat (limited to 'ext/pcre/php_pcre.c')
-rw-r--r--ext/pcre/php_pcre.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index 52ceb6f727..86f1876752 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -108,6 +108,63 @@ static PHP_MSHUTDOWN_FUNCTION(pcre)
}
/* }}} */
+#define PCRE_CACHE_SIZE 4096
+
+/* {{{ static pcre_clean_cache */
+static void pcre_clean_cache()
+{
+ HashTable *ht = &PCRE_G(pcre_cache);
+ Bucket *p = NULL;
+ int clean_size = PCRE_CACHE_SIZE / 8;
+
+ HANDLE_BLOCK_INTERRUPTIONS();
+
+ do {
+ p = ht->pListHead;
+
+ if (ht->pDestructor) {
+ ht->pDestructor(p->pData);
+ }
+ if (!p->pDataPtr) {
+ pefree(p->pData, ht->persistent);
+ }
+
+ if (p->pLast) {
+ p->pLast->pNext = p->pNext;
+ } else {
+ uint nIndex;
+
+ nIndex = p->h & ht->nTableMask;
+ ht->arBuckets[nIndex] = p->pNext;
+ }
+ if (p->pNext) {
+ p->pNext->pLast = p->pLast;
+ } else {
+ /* Nothing to do as this list doesn't have a tail */
+ }
+
+ if (p->pListLast != NULL) {
+ p->pListLast->pListNext = p->pListNext;
+ } else {
+ /* Deleting the head of the list */
+ ht->pListHead = p->pListNext;
+ }
+ if (p->pListNext != NULL) {
+ p->pListNext->pListLast = p->pListLast;
+ } else {
+ ht->pListTail = p->pListLast;
+ }
+ if (ht->pInternalPointer == p) {
+ ht->pInternalPointer = p->pListNext;
+ }
+ pefree(p, ht->persistent);
+ ht->nNumOfElements--;
+ } while (ht->nNumOfElements > PCRE_CACHE_SIZE - clean_size);
+
+ HANDLE_UNBLOCK_INTERRUPTIONS();
+}
+/* }}} */
+
/* {{{ pcre_get_compiled_regex
*/
PHPAPI pcre* pcre_get_compiled_regex(char *regex, pcre_extra **extra, int *preg_options TSRMLS_DC)
@@ -290,6 +347,15 @@ PHPAPI pcre* pcre_get_compiled_regex_ex(char *regex, pcre_extra **extra, int *pr
efree(pattern);
+ /*
+ * If we reached cache limit, clean out the items from the head of the list;
+ * these are supposedly the oldest ones (but not necessarily the least used
+ * ones).
+ */
+ if (zend_hash_num_elements(&PCRE_G(pcre_cache)) == PCRE_CACHE_SIZE) {
+ pcre_clean_cache();
+ }
+
/* Store the compiled pattern and extra info in the cache. */
new_entry.re = re;
new_entry.extra = *extra;