mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 01:07:15 +03:00
2a938a761c
Summary: Previously we were throwing away copy information when we repacked things into pack files. The hope was that we could store copy information somewhere else, and keep the history pack using fixed length entries. Since storing copy information elsewhere is a long ways off, let's just go ahead and put copy info in the pack file. This makes the entries non-fixed length, which means any iteration over them has to read the length of each entry. This also affects the historypack filename hashes since they are content based, so the tests had to change. This matches the old remotefilelog behavior more closely (which is why no code had to change outside the pack logic). Test Plan: Added a test Reviewers: #mercurial, mitrandir, ttung Reviewed By: mitrandir Subscribers: mitrandir Differential Revision: https://phabricator.intern.facebook.com/D3262185 Signature: t1:3262185:1462562602:935683692276c7fa569d381b18aa3b18656793b1
108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
import os
|
|
import basestore, shallowutil
|
|
from mercurial import error, util
|
|
from mercurial.i18n import _
|
|
from mercurial.node import hex, nullid
|
|
|
|
class unionmetadatastore(object):
|
|
def __init__(self, *args, **kwargs):
|
|
self.stores = args
|
|
self.writestore = kwargs.get('writestore')
|
|
|
|
def getancestors(self, name, node):
|
|
"""Returns as many ancestors as we're aware of.
|
|
|
|
return value: {
|
|
node: (p1, p2, linknode, copyfrom),
|
|
...
|
|
}
|
|
"""
|
|
ancestors = {}
|
|
def traverse(curname, curnode):
|
|
# TODO: this algorithm has the potential to traverse parts of
|
|
# history twice. Ex: with A->B->C->F and A->B->D->F, both D and C
|
|
# may be queued as missing, then B and A are traversed for both.
|
|
queue = [(curname, curnode)]
|
|
missing = []
|
|
while queue:
|
|
name, node = queue.pop()
|
|
value = ancestors.get(node)
|
|
if not value:
|
|
missing.append((name, node))
|
|
continue
|
|
p1, p2, linknode, copyfrom = value
|
|
if p1 != nullid:
|
|
queue.append((copyfrom or curname, p1))
|
|
if p2 != nullid:
|
|
queue.append((curname, p2))
|
|
return missing
|
|
|
|
missing = [(name, node)]
|
|
while missing:
|
|
curname, curnode = missing.pop()
|
|
ancestors.update(self._getpartialancestors(curname, curnode))
|
|
newmissing = traverse(curname, curnode)
|
|
missing.extend(newmissing)
|
|
|
|
# TODO: ancestors should probably be (name, node) -> (value)
|
|
return ancestors
|
|
|
|
def _getpartialancestors(self, name, node):
|
|
for store in self.stores:
|
|
try:
|
|
return store.getancestors(name, node)
|
|
except KeyError:
|
|
pass
|
|
|
|
raise error.LookupError(node, name, _('no valid file history'))
|
|
|
|
def add(self, name, node, data):
|
|
raise RuntimeError("cannot add content only to remotefilelog "
|
|
"contentstore")
|
|
|
|
def getmissing(self, keys):
|
|
missing = keys
|
|
for store in self.stores:
|
|
if missing:
|
|
missing = store.getmissing(missing)
|
|
return missing
|
|
|
|
def markledger(self, ledger):
|
|
for store in self.stores:
|
|
store.markledger(ledger)
|
|
|
|
class remotefilelogmetadatastore(basestore.basestore):
|
|
def getancestors(self, name, node):
|
|
"""Returns as many ancestors as we're aware of.
|
|
|
|
return value: {
|
|
node: (p1, p2, linknode, copyfrom),
|
|
...
|
|
}
|
|
"""
|
|
data = self._getdata(name, node)
|
|
ancestors = shallowutil.ancestormap(data)
|
|
return ancestors
|
|
|
|
def add(self, name, node, parents, linknode):
|
|
raise RuntimeError("cannot add metadata only to remotefilelog "
|
|
"metadatastore")
|
|
|
|
class remotemetadatastore(object):
|
|
def __init__(self, ui, fileservice, shared):
|
|
self._fileservice = fileservice
|
|
self._shared = shared
|
|
|
|
def getancestors(self, name, node):
|
|
self._fileservice.prefetch([(name, hex(node))])
|
|
return self._shared.getancestors(name, node)
|
|
|
|
def add(self, name, node, data):
|
|
raise RuntimeError("cannot add to a remote store")
|
|
|
|
def getmissing(self, keys):
|
|
return keys
|
|
|
|
def markledger(self, ledger):
|
|
pass
|