fastmanifest: move tree writing to memmanifestctx.write()

Summary:
Previously fastmanifest hooked into manifestrevlog.add() to write the local tree
manifest when a flat manifest is written. In a future diff we'll be moving the
datastore objects off of the opener object and on to the manifestlog. Since we
need the datastore to write trees, and the datastore will soon be on the
manifestlog, and the manifestlog isn't accessible from manifestrevlog.add(), we
need to move our tree write up to the ctx level instead. This is probably
cleaner anyway since the ctx level is where we differentiate manifest types, not
at the revlog/storage level.

Test Plan: Ran the tests

Reviewers: #fbhgext, ryanmce

Reviewed By: #fbhgext, ryanmce

Differential Revision: https://phab.mercurial-scm.org/D233
This commit is contained in:
Durham Goode 2017-08-07 19:27:17 -07:00
parent 44b2f83b7d
commit b10ba0327d
2 changed files with 24 additions and 13 deletions

View File

@ -202,6 +202,8 @@ class FastManifestExtension(object):
manifest.manifestlog, '__getitem__', factory.newgetitem) manifest.manifestlog, '__getitem__', factory.newgetitem)
extensions.wrapfunction( extensions.wrapfunction(
manifest.manifestlog, 'get', factory.newgetdirmanifestctx) manifest.manifestlog, 'get', factory.newgetdirmanifestctx)
extensions.wrapfunction(
manifest.memmanifestctx, 'write', factory.ctxwrite)
extensions.wrapfunction(manifest.manifestrevlog, 'add', factory.add) extensions.wrapfunction(manifest.manifestrevlog, 'add', factory.add)
if ui.configbool('fastmanifest', 'usecache', True): if ui.configbool('fastmanifest', 'usecache', True):

View File

@ -968,18 +968,27 @@ class manifestfactory(object):
# If neither cache could help, fallback to the normal add # If neither cache could help, fallback to the normal add
node = orig(*args, **kwargs) node = orig(*args, **kwargs)
# Add the new manifest to the tree return node
def ctxwrite(self, orig, mfctx, transaction, link, p1, p2, added, removed):
node = orig(mfctx, transaction, link, p1, p2, added, removed)
treeenabled = self.ui.configbool("fastmanifest", "usetree", False)
if supportsctree and treeenabled: if supportsctree and treeenabled:
mfl = mfctx._manifestlog
datastore = mfctx._revlog().opener.manifestdatastore
opener = mfctx._revlog().opener
m = mfctx._manifestdict
# hybridmanifest requires you provide either a value or loadflat.
# Let's give it a dummy value, since we know we'll only be calling
# _treemanifest()
def loadflat(): def loadflat():
# This should eventually be made lazy loaded, so consumers can raise RuntimeError("no-op loadflat should never be hit")
# access the node/p1/linkrev data without having to parse the tree = hybridmanifest(self.ui, opener, mfl, loadflat=loadflat,
# whole manifest.
data = origself.revision(p1)
arraytext = bytearray(data)
origself._fulltextcache[p1] = arraytext
return manifest.manifestdict(data)
tree = hybridmanifest(self.ui, origself.opener, loadflat=loadflat,
node=p1)._treemanifest() node=p1)._treemanifest()
if tree is not None: if tree is not None:
newtree = tree.copy() newtree = tree.copy()
for filename in removed: for filename in removed:
@ -992,7 +1001,7 @@ class manifestfactory(object):
if not util.safehasattr(transaction, 'treedatapack'): if not util.safehasattr(transaction, 'treedatapack'):
packpath = shallowutil.getlocalpackpath( packpath = shallowutil.getlocalpackpath(
origself.opener.vfs.base, opener.vfs.base,
'manifests') 'manifests')
transaction.treedatapack = datapack.mutabledatapack( transaction.treedatapack = datapack.mutabledatapack(
self.ui, self.ui,
@ -1003,9 +1012,9 @@ class manifestfactory(object):
def finalize(tr): def finalize(tr):
tr.treedatapack.close() tr.treedatapack.close()
tr.treehistpack.close() tr.treehistpack.close()
treemanifestcache.getinstance(origself.opener, treemanifestcache.getinstance(opener,
self.ui).clear() self.ui).clear()
origself.opener.manifestdatastore.markforrefresh() datastore.markforrefresh()
def abort(tr): def abort(tr):
tr.treedatapack.abort() tr.treedatapack.abort()
tr.treehistpack.abort() tr.treehistpack.abort()
@ -1024,7 +1033,7 @@ class manifestfactory(object):
dpack.add(nname, nnode, revlog.nullid, ntext) dpack.add(nname, nnode, revlog.nullid, ntext)
hpack.add(nname, nnode, np1, np2, revlog.nullid, '') hpack.add(nname, nnode, np1, np2, revlog.nullid, '')
treemanifestcache.getinstance(origself.opener, treemanifestcache.getinstance(opener,
self.ui)[node] = newtree self.ui)[node] = newtree
return node return node