[py-svn] r8032 - py/dist/py/path/svn

hpk at codespeak.net hpk at codespeak.net
Sun Jan 2 12:35:29 CET 2005


Author: hpk
Date: Sun Jan  2 12:35:29 2005
New Revision: 8032

Modified:
   py/dist/py/path/svn/svncommon.py
   py/dist/py/path/svn/urlcommand.py
Log:
- introduce a cache for reading svn listdir entries. 
  there are two caches, one AgingCache for rev==None 
  and one BuildcostAccess cache for rev != None. 
  The latter has no consistency problems while 
  the former cannot account for changes made 
  in other processes (it does invalidate the 
  cache on mkdir/remove/copy invocations, though) 

- get rid of other uncleaner caching in the checkers. 



Modified: py/dist/py/path/svn/svncommon.py
==============================================================================
--- py/dist/py/path/svn/svncommon.py	(original)
+++ py/dist/py/path/svn/svncommon.py	Sun Jan  2 12:35:29 2005
@@ -210,16 +210,9 @@
     #    return rev
 
     class Checkers(common.FSCheckers):
-        def _info(self):
-            try:
-                return self._infocache
-            except AttributeError:
-                self._infocache = self.path.info()
-                return self._infocache
-
         def dir(self):
             try:
-                return self._info().kind == 'dir'
+                return self.path.info().kind == 'dir'
             except IOError:
                 return self._listdirworks()
 
@@ -233,13 +226,13 @@
 
         def file(self):
             try:
-                return self._info().kind == 'file'
+                return self.path.info().kind == 'file'
             except (IOError, error.FileNotFound):
                 return False
 
         def exists(self):
             try:
-                return self._info()
+                return self.path.info()
             except IOError:
                 return self._listdirworks()
 

Modified: py/dist/py/path/svn/urlcommand.py
==============================================================================
--- py/dist/py/path/svn/urlcommand.py	(original)
+++ py/dist/py/path/svn/urlcommand.py	Sun Jan  2 12:35:29 2005
@@ -10,14 +10,18 @@
 from py.__impl__.path import common 
 from py.__impl__.path import error 
 from py.__impl__.path.svn import svncommon 
+from py.__impl__.misc.cache import BuildcostAccessCache, AgingCache 
 
 class SvnCommandPath(svncommon.SvnPathBase):
+    _lsrevcache = BuildcostAccessCache(maxentries=128) 
+    _lsnorevcache = AgingCache(maxentries=1000, maxseconds=60.0) 
+
     def __new__(cls, path, rev=None): 
-        if isinstance(path, cls): 
-            if path.rev == rev:
-                return path 
         self = object.__new__(cls)
-        self.strpath = path.rstrip('/')
+        if not isinstance(path, str): 
+            path = str(path) 
+        path = path.rstrip('/') 
+        self.strpath = path 
         self.rev = rev
         return self
 
@@ -64,22 +68,24 @@
             return popen(svncommon.fixlocale() + 
                             'svn cat -r %s "%s"' % (self.rev, self.strpath))
 
-    def mkdir(self, commit_msg=None):
-        if commit_msg:
-            self._svnwrite('mkdir', '-m', commit_msg)
-        else:
-            self._svnwrite('mkdir')
+    # modifying methods (cache must be invalidated) 
+    def mkdir(self, commit_msg="copied by py lib invocation"):
+        self._svnwrite('mkdir', '-m', commit_msg)
+        self._lsnorevcache.delentry(self.strpath) 
 
-    def copy(self, target, msg='auto'):
+    def copy(self, target, msg='copied by py lib invocation'):
         if getattr(target, 'rev', None) is not None: 
             raise path.Invalid("target can't have a revision: %r" % target)
         process.cmdexec("svn copy -m %r %s %s" %(msg, str(self), str(target)))
+        self._lsnorevcache.delentry(target.dirpath().strpath) 
 
-    def remove(self, rec=1, msg='auto'):
+    def remove(self, rec=1, msg='removed by py lib invocation'):
         if self.rev is not None:
             raise path.Invalid("cannot remove revisioned object: %r" % self)
         process.cmdexec("svn rm -m %r %s" %(msg, str(self)))
+        self._lsnorevcache.delentry(self.dirpath().strpath) 
 
+    # end of modifying methods 
     def _propget(self, name):
         res = self._svn('propget', name)
         return res[:-1] # strip trailing newline
@@ -92,25 +98,30 @@
 
     def _listdir_nameinfo(self):
         """ return sequence of name-info directory entries of self """
-        try:
-            res = self._svn('ls', '-v')
-        except process.cmdexec.Error, e:
-            if e.err.find('non-existent in that revision') != -1:
-                raise error.FileNotFound(self, e.err)
-            elif e.err.find('not part of a repository')!=-1:
-                raise IOError, e.err
-            elif e.err.find('Unable to open')!=-1:
-                raise IOError, e.err
-            elif e.err.lower().find('method not allowed')!=-1:
-                raise IOError, e.err
-            raise 
-        lines = res.split('\n')
-        nameinfo_seq = []
-        for lsline in lines:
-            if lsline:
-                info = InfoSvnCommand(lsline)
-                nameinfo_seq.append((info._name, info))
-        return nameinfo_seq
+        def builder(): 
+            try:
+                res = self._svn('ls', '-v')
+            except process.cmdexec.Error, e:
+                if e.err.find('non-existent in that revision') != -1:
+                    raise error.FileNotFound(self, e.err)
+                elif e.err.find('not part of a repository')!=-1:
+                    raise IOError, e.err
+                elif e.err.find('Unable to open')!=-1:
+                    raise IOError, e.err
+                elif e.err.lower().find('method not allowed')!=-1:
+                    raise IOError, e.err
+                raise 
+            lines = res.split('\n')
+            nameinfo_seq = []
+            for lsline in lines:
+                if lsline:
+                    info = InfoSvnCommand(lsline)
+                    nameinfo_seq.append((info._name, info))
+            return nameinfo_seq
+        if self.rev is not None: 
+            return self._lsrevcache.getorbuild((self.strpath, self.rev), builder)
+        else: 
+            return self._lsnorevcache.getorbuild(self.strpath, builder)
 
     def log(self, rev_start=None, rev_end=1, verbose=False):
         assert self.check() #make it simpler for the pipe



More information about the pytest-commit mailing list