[PATCH 5 of 5] posix: give checklink a fast path that cache the check file and is read only

Augie Fackler raf at durin42.com
Fri Nov 18 20:36:10 EST 2016


On Thu, Nov 17, 2016 at 07:44:21PM +0100, Mads Kiilerich wrote:
> # HG changeset patch
> # User Mads Kiilerich <madski at unity3d.com>
> # Date 1421194526 -3600
> #      Wed Jan 14 01:15:26 2015 +0100
> # Node ID 73b671fbed41d82a5dd46e485c61ddb8afe42faf
> # Parent  5409e0c5e6c0764e802360a3912f7719885ba2b5
> posix: give checklink a fast path that cache the check file and is read only

Queued these, thanks.

>
> util.checklink would create a symlink and remove it again. That would sometimes
> happen multiple times. Write operations are relatively expensive and give disk
> tear and noise for applications monitoring file system activity.
>
> Instead of creating a symlink and deleting it again, just create it once and
> leave it in .hg/cache/check-link . If the file exists, just verify that
> os.islink reports true. We will assume that this check is as good as symlink
> creation not failing.
>
> Note: The symlink left in .hg/cache has to resolve to a file - otherwise 'make
> dist' will fail ...
>
> test-symlink-os-yes-fs-no.py does some monkey patching to simulate a platform
> without symlink support. The slightly different testing method requires
> additional monkeying.
>
> diff --git a/mercurial/posix.py b/mercurial/posix.py
> --- a/mercurial/posix.py
> +++ b/mercurial/posix.py
> @@ -220,6 +220,10 @@ def checklink(path):
>      # file already exists
>      while True:
>          cachedir = os.path.join(path, '.hg', 'cache')
> +        checklink = os.path.join(cachedir, 'checklink')
> +        # try fast path, read only
> +        if os.path.islink(checklink):
> +            return True
>          if os.path.isdir(cachedir):
>              checkdir = cachedir
>          else:
> @@ -231,7 +235,13 @@ def checklink(path):
>                                               prefix='hg-checklink-')
>              try:
>                  os.symlink(os.path.basename(fd.name), name)
> -                os.unlink(name)
> +                if cachedir is None:
> +                    os.unlink(name)
> +                else:
> +                    try:
> +                        os.rename(name, checklink)
> +                    except OSError:
> +                        os.unlink(name)
>                  return True
>              except OSError as inst:
>                  # link creation might race, try again
> diff --git a/tests/test-clone.t b/tests/test-clone.t
> --- a/tests/test-clone.t
> +++ b/tests/test-clone.t
> @@ -32,6 +32,7 @@ Trigger branchcache creation:
>    $ ls .hg/cache
>    branch2-served
>    checkisexec
> +  checklink
>    checknoexec
>    rbc-names-v1
>    rbc-revs-v1
> @@ -48,6 +49,7 @@ Ensure branchcache got copied over:
>    $ ls .hg/cache
>    branch2-served
>    checkisexec
> +  checklink
>
>    $ cat a
>    a
> diff --git a/tests/test-symlink-os-yes-fs-no.py b/tests/test-symlink-os-yes-fs-no.py
> --- a/tests/test-symlink-os-yes-fs-no.py
> +++ b/tests/test-symlink-os-yes-fs-no.py
> @@ -35,6 +35,9 @@ commands.status(u, repo)
>  def symlink_failure(src, dst):
>      raise OSError(1, "Operation not permitted")
>  os.symlink = symlink_failure
> +def islink_failure(path):
> +    return False
> +os.path.islink = islink_failure
>
>  # dereference links as if a Samba server has exported this to a
>  # Windows client
> diff --git a/tests/test-tags.t b/tests/test-tags.t
> --- a/tests/test-tags.t
> +++ b/tests/test-tags.t
> @@ -673,6 +673,7 @@ Missing tags2* files means the cache was
>    $ ls tagsclient/.hg/cache
>    branch2-served
>    checkisexec
> +  checklink
>    hgtagsfnodes1
>    rbc-names-v1
>    rbc-revs-v1
> @@ -698,6 +699,7 @@ Running hg tags should produce tags2* fi
>    $ ls tagsclient/.hg/cache
>    branch2-served
>    checkisexec
> +  checklink
>    hgtagsfnodes1
>    rbc-names-v1
>    rbc-revs-v1
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list