monotone-commits-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Monotone-commits-diffs] net.venge.monotone.regex-cache: 3f8f0d347ad197a


From: code
Subject: [Monotone-commits-diffs] net.venge.monotone.regex-cache: 3f8f0d347ad197aafa02785464810636e5db07eb
Date: Sun, 30 Oct 2011 14:29:44 +0100 (CET)

revision:            3f8f0d347ad197aafa02785464810636e5db07eb
date:                2011-10-30T12:57:58
author:              Richard Hopkins <address@hidden>
branch:              net.venge.monotone.regex-cache
changelog:
Cache previously compiled regexs in pcrewrap.cc

The benefit of this is to improve the use of the ".mtn-ignore" file by
commands such as "mtn ls unknown".

The timings obtained via "time mtn ls unknown" are shown below when
run on a Dell Inspiron 1501 with 894 MB RAM, OpenSUSE 11.4. The workspace
was a normal checkout of "net.venge.monotone" after the standard
"./configure", "make" cycle and using the standard ".mtn-ignore" file as
part of the checkout.

Repeated execution obtains results consistent with those below showing the
cache improves execution time.

Normal monotone (no caching)

real: 0m0.365s
user: 0m0.312s
sys: 0m0.052s

With caching

real: 0m0.316s
user: 0m0.240s
sys: 0m0.072s

However, currently the cache will be leaked as I don't know where to call
the new function "free_compiled" which will free everything.

manifest:
format_version "1"

new_manifest [e6131c40497627c43895c678106acea89f48dc20]

old_revision [c954e1afd2121eff60933e93270d855a81d726ad]

patch "src/pcrewrap.cc"
 from [7f5bd4e7d8d9e02f2b0271fa9a0f64dcbce2467d]
   to [b50d03e955358a7d96e2babbe24ee59fb490649f]
============================================================
--- src/pcrewrap.cc	7f5bd4e7d8d9e02f2b0271fa9a0f64dcbce2467d
+++ src/pcrewrap.cc	b50d03e955358a7d96e2babbe24ee59fb490649f
@@ -11,6 +11,7 @@
 #include "pcrewrap.hh"
 #include "sanity.hh"
 #include <cstring>
+#include <map>
 #include <vector>
 
 // This dirty trick is necessary to prevent the 'pcre' typedef defined by
@@ -19,6 +20,9 @@
 #include "pcre.h"
 #undef pcre
 
+using std::make_pair;
+using std::map;
+using std::pair;
 using std::string;
 using std::vector;
 
@@ -69,11 +73,25 @@ namespace pcre
 
 namespace pcre
 {
+  typedef map<char const *,
+              pair<struct real_pcre const *, struct pcre_extra const *> >
+              regex_cache;
+  regex_cache compiled;
+
   void regex::init(char const * pattern, flags options)
   {
     int errcode;
     int erroff;
     char const * err;
+    // use the cached data if we have it
+    regex_cache::iterator iter = compiled.find(pattern);
+    if (iter != compiled.end())
+      {
+        basedat = iter->second.first;
+        extradat = iter->second.second;
+        return;
+      }
+    // not in cache - compile them then store in cache
     basedat = pcre_compile2(pattern, flags_to_internal(options),
                             &errcode, &err, &erroff, 0);
     if (!basedat)
@@ -97,6 +115,8 @@ namespace pcre
     ed->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
     ed->match_limit_recursion = 2000;
     extradat = ed;
+    // store in cache
+    compiled[pattern] = make_pair(basedat, extradat);
   }
 
   regex::regex(char const * pattern, origin::type whence, flags options)
@@ -113,12 +133,24 @@ namespace pcre
 
   regex::~regex()
   {
-    if (basedat)
-      pcre_free(const_cast<pcre_t *>(basedat));
-    if (extradat)
-      pcre_free(const_cast<pcre_extra *>(extradat));
   }
 
+  // currently not called from anywhere so the entries are leaked
+  void free_compiled()
+  {
+    for (regex_cache::iterator iter = compiled.begin();
+         iter != compiled.end();
+         ++iter)
+      {
+        if (iter->second.first)
+          pcre_free(const_cast<pcre_t *>(iter->second.first));
+
+        if (iter->second.second)
+          pcre_free(const_cast<pcre_extra *>(iter->second.second));
+      }
+      compiled.clear();
+  }
+
   bool
   regex::match(string const & subject, origin::type subject_origin,
                flags options) const

reply via email to

[Prev in Thread] Current Thread [Next in Thread]