subrepo: avoid redundant "util.makedirs" invocation

"util.makedirs" for the (sub-)repository root of "hgsubrepo" is also
executed in the constructor of "localrepository", if "create" is True
and ".hg" of it doesn't exist.

This patch avoids redundant "util.makedirs" invocation in the
constructor of "hgsubrepo".
subrepo: replace "os.path.exists" by "exists" via wvfs of the parent

Existance of specified "path" should be examined by "exists" via wvfs
of the parent repository, because the working directory of the parent
repository may be in UTF-8 mode. Wide API should be used via wvfs in
such case.

In this patch, "/" is used as the path separator, even though "path"
uses platform specific path separator (e.g. "\\" on Windows). But it
is reasonable enough, because "store" and other management file
handling already include such implementation, and they work well.
subrepo: replace "_calcfilehash" invocation by "vfs.tryread"

"_calcfilehash" can be completely replaced by simple "vfs.tryread"
invocation.

    def _calcfilehash(filename):
        data = ''
        if os.path.exists(filename):
            fd = open(filename, 'rb')
            data = fd.read()
            fd.close()
        return util.sha1(data).hexdigest()

Building absolute path "absname" up by "self._repo.join" for files in
"filelist" is avoided, because "vfs.tryread" does so internally.
subrepo: remove "_calcfilehash" referred by no other code paths
subrepo: add "_cachestorehashvfs" to handle cache store hash files via vfs

This "vfs" object will be used by subsequent patches to handle cache
store hash files without direct file APIs.

This patch decorates "_cachestorehashvfs" with "@propertycache" to
delay vfs creation, because it is used only for cooperation with other
repositories.

In this patch, "/" is used as the path separator, even though
"self._repo.join" uses platform specific path separator (e.g. "\\" on
Windows). But it is reasonable enough, because "store" and other
management file handling already include such implementation, and they
work well.
vfs: add "readlines" and "tryreadlines"

This patch allows "readlines" and "tryreadlines" to take "mode"
argument, because "subrepo" requires to read files not in "rb"
(binary, default for vfs) but in "r" (text) mode in subsequent patch.
subrepo: replace direct file APIs around "readlines" by "vfs.tryreadlines"

This patch also replaces "self._getstorehashcachepath" (building
absolute path up) by "self._getstorehashcachename" (building relative
path up), because "vfs.tryreadlines" requires relative path.

This patch makes "_readstorehashcache()" return "[]" (returned by
"vfs.tryreadlines()"), when cache file doesn't exist, even though
"_readstorehashcache()" returned '' (empty string) in such case before
this patch.

"_readstorehashcache()" is invoked only by the code path below in
"_storeclean()":

            for filehash in self._readstorehashcache(path):
                if filehash != itercache.next():
                    clean = False
                    break

In this case, "[]" and '' don't differ from each other, because both
of them cause avoiding iteration of "for loop".
vfs: add "notindexed" argument to invoke "ensuredir" with it in write mode

This patch uses "False" as default value of "notindexed" argument,
even though "vfs.makedir()" uses "True" for it, because "os.mkdir()"
doesn't set "_FILE_ATTRIBUTE_NOT_CONTENT_INDEXED" attribute to newly
created directories.
vfs: add "writelines"

This patch allows "writelines" to take "mode" and "notindexed"
arguments, because subsequent patch for subrepo requires both.
subrepo: replace direct file APIs around "writelines" by "vfs.writelines"

This patch also replaces "self._getstorehashcachepath" (building
absolute path up) by "self._getstorehashcachename" (building relative
path up), because "vfs.writelines" requires relative path.
subrepo: remove "_getstorehashcachepath" referred by no other code paths
revert: access status fields by name rather than index

For better readability.

--HG--
extra : rebase_source : fca2fd8d70f3d6572bfce9854ccdad990710c3aa
dirstate: speed up repeated missing directory checks

In a mozilla repo with tip at bb3ff09f52fe,

  hg update tip~1000 && time hg revert -nq -r tip .

displays ~4:20 minutes. With tip~100, it runs in ~11 s. With revision
100000, it did not finish in 12 minutes.

Revert calls dirstate.status() with a matcher that matches each file
in the target revision. The main problem [1] lies in
dirstate._walkexplicit(), which looks for matching deleted directories
by checking whether each path is prefix of any path in the
dirstate. With m files in the dirstate and n files in the target
revision that are not in the dirstate, this is clearly O(m*n). Let's
improve by keeping a lazily initialized set of all the directories in
the dirstate, so the time becomes O(m+n).

After this patch, the 4:20 minutes become 5.5 s, while for a single
missing path, it slows down from 1.092 s to 1.150 s (best of 4). The
>12 min case becomes 5.8 s.

 [1] A narrower optimization would be to make revert take the fast
     path for '.' and '--all'.

--HG--
extra : rebase_source : 9b8b14c4f0f641b68208eae570484bdcbca4e82a