Mercurial > hg
comparison contrib/shrink-revlog.py @ 10213:9e6848f352b0
contrib: use ui to write in shrink-revlog.py
author | Dirkjan Ochtman <dirkjan@ochtman.nl> |
---|---|
date | Thu, 07 Jan 2010 15:07:18 +0100 |
parents | 69dca8574a6a |
children | 8111f9988c9d |
comparison
equal
deleted
inserted
replaced
10212:3ab391dd5ec5 | 10213:9e6848f352b0 |
---|---|
20 import sys, os, tempfile | 20 import sys, os, tempfile |
21 import optparse | 21 import optparse |
22 from mercurial import ui as ui_, hg, revlog, transaction, node, util | 22 from mercurial import ui as ui_, hg, revlog, transaction, node, util |
23 from mercurial import changegroup | 23 from mercurial import changegroup |
24 | 24 |
25 def toposort(rl): | 25 def toposort(ui, rl): |
26 write = sys.stdout.write | |
27 | 26 |
28 children = {} | 27 children = {} |
29 root = [] | 28 root = [] |
30 # build children and roots | 29 # build children and roots |
31 write('reading %d revs ' % len(rl)) | 30 ui.write('reading %d revs ' % len(rl)) |
32 try: | 31 try: |
33 for i in rl: | 32 for i in rl: |
34 children[i] = [] | 33 children[i] = [] |
35 parents = [p for p in rl.parentrevs(i) if p != node.nullrev] | 34 parents = [p for p in rl.parentrevs(i) if p != node.nullrev] |
36 # in case of duplicate parents | 35 # in case of duplicate parents |
42 | 41 |
43 if len(parents) == 0: | 42 if len(parents) == 0: |
44 root.append(i) | 43 root.append(i) |
45 | 44 |
46 if i % 1000 == 0: | 45 if i % 1000 == 0: |
47 write('.') | 46 ui.write('.') |
48 finally: | 47 finally: |
49 write('\n') | 48 ui.write('\n') |
50 | 49 |
51 # XXX this is a reimplementation of the 'branchsort' topo sort | 50 # XXX this is a reimplementation of the 'branchsort' topo sort |
52 # algorithm in hgext.convert.convcmd... would be nice not to duplicate | 51 # algorithm in hgext.convert.convcmd... would be nice not to duplicate |
53 # the algorithm | 52 # the algorithm |
54 write('sorting ...') | 53 ui.write('sorting ...') |
55 visit = root | 54 visit = root |
56 ret = [] | 55 ret = [] |
57 while visit: | 56 while visit: |
58 i = visit.pop(0) | 57 i = visit.pop(0) |
59 ret.append(i) | 58 ret.append(i) |
66 parents_unseen = [p for p in rl.parentrevs(c) | 65 parents_unseen = [p for p in rl.parentrevs(c) |
67 if p != node.nullrev and p in children] | 66 if p != node.nullrev and p in children] |
68 if len(parents_unseen) == 0: | 67 if len(parents_unseen) == 0: |
69 next.append(c) | 68 next.append(c) |
70 visit = next + visit | 69 visit = next + visit |
71 write('\n') | 70 ui.write('\n') |
72 return ret | 71 return ret |
73 | 72 |
74 def writerevs(r1, r2, order, tr): | 73 def writerevs(ui, r1, r2, order, tr): |
75 write = sys.stdout.write | 74 |
76 write('writing %d revs ' % len(order)) | 75 ui.write('writing %d revs ' % len(order)) |
77 | |
78 count = [0] | 76 count = [0] |
79 def progress(*args): | 77 def progress(*args): |
80 if count[0] % 1000 == 0: | 78 if count[0] % 1000 == 0: |
81 write('.') | 79 ui.write('.') |
82 count[0] += 1 | 80 count[0] += 1 |
83 | 81 |
84 order = [r1.node(r) for r in order] | 82 order = [r1.node(r) for r in order] |
85 | 83 |
86 # this is a bit ugly, but it works | 84 # this is a bit ugly, but it works |
90 try: | 88 try: |
91 group = util.chunkbuffer(r1.group(order, lookup, progress)) | 89 group = util.chunkbuffer(r1.group(order, lookup, progress)) |
92 chunkiter = changegroup.chunkiter(group) | 90 chunkiter = changegroup.chunkiter(group) |
93 r2.addgroup(chunkiter, unlookup, tr) | 91 r2.addgroup(chunkiter, unlookup, tr) |
94 finally: | 92 finally: |
95 write('\n') | 93 ui.write('\n') |
96 | 94 |
97 def report(olddatafn, newdatafn): | 95 def report(ui, olddatafn, newdatafn): |
98 oldsize = float(os.stat(olddatafn).st_size) | 96 oldsize = float(os.stat(olddatafn).st_size) |
99 newsize = float(os.stat(newdatafn).st_size) | 97 newsize = float(os.stat(newdatafn).st_size) |
100 | 98 |
101 # argh: have to pass an int to %d, because a float >= 2^32 | 99 # argh: have to pass an int to %d, because a float >= 2^32 |
102 # blows up under Python 2.5 or earlier | 100 # blows up under Python 2.5 or earlier |
103 sys.stdout.write('old file size: %12d bytes (%6.1f MiB)\n' | 101 ui.write('old file size: %12d bytes (%6.1f MiB)\n' |
104 % (int(oldsize), oldsize/1024/1024)) | 102 % (int(oldsize), oldsize/1024/1024)) |
105 sys.stdout.write('new file size: %12d bytes (%6.1f MiB)\n' | 103 ui.write('new file size: %12d bytes (%6.1f MiB)\n' |
106 % (int(newsize), newsize/1024/1024)) | 104 % (int(newsize), newsize/1024/1024)) |
107 | 105 |
108 shrink_percent = (oldsize - newsize) / oldsize * 100 | 106 shrink_percent = (oldsize - newsize) / oldsize * 100 |
109 shrink_factor = oldsize / newsize | 107 shrink_factor = oldsize / newsize |
110 sys.stdout.write('shrinkage: %.1f%% (%.1fx)\n' | 108 ui.write('shrinkage: %.1f%% (%.1fx)\n' % (shrink_percent, shrink_factor)) |
111 % (shrink_percent, shrink_factor)) | |
112 | 109 |
113 def main(): | 110 def main(): |
114 | 111 |
115 # Unbuffer stdout for nice progress output. | 112 # Unbuffer stdout for nice progress output. |
116 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) | 113 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) |
117 write = sys.stdout.write | |
118 | 114 |
119 parser = optparse.OptionParser(description=__doc__) | 115 parser = optparse.OptionParser(description=__doc__) |
120 parser.add_option('-R', '--repository', | 116 parser.add_option('-R', '--repository', |
121 default=os.path.curdir, | 117 default=os.path.curdir, |
122 metavar='REPO', | 118 metavar='REPO', |
166 ' %s\n' | 162 ' %s\n' |
167 'exists from a previous run; please clean up before ' | 163 'exists from a previous run; please clean up before ' |
168 'running again' | 164 'running again' |
169 % (oldindexfn, olddatafn)) | 165 % (oldindexfn, olddatafn)) |
170 | 166 |
171 write('shrinking %s\n' % indexfn) | 167 ui.write('shrinking %s\n' % indexfn) |
172 prefix = os.path.basename(indexfn)[:-1] | 168 prefix = os.path.basename(indexfn)[:-1] |
173 (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn), | 169 (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn), |
174 prefix=prefix, | 170 prefix=prefix, |
175 suffix='.i') | 171 suffix='.i') |
176 tmpdatafn = tmpindexfn[:-2] + '.d' | 172 tmpdatafn = tmpindexfn[:-2] + '.d' |
188 open, | 184 open, |
189 repo.sjoin('journal')) | 185 repo.sjoin('journal')) |
190 | 186 |
191 try: | 187 try: |
192 try: | 188 try: |
193 order = toposort(r1) | 189 order = toposort(ui, r1) |
194 writerevs(r1, r2, order, tr) | 190 writerevs(ui, r1, r2, order, tr) |
195 report(datafn, tmpdatafn) | 191 report(ui, datafn, tmpdatafn) |
196 tr.close() | 192 tr.close() |
197 except: | 193 except: |
198 # Abort transaction first, so we truncate the files before | 194 # Abort transaction first, so we truncate the files before |
199 # deleting them. | 195 # deleting them. |
200 tr.abort() | 196 tr.abort() |
208 | 204 |
209 os.link(indexfn, oldindexfn) | 205 os.link(indexfn, oldindexfn) |
210 os.link(datafn, olddatafn) | 206 os.link(datafn, olddatafn) |
211 os.rename(tmpindexfn, indexfn) | 207 os.rename(tmpindexfn, indexfn) |
212 os.rename(tmpdatafn, datafn) | 208 os.rename(tmpdatafn, datafn) |
213 write('note: old revlog saved in:\n' | 209 ui.write('note: old revlog saved in:\n' |
214 ' %s\n' | 210 ' %s\n' |
215 ' %s\n' | 211 ' %s\n' |
216 '(You can delete those files when you are satisfied that your\n' | 212 '(You can delete those files when you are satisfied that your\n' |
217 'repository is still sane. ' | 213 'repository is still sane. ' |
218 'Running \'hg verify\' is strongly recommended.)\n' | 214 'Running \'hg verify\' is strongly recommended.)\n' |