85 rlog = revlog.revlog(tvfs, name) |
85 rlog = revlog.revlog(tvfs, name) |
86 return rlog |
86 return rlog |
87 |
87 |
88 |
88 |
89 def appendrev(rlog, text, tr, isext=False, isdelta=True): |
89 def appendrev(rlog, text, tr, isext=False, isdelta=True): |
90 '''Append a revision. If isext is True, set the EXTSTORED flag so flag |
90 """Append a revision. If isext is True, set the EXTSTORED flag so flag |
91 processor will be used (and rawtext is different from text). If isdelta is |
91 processor will be used (and rawtext is different from text). If isdelta is |
92 True, force the revision to be a delta, otherwise it's full text. |
92 True, force the revision to be a delta, otherwise it's full text. |
93 ''' |
93 """ |
94 nextrev = len(rlog) |
94 nextrev = len(rlog) |
95 p1 = rlog.node(nextrev - 1) |
95 p1 = rlog.node(nextrev - 1) |
96 p2 = node.nullid |
96 p2 = node.nullid |
97 if isext: |
97 if isext: |
98 flags = revlog.REVIDX_EXTSTORED |
98 flags = revlog.REVIDX_EXTSTORED |
109 # Restore storedeltachains. It is always True, see revlog.__init__ |
109 # Restore storedeltachains. It is always True, see revlog.__init__ |
110 rlog._storedeltachains = True |
110 rlog._storedeltachains = True |
111 |
111 |
112 |
112 |
113 def addgroupcopy(rlog, tr, destname=b'_destrevlog.i', optimaldelta=True): |
113 def addgroupcopy(rlog, tr, destname=b'_destrevlog.i', optimaldelta=True): |
114 '''Copy revlog to destname using revlog.addgroup. Return the copied revlog. |
114 """Copy revlog to destname using revlog.addgroup. Return the copied revlog. |
115 |
115 |
116 This emulates push or pull. They use changegroup. Changegroup requires |
116 This emulates push or pull. They use changegroup. Changegroup requires |
117 repo to work. We don't have a repo, so a dummy changegroup is used. |
117 repo to work. We don't have a repo, so a dummy changegroup is used. |
118 |
118 |
119 If optimaldelta is True, use optimized delta parent, so the destination |
119 If optimaldelta is True, use optimized delta parent, so the destination |
120 revlog could probably reuse it. Otherwise it builds sub-optimal delta, and |
120 revlog could probably reuse it. Otherwise it builds sub-optimal delta, and |
121 the destination revlog needs more work to use it. |
121 the destination revlog needs more work to use it. |
122 |
122 |
123 This exercises some revlog.addgroup (and revlog._addrevision(text=None)) |
123 This exercises some revlog.addgroup (and revlog._addrevision(text=None)) |
124 code path, which is not covered by "appendrev" alone. |
124 code path, which is not covered by "appendrev" alone. |
125 ''' |
125 """ |
126 |
126 |
127 class dummychangegroup(object): |
127 class dummychangegroup(object): |
128 @staticmethod |
128 @staticmethod |
129 def deltachunk(pnode): |
129 def deltachunk(pnode): |
130 pnode = pnode or node.nullid |
130 pnode = pnode or node.nullid |
172 dlog.addgroup(dummydeltas, linkmap, tr) |
172 dlog.addgroup(dummydeltas, linkmap, tr) |
173 return dlog |
173 return dlog |
174 |
174 |
175 |
175 |
176 def lowlevelcopy(rlog, tr, destname=b'_destrevlog.i'): |
176 def lowlevelcopy(rlog, tr, destname=b'_destrevlog.i'): |
177 '''Like addgroupcopy, but use the low level revlog._addrevision directly. |
177 """Like addgroupcopy, but use the low level revlog._addrevision directly. |
178 |
178 |
179 It exercises some code paths that are hard to reach easily otherwise. |
179 It exercises some code paths that are hard to reach easily otherwise. |
180 ''' |
180 """ |
181 dlog = newrevlog(destname, recreate=True) |
181 dlog = newrevlog(destname, recreate=True) |
182 for r in rlog: |
182 for r in rlog: |
183 p1 = rlog.node(r - 1) |
183 p1 = rlog.node(r - 1) |
184 p2 = node.nullid |
184 p2 = node.nullid |
185 if r == 0 or (rlog.flags(r) & revlog.REVIDX_EXTSTORED): |
185 if r == 0 or (rlog.flags(r) & revlog.REVIDX_EXTSTORED): |
216 |
216 |
217 # Utilities to generate revisions for testing |
217 # Utilities to generate revisions for testing |
218 |
218 |
219 |
219 |
220 def genbits(n): |
220 def genbits(n): |
221 '''Given a number n, generate (2 ** (n * 2) + 1) numbers in range(2 ** n). |
221 """Given a number n, generate (2 ** (n * 2) + 1) numbers in range(2 ** n). |
222 i.e. the generated numbers have a width of n bits. |
222 i.e. the generated numbers have a width of n bits. |
223 |
223 |
224 The combination of two adjacent numbers will cover all possible cases. |
224 The combination of two adjacent numbers will cover all possible cases. |
225 That is to say, given any x, y where both x, and y are in range(2 ** n), |
225 That is to say, given any x, y where both x, and y are in range(2 ** n), |
226 there is an x followed immediately by y in the generated sequence. |
226 there is an x followed immediately by y in the generated sequence. |
227 ''' |
227 """ |
228 m = 2 ** n |
228 m = 2 ** n |
229 |
229 |
230 # Gray Code. See https://en.wikipedia.org/wiki/Gray_code |
230 # Gray Code. See https://en.wikipedia.org/wiki/Gray_code |
231 gray = lambda x: x ^ (x >> 1) |
231 gray = lambda x: x ^ (x >> 1) |
232 reversegray = {gray(i): i for i in range(m)} |
232 reversegray = {gray(i): i for i in range(m)} |
253 '''Given a revision number, generate dummy text''' |
253 '''Given a revision number, generate dummy text''' |
254 return b''.join(b'%d\n' % j for j in range(-1, rev % 5)) |
254 return b''.join(b'%d\n' % j for j in range(-1, rev % 5)) |
255 |
255 |
256 |
256 |
257 def writecases(rlog, tr): |
257 def writecases(rlog, tr): |
258 '''Write some revisions interested to the test. |
258 """Write some revisions interested to the test. |
259 |
259 |
260 The test is interested in 3 properties of a revision: |
260 The test is interested in 3 properties of a revision: |
261 |
261 |
262 - Is it a delta or a full text? (isdelta) |
262 - Is it a delta or a full text? (isdelta) |
263 This is to catch some delta application issues. |
263 This is to catch some delta application issues. |
279 |
279 |
280 Where "r.delta", "r.ext", and "r.empty" are booleans matching properties |
280 Where "r.delta", "r.ext", and "r.empty" are booleans matching properties |
281 mentioned above. |
281 mentioned above. |
282 |
282 |
283 Return expected [(text, rawtext)]. |
283 Return expected [(text, rawtext)]. |
284 ''' |
284 """ |
285 result = [] |
285 result = [] |
286 for i, x in enumerate(genbits(3)): |
286 for i, x in enumerate(genbits(3)): |
287 isdelta, isext, isempty = bool(x & 1), bool(x & 2), bool(x & 4) |
287 isdelta, isext, isempty = bool(x & 1), bool(x & 2), bool(x & 4) |
288 if isempty: |
288 if isempty: |
289 text = b'' |
289 text = b'' |