[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