# Code dedicated to debug commands around evolution## Copyright 2017 Pierre-Yves David <pierre-yves.david@ens-lyon.org>## This software may be used and distributed according to the terms of the# GNU General Public License version 2 or any later version.# Status: Ready to Upstream## * We could have the same code in core as `hg debugobsolete --stat`,# * We probably want a way for the extension to hook in for extra data.frommercurialimport(obsolete,node,)frommercurial.i18nimport_from.import(compat,exthelper,)eh=exthelper.exthelper()@eh.command(b'debugobsstorestat',[],b'')defcmddebugobsstorestat(ui,repo):"""print statistics about obsolescence markers in the repo"""def_updateclustermap(nodes,mark,clustersmap):c=(set(nodes),set([mark]))toproceed=set(nodes)whiletoproceed:n=toproceed.pop()other=clustersmap.get(n)if(otherisnotNoneandotherisnotc):other[0].update(c[0])other[1].update(c[1])foroninc[0]:ifonintoproceed:continueclustersmap[on]=otherc=otherclustersmap[n]=cstore=repo.obsstoreunfi=repo.unfiltered()getrev=compat.getgetrev(unfi.changelog)nbmarkers=len(store._all)ui.write(_(b'markers total: %9i\n')%nbmarkers)sucscount=[0,0,0,0]known=0parentsdata=0metakeys={}# node -> cluster mapping# a cluster is a (set(nodes), set(markers)) tupleclustersmap={}# same data using parent informationpclustersmap={}size_v0=[]size_v1=[]formarkinstore:ifgetrev(mark[0])isnotNone:known+=1nbsucs=len(mark[1])sucscount[min(nbsucs,3)]+=1meta=mark[3]forkey,valueinmeta:metakeys.setdefault(key,0)metakeys[key]+=1meta=dict(meta)parents=[meta.get(b'p1'),meta.get(b'p2')]parents=[node.bin(p)forpinparentsifpisnotNone]ifparents:parentsdata+=1# cluster handlingnodes=set(mark[1])nodes.add(mark[0])_updateclustermap(nodes,mark,clustersmap)# same with parent datanodes.update(parents)_updateclustermap(nodes,mark,pclustersmap)size_v0.append(len(obsolete._fm0encodeonemarker(mark)))size_v1.append(len(obsolete._fm1encodeonemarker(mark)))# freezing the resultforcinclustersmap.values():fc=(frozenset(c[0]),frozenset(c[1]))forninfc[0]:clustersmap[n]=fc# same with parent dataforcinpclustersmap.values():fc=(frozenset(c[0]),frozenset(c[1]))forninfc[0]:pclustersmap[n]=fcnumobs=len(unfi.revs(b'obsolete()'))numtotal=len(unfi)ui.write((b' for known precursors: %9i'%known))ui.write((b' (%i/%i obsolete changesets)\n'%(numobs,numtotal)))ui.write((b' with parents data: %9i\n'%parentsdata))# successors dataui.write((b'markers with no successors: %9i\n'%sucscount[0]))ui.write((b' 1 successors: %9i\n'%sucscount[1]))ui.write((b' 2 successors: %9i\n'%sucscount[2]))ui.write((b' more than 2 successors: %9i\n'%sucscount[3]))# meta data infoui.write((b' available keys:\n'))forkeyinsorted(metakeys):ui.write((b' %15s: %9i\n'%(key,metakeys[key])))size_v0.sort()size_v1.sort()ifsize_v0:ui.write(b'marker size:\n')# format v1ui.write(b' format v1:\n')ui.write((b' smallest length: %9i\n'%size_v1[0]))ui.write((b' longer length: %9i\n'%size_v1[-1]))median=size_v1[nbmarkers//2]ui.write((b' median length: %9i\n'%median))mean=sum(size_v1)//nbmarkersui.write((b' mean length: %9i\n'%mean))# format v0ui.write(b' format v0:\n')ui.write((b' smallest length: %9i\n'%size_v0[0]))ui.write((b' longer length: %9i\n'%size_v0[-1]))median=size_v0[nbmarkers//2]ui.write((b' median length: %9i\n'%median))mean=sum(size_v0)//nbmarkersui.write((b' mean length: %9i\n'%mean))allclusters=list(set(clustersmap.values()))allclusters.sort(key=lambdax:len(x[1]))ui.write((b'disconnected clusters: %9i\n'%len(allclusters)))ui.write(b' any known node: %9i\n'%len([cforcinallclustersif[nforninc[0]ifgetrev(n)isnotNone]]))ifallclusters:nbcluster=len(allclusters)ui.write((b' smallest length: %9i\n'%len(allclusters[0][1])))ui.write((b' longer length: %9i\n'%len(allclusters[-1][1])))median=len(allclusters[nbcluster//2][1])ui.write((b' median length: %9i\n'%median))mean=sum(len(x[1])forxinallclusters)//nbclusterui.write((b' mean length: %9i\n'%mean))allpclusters=list(set(pclustersmap.values()))allpclusters.sort(key=lambdax:len(x[1]))ui.write((b' using parents data: %9i\n'%len(allpclusters)))ui.write(b' any known node: %9i\n'%len([cforcinallclustersif[nforninc[0]ifgetrev(n)isnotNone]]))ifallpclusters:nbcluster=len(allpclusters)ui.write((b' smallest length: %9i\n'%len(allpclusters[0][1])))ui.write((b' longer length: %9i\n'%len(allpclusters[-1][1])))median=len(allpclusters[nbcluster//2][1])ui.write((b' median length: %9i\n'%median))mean=sum(len(x[1])forxinallpclusters)//nbclusterui.write((b' mean length: %9i\n'%mean))