bundle2: extract logic for seeking bundle2 part into own class
Currently, unbundlepart classes support bi-directional seeking.
Most consumers of unbundlepart only ever seek forward - typically
as part of moving to the end of the bundle part so they can move
on to the next one. But regardless of the actual usage of the
part, instances maintain an index mapping offsets within the
underlying raw payload to offsets within the decoded payload.
Maintaining the mapping of offset data can be expensive in terms of
memory use. Furthermore, many bundle2 consumers don't have access
to an underlying seekable stream. This includes all compressed
bundles. So maintaining offset data when the underlying stream
can't be seeked anyway is wasteful. And since many bundle2 streams
can't be seeked, it seems like a bad idea to expose a seek API
in bundle2 parts by default. If you provide them, people will
attempt to use them.
Seekable bundle2 parts should be the exception, not the rule. This
commit starts the process dividing unbundlepart into 2 classes: a
base class that supports linear, one-time reads and a child class
that supports bi-directional seeking. In this first commit, we
split various methods and attributes out into a new
"seekableunbundlepart" class. Previous instantiators of "unbundlepart"
now instantiate "seekableunbundlepart." This preserves backwards
compatibility. The coupling between the classes is still tight:
"unbundlepart" cannot be used on its own. This will be addressed
in subsequent commits.
Differential Revision: https://phab.mercurial-scm.org/D1386
Create a repository:
$ hg config
devel.all-warnings=true
devel.default-date=0 0
extensions.fsmonitor= (fsmonitor !)
largefiles.usercache=$TESTTMP/.cache/largefiles (glob)
ui.slash=True
ui.interactive=False
ui.mergemarkers=detailed
ui.promptecho=True
web.address=localhost
web\.ipv6=(?:True|False) (re)
$ hg init t
$ cd t
Prepare a changeset:
$ echo a > a
$ hg add a
$ hg status
A a
Writes to stdio succeed and fail appropriately
#if devfull
$ hg status 2>/dev/full
A a
$ hg status >/dev/full
abort: No space left on device
[255]
#endif
#if devfull no-chg
$ hg status >/dev/full 2>&1
[1]
$ hg status ENOENT 2>/dev/full
[1]
#endif
#if devfull chg
$ hg status >/dev/full 2>&1
[255]
$ hg status ENOENT 2>/dev/full
[255]
#endif
$ hg commit -m test
This command is ancient:
$ hg history
changeset: 0:acb14030fe0a
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: test
Verify that updating to revision 0 via commands.update() works properly
$ cat <<EOF > update_to_rev0.py
> from mercurial import ui, hg, commands
> myui = ui.ui.load()
> repo = hg.repository(myui, path='.')
> commands.update(myui, repo, rev=0)
> EOF
$ hg up null
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ $PYTHON ./update_to_rev0.py
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg identify -n
0
Poke around at hashes:
$ hg manifest --debug
b789fdd96dc2f3bd229c1dd8eedf0fc60e2b68e3 644 a
$ hg cat a
a
Verify should succeed:
$ hg verify
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
1 files, 1 changesets, 1 total revisions
At the end...
$ cd ..