[PATCH 04 of 11 v2] localrepo: decorate dirstate() with filecache

timeless timeless at gmail.com
Mon Jul 25 08:20:06 CDT 2011


s/different to/different from/
s/that it/in that it/
s/rereads/reread/

On 7/25/11, Idan Kamara <idankk86 at gmail.com> wrote:
> # HG changeset patch
> # User Idan Kamara <idankk86 at gmail.com>
> # Date 1311595717 -10800
> # Node ID 5a728dc76ad8ec3be9bdce47e24a0157997f3a00
> # Parent  dfba7752392c9e7af6792ed337040b70d48d1fac
> localrepo: decorate dirstate() with filecache
>
> We refresh the stat info when releasing repo.wlock(), right after writing
> it.
>
> Also, invalidate the dirstate by deleting its attribute. This will force a
> stat by the decorator that actually checks if anything changed, rather than
> reading it again every time.
>
> Note that prior to this, there was a single dirstate instance created for a
> localrepo. It was invalidated by calling dirstate.invalidated(), clearing
> its internal attributes.
>
> As a consequence, the following construct is no longer safe:
>
>   ds = repo.dirstate # keep a reference to the repo's dirstate
>   wlock = repo.wlock()
>   try:
>       ds.setparents(...)
>   finally:
>       wlock.release() # dirstate should be written here
>
> Since it's possible that the dirstate was modified between lines #1 and #2,
> therefore changes to the old dirstate won't get written when the lock
> releases,
> because a new instance was created by the decorator.
>
> diff -r dfba7752392c -r 5a728dc76ad8 mercurial/localrepo.py
> --- a/mercurial/localrepo.py	Mon Jul 25 15:08:37 2011 +0300
> +++ b/mercurial/localrepo.py	Mon Jul 25 15:08:37 2011 +0300
> @@ -17,6 +17,7 @@
>  from lock import release
>  import weakref, errno, os, time, inspect
>  propertycache = util.propertycache
> +filecache = scmutil.filecache
>
>  class localrepository(repo.repository):
>      capabilities = set(('lookup', 'changegroupsubset', 'branchmap',
> 'pushkey',
> @@ -187,7 +188,7 @@
>      def manifest(self):
>          return manifest.manifest(self.sopener)
>
> -    @propertycache
> +    @filecache('dirstate')
>      def dirstate(self):
>          warned = [0]
>          def validate(node):
> @@ -797,6 +798,20 @@
>          self._branchcache = None # in UTF-8
>          self._branchcachetip = None
>
> +    def invalidatedirstate(self):
> +        '''Invalidates the dirstate, causing the next call to dirstate
> +        to check if it was modified since the last time it was read,
> +        rereading it if it has.
> +
> +        This is different to dirstate.invalidate() that it doesn't always
> +        rereads the dirstate. Use dirstate.invalidate() if you want to
> +        explicitly read the dirstate again (i.e. restoring it to a previous
> +        known good state).'''
> +        try:
> +            delattr(self, 'dirstate')
> +        except AttributeError:
> +            pass
> +
>      def invalidate(self):
>          for a in ("changelog", "manifest", "_bookmarks",
> "_bookmarkcurrent"):
>              if a in self.__dict__:
> @@ -841,8 +856,14 @@
>              l.lock()
>              return l
>
> -        l = self._lock(self.join("wlock"), wait, self.dirstate.write,
> -                       self.dirstate.invalidate, _('working directory of
> %s') %
> +        def unlock():
> +            self.dirstate.write()
> +            ce = self._filecache.get('dirstate')
> +            if ce:
> +                ce.refresh()
> +
> +        l = self._lock(self.join("wlock"), wait, unlock,
> +                       self.invalidatedirstate, _('working directory of
> %s') %
>                         self.origroot)
>          self._wlockref = weakref.ref(l)
>          return l
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
>

-- 
Sent from my mobile device


More information about the Mercurial-devel mailing list