treemanifest: lazily load manifests
Most operations on treemanifests already visit only relevant
submanifests. Notable examples include __getitem__, __contains__,
walk/matches with matcher, diff. By making submanifests lazily loaded,
we speed up all these operations.
The lazy loading is achieved by adding a _load() method that gets
defined where we currently eagerly parse the manifest. We make sure to
call it before any access to _dirs, _files or _flags.
Some timings on the Mozilla repo (with flat manifest timings for
reference):
hg cat -r . README.txt: 1.644s -> 0.096s (0.255s)
hg diff -r .^ -r . : 1.746s -> 0.137s (0.431s)
hg files -r . python : 1.508s -> 0.146s (0.335s)
hg files -r . : 2.125s -> 2.203s (0.712s)
$ cat > unix2mac.py <<EOF
> import sys
>
> for path in sys.argv[1:]:
> data = file(path, 'rb').read()
> data = data.replace('\n', '\r')
> file(path, 'wb').write(data)
> EOF
$ cat > print.py <<EOF
> import sys
> print(sys.stdin.read().replace('\n', '<LF>').replace('\r', '<CR>').replace('\0', '<NUL>'))
> EOF
$ hg init
$ echo '[hooks]' >> .hg/hgrc
$ echo 'pretxncommit.cr = python:hgext.win32text.forbidcr' >> .hg/hgrc
$ echo 'pretxnchangegroup.cr = python:hgext.win32text.forbidcr' >> .hg/hgrc
$ cat .hg/hgrc
[hooks]
pretxncommit.cr = python:hgext.win32text.forbidcr
pretxnchangegroup.cr = python:hgext.win32text.forbidcr
$ echo hello > f
$ hg add f
$ hg ci -m 1
$ python unix2mac.py f
$ hg ci -m 2
attempt to commit or push text file(s) using CR line endings
in dea860dc51ec: f
transaction abort!
rollback completed
abort: pretxncommit.cr hook failed
[255]
$ hg cat f | python print.py
hello<LF>
$ cat f | python print.py
hello<CR>