diff --git a/remotefilelog/__init__.py b/remotefilelog/__init__.py --- a/remotefilelog/__init__.py +++ b/remotefilelog/__init__.py @@ -933,6 +933,10 @@ def debughistorypack(ui, path, **opts): return debugcommands.debughistorypack(ui, path) +@command('debugpackstatus', [], 'hg debugpackstatus') +def debugpackstatus(repo, ui, **opts): + return debugcommands.debugpackstatus(repo, ui) + @command('debugkeepset', [ ], _('hg debugkeepset')) def debugkeepset(ui, repo, **opts): diff --git a/remotefilelog/basestore.py b/remotefilelog/basestore.py --- a/remotefilelog/basestore.py +++ b/remotefilelog/basestore.py @@ -40,6 +40,30 @@ if shared: shallowutil.mkstickygroupdir(self.ui, path) + def getnumfiles(self): + count = 0 + for fn, node in self._listkeys(): + count += 1 + return count + + def gettotalsize(self): + totalsize = 0 + for fnhash, node in self._listkeys(): + fnhashhex = hex(fnhash) + path = self._getrootpath() + '/' + path += (fnhashhex[0:2] + '/' + fnhashhex[2:] if self._shared else + fnhashhex) + path += '/' + hex(node) + totalsize += os.stat(path).st_size + + return totalsize + + def getmetrics(self): + return { + 'numloosefiles': self.getnumfiles(), + 'totalloosesize': self.gettotalsize(), + } + def getmissing(self, keys): missing = [] for name, node in keys: @@ -152,16 +176,18 @@ return filenames + def _getrootpath(self): + if self._shared: + return os.path.join(self._path, self._reponame) + else: + return self._path + def _listkeys(self): """List all the remotefilelog keys that exist in the store. Returns a iterator of (filename hash, filecontent hash) tuples. """ - if self._shared: - path = os.path.join(self._path, self._reponame) - else: - path = self._path - + path = self._getrootpath() for root, dirs, files in os.walk(path): for filename in files: if len(filename) != 40: diff --git a/remotefilelog/contentstore.py b/remotefilelog/contentstore.py --- a/remotefilelog/contentstore.py +++ b/remotefilelog/contentstore.py @@ -222,6 +222,9 @@ def markledger(self, ledger): pass + def getmetrics(self): + return {} + class manifestrevlogstore(object): def __init__(self, repo): self._store = repo.store diff --git a/remotefilelog/debugcommands.py b/remotefilelog/debugcommands.py --- a/remotefilelog/debugcommands.py +++ b/remotefilelog/debugcommands.py @@ -6,7 +6,7 @@ # GNU General Public License version 2 or any later version. from __future__ import absolute_import -from mercurial import error, filelog, revlog +from mercurial import error, filelog, revlog, util from mercurial.node import bin, hex, nullid, short from mercurial.i18n import _ from . import ( @@ -357,6 +357,33 @@ ui.write("%s %s %s %s %s\n" % (short(node), short(p1node), short(p2node), short(linknode), copyfrom)) +def debugpackstatus(ui, repo): + def format(metrics, paths=None): + parts = [] + if 'numpacks' in metrics: + parts.append("%d packs consuming %s" % (metrics['numpacks'], + util.bytecount(metrics['totalpacksize']))) + if 'numloosefiles' in metrics: + parts.append("%d loose files consuming %s" % ( + metrics['numloosefiles'], + util.bytecount(metrics['totalloosesize']))) + + if paths: + parts.append("in %s" % ",".join(paths)) + return ", ".join(parts) + + mfl = repo.manifestlog + ui.write("Local Tree Store: %s\n" % format( + shallowutil.sumdicts(*[s.getmetrics() for s in mfl.localdatastores]), + [s.path for p in mfl.localdatastores] + )) + ui.write("Shared Tree Store: %s\n" % format( + shallowutil.sumdicts(*[s.getmetrics() for s in mfl.shareddatastores]), + [s.path for p in mfl.localdatastores] + )) + ui.write("File Content Store: %s\n" % format(repo.contentstore.getmetrics())) + ui.write("File Data Store: %s\n" % format(repo.metadatastore.getmetrics())) + def debugwaitonrepack(repo): with repo._lock(repo.svfs, "repacklock", True, None, None, _('repacking %s') % repo.origroot): diff --git a/remotefilelog/metadatastore.py b/remotefilelog/metadatastore.py --- a/remotefilelog/metadatastore.py +++ b/remotefilelog/metadatastore.py @@ -145,3 +145,6 @@ def markledger(self, ledger): pass + + def getmetrics(self): + return {}