changeset 1478:797c7b58a735

maps: add a config option to tweak sqlite Sqlite is highly configurable by PRAGMA statements [1]. This patch adds a config option to give the user changes to tweak them. [1]: https://www.sqlite.org/pragma.html
author Jun Wu <quark@fb.com>
date Thu, 23 Jun 2016 20:03:30 +0100
parents a4f77acf7051
children 9a6bb3657861
files hgsubversion/help/subversion.rst hgsubversion/maps.py hgsubversion/svnmeta.py
diffstat 3 files changed, 24 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/hgsubversion/help/subversion.rst
+++ b/hgsubversion/help/subversion.rst
@@ -362,6 +362,15 @@ settings:
     If it is set to an implementation different from what the repo is using,
     a migration will run automatically when the revision map is accessed.
 
+  ``hgsubversion.sqlitepragmas``
+
+    A list of sqlite PRAGMA statements to tweak sqlite. Each item should be
+    in the format ``key=value`` without ``PRAGMA``, or spaces, or quotation
+    marks. Refer to https://www.sqlite.org/pragma.html for possible options.
+
+    For example, setting it to ``synchronous=0, journal_mode=memory`` will
+    give you better performance at the cost of possible database corruption.
+
   ``hgsubversion.stupid``
     Setting this boolean option to true will force using a slower method for
     pulling revisions from Subversion. This method is compatible with servers
--- a/hgsubversion/maps.py
+++ b/hgsubversion/maps.py
@@ -558,7 +558,7 @@ class SqliteRevMap(collections.MutableMa
     rowcount = util.fileproperty('_rowcount', lambda x: x._rowcountpath,
                                  default=0, deserializer=int)
 
-    def __init__(self, revmap_path, lastpulled_path):
+    def __init__(self, revmap_path, lastpulled_path, sqlitepragmas=None):
         self._filepath = revmap_path
         self._dbpath = revmap_path + '.db'
         self._rowcountpath = self._dbpath + '.rowcount'
@@ -566,6 +566,7 @@ class SqliteRevMap(collections.MutableMa
 
         self._db = None
         self._hashes = None
+        self._sqlitepragmas = sqlitepragmas
         self.firstpulled = 0
         self._updatefirstlastpulled()
         # __iter__ is expensive and thus disabled by default
@@ -720,6 +721,12 @@ class SqliteRevMap(collections.MutableMa
                 cachesize += os.stat(path).st_size * ratio // 1000
         self._db.execute('PRAGMA cache_size=%d' % (-cachesize))
 
+        # PRAGMA statements provided by the user
+        for pragma in (self._sqlitepragmas or []):
+            # drop malicious ones
+            if re.match(r'\A\w+=\w+\Z', pragma):
+                self._db.execute('PRAGMA %s' % pragma)
+
         # disable auto-commit. everything is inside a transaction
         self._db.isolation_level = 'DEFERRED'
 
--- a/hgsubversion/svnmeta.py
+++ b/hgsubversion/svnmeta.py
@@ -345,8 +345,14 @@ class SVNMeta(object):
     @property
     def revmap(self):
         if self._revmap is None:
+            lastpulled_path = os.path.join(self.metapath, 'lastpulled')
+            opts = {}
+            if self.revmapclass is maps.SqliteRevMap:
+                # sqlite revmap takes an optional option: sqlitepragmas
+                opts['sqlitepragmas'] = self.ui.configlist(
+                    'hgsubversion', 'sqlitepragmas')
             self._revmap = self.revmapclass(
-                self.revmap_file, os.path.join(self.metapath, 'lastpulled'))
+                self.revmap_file, lastpulled_path, **opts)
         return self._revmap
 
     @property