##// END OF EJS Templates
sidedata: enable sidedata computers to optionally rewrite flags...
Raphaël Gomès -
r47844:223b4723 default
parent child Browse files
Show More
@@ -503,14 +503,14 b' static PyObject *index_append(indexObjec'
503 503 inside the transaction that creates the given revision. */
504 504 static PyObject *index_replace_sidedata_info(indexObject *self, PyObject *args)
505 505 {
506 uint64_t sidedata_offset;
506 uint64_t offset_flags, sidedata_offset;
507 507 int rev;
508 508 Py_ssize_t sidedata_comp_len;
509 509 char *data;
510 510 #if LONG_MAX == 0x7fffffffL
511 const char *const sidedata_format = PY23("nKi", "nKi");
511 const char *const sidedata_format = PY23("nKiK", "nKiK");
512 512 #else
513 const char *const sidedata_format = PY23("nki", "nki");
513 const char *const sidedata_format = PY23("nkik", "nkik");
514 514 #endif
515 515
516 516 if (self->hdrsize == v1_hdrsize || self->inlined) {
@@ -525,7 +525,7 b' static PyObject *index_replace_sidedata_'
525 525 }
526 526
527 527 if (!PyArg_ParseTuple(args, sidedata_format, &rev, &sidedata_offset,
528 &sidedata_comp_len))
528 &sidedata_comp_len, &offset_flags))
529 529 return NULL;
530 530
531 531 if (rev < 0 || rev >= index_length(self)) {
@@ -542,6 +542,7 b' static PyObject *index_replace_sidedata_'
542 542 /* Find the newly added node, offset from the "already on-disk" length
543 543 */
544 544 data = self->added + self->hdrsize * (rev - self->length);
545 putbe64(offset_flags, data);
545 546 putbe64(sidedata_offset, data + 64);
546 547 putbe32(sidedata_comp_len, data + 72);
547 548
@@ -1856,7 +1856,7 b' class ilocalrepositorymain(interfaceutil'
1856 1856 def savecommitmessage(text):
1857 1857 pass
1858 1858
1859 def register_sidedata_computer(kind, category, keys, computer):
1859 def register_sidedata_computer(kind, category, keys, computer, flags):
1860 1860 pass
1861 1861
1862 1862 def register_wanted_sidedata(category):
@@ -3370,9 +3370,9 b' class localrepository(object):'
3370 3370 return
3371 3371 self._wanted_sidedata.add(pycompat.bytestr(category))
3372 3372
3373 def register_sidedata_computer(self, kind, category, keys, computer):
3373 def register_sidedata_computer(self, kind, category, keys, computer, flags):
3374 3374 if kind not in revlogconst.ALL_KINDS:
3375 msg = _(b"unexpected revlog kind %r.")
3375 msg = _(b"unexpected revlog kind '%s'.")
3376 3376 raise error.ProgrammingError(msg % kind)
3377 3377 category = pycompat.bytestr(category)
3378 3378 if category in self._sidedata_computers.get(kind, []):
@@ -3381,7 +3381,7 b' class localrepository(object):'
3381 3381 )
3382 3382 raise error.ProgrammingError(msg % category)
3383 3383 self._sidedata_computers.setdefault(kind, {})
3384 self._sidedata_computers[kind][category] = (keys, computer)
3384 self._sidedata_computers[kind][category] = (keys, computer, flags)
3385 3385
3386 3386
3387 3387 # used to avoid circular references so destructors work
@@ -820,7 +820,9 b' def _getsidedata(srcrepo, rev):'
820 820
821 821
822 822 def copies_sidedata_computer(repo, revlog, rev, existing_sidedata):
823 return _getsidedata(repo, rev)[0]
823 sidedata, has_copies_info = _getsidedata(repo, rev)
824 flags_to_add = sidedataflag.REVIDX_HASCOPIESINFO if has_copies_info else 0
825 return sidedata, (flags_to_add, 0)
824 826
825 827
826 828 def set_sidedata_spec_for_repo(repo):
@@ -831,6 +833,7 b' def set_sidedata_spec_for_repo(repo):'
831 833 sidedatamod.SD_FILES,
832 834 (sidedatamod.SD_FILES,),
833 835 copies_sidedata_computer,
836 sidedataflag.REVIDX_HASCOPIESINFO,
834 837 )
835 838
836 839
@@ -268,7 +268,9 b' class Index2Mixin(object):'
268 268 index_format = revlog_constants.INDEX_ENTRY_V2
269 269 null_item = (0, 0, 0, -1, -1, -1, -1, sha1nodeconstants.nullid, 0, 0)
270 270
271 def replace_sidedata_info(self, i, sidedata_offset, sidedata_length):
271 def replace_sidedata_info(
272 self, i, sidedata_offset, sidedata_length, offset_flags
273 ):
272 274 """
273 275 Replace an existing index entry's sidedata offset and length with new
274 276 ones.
@@ -283,7 +285,8 b' class Index2Mixin(object):'
283 285 if i >= self._lgt:
284 286 packed = _pack(sidedata_format, sidedata_offset, sidedata_length)
285 287 old = self._extra[i - self._lgt]
286 new = old[:64] + packed + old[64 + packed_size :]
288 offset_flags = struct.pack(b">Q", offset_flags)
289 new = offset_flags + old[8:64] + packed + old[64 + packed_size :]
287 290 self._extra[i - self._lgt] = new
288 291 else:
289 292 msg = b"cannot rewrite entries outside of this transaction"
@@ -3105,7 +3105,7 b' class revlog(object):'
3105 3105 current_offset = fp.tell()
3106 3106 for rev in range(startrev, endrev + 1):
3107 3107 entry = self.index[rev]
3108 new_sidedata = storageutil.run_sidedata_helpers(
3108 new_sidedata, flags = storageutil.run_sidedata_helpers(
3109 3109 store=self,
3110 3110 sidedata_helpers=helpers,
3111 3111 sidedata={},
@@ -3121,7 +3121,11 b' class revlog(object):'
3121 3121 # revlog.
3122 3122 msg = b"Rewriting existing sidedata is not supported yet"
3123 3123 raise error.Abort(msg)
3124 entry = entry[:8]
3124
3125 # Apply (potential) flags to add and to remove after running
3126 # the sidedata helpers
3127 new_offset_flags = entry[0] | flags[0] & ~flags[1]
3128 entry = (new_offset_flags,) + entry[1:8]
3125 3129 entry += (current_offset, len(serialized_sidedata))
3126 3130
3127 3131 fp.write(serialized_sidedata)
@@ -3131,9 +3135,9 b' class revlog(object):'
3131 3135 # rewrite the new index entries
3132 3136 with self._indexfp(b'w+') as fp:
3133 3137 fp.seek(startrev * self.index.entry_size)
3134 for i, entry in enumerate(new_entries):
3138 for i, e in enumerate(new_entries):
3135 3139 rev = startrev + i
3136 self.index.replace_sidedata_info(rev, entry[8], entry[9])
3140 self.index.replace_sidedata_info(rev, e[8], e[9], e[0])
3137 3141 packed = self.index.entry_binary(rev)
3138 3142 if rev == 0:
3139 3143 header = self.index.pack_header(self.version)
@@ -366,12 +366,17 b' def emitrevisions('
366 366 If not None, means that sidedata should be included.
367 367 A dictionary of revlog type to tuples of `(repo, computers, removers)`:
368 368 * `repo` is used as an argument for computers
369 * `computers` is a list of `(category, (keys, computer)` that
369 * `computers` is a list of `(category, (keys, computer, flags)` that
370 370 compute the missing sidedata categories that were asked:
371 371 * `category` is the sidedata category
372 372 * `keys` are the sidedata keys to be affected
373 * `flags` is a bitmask (an integer) of flags to remove when
374 removing the category.
373 375 * `computer` is the function `(repo, store, rev, sidedata)` that
374 returns a new sidedata dict.
376 returns a tuple of
377 `(new sidedata dict, (flags to add, flags to remove))`.
378 For example, it will return `({}, (0, 1 << 15))` to return no
379 sidedata, with no flags to add and one flag to remove.
375 380 * `removers` will remove the keys corresponding to the categories
376 381 that are present, but not needed.
377 382 If both `computers` and `removers` are empty, sidedata are simply not
@@ -491,12 +496,13 b' def emitrevisions('
491 496 available.add(rev)
492 497
493 498 serialized_sidedata = None
499 sidedata_flags = (0, 0)
494 500 if sidedata_helpers:
495 sidedata = store.sidedata(rev)
496 sidedata = run_sidedata_helpers(
501 old_sidedata = store.sidedata(rev)
502 sidedata, sidedata_flags = run_sidedata_helpers(
497 503 store=store,
498 504 sidedata_helpers=sidedata_helpers,
499 sidedata=sidedata,
505 sidedata=old_sidedata,
500 506 rev=rev,
501 507 )
502 508 if sidedata:
@@ -507,6 +513,8 b' def emitrevisions('
507 513 if serialized_sidedata:
508 514 # Advertise that sidedata exists to the other side
509 515 protocol_flags |= CG_FLAG_SIDEDATA
516 # Computers and removers can return flags to add and/or remove
517 flags = flags | sidedata_flags[0] & ~sidedata_flags[1]
510 518
511 519 yield resultcls(
512 520 node=node,
@@ -535,12 +543,17 b' def run_sidedata_helpers(store, sidedata'
535 543 """
536 544 repo, sd_computers, sd_removers = sidedata_helpers
537 545 kind = store.revlog_kind
538 for _keys, sd_computer in sd_computers.get(kind, []):
539 sidedata = sd_computer(repo, store, rev, sidedata)
540 for keys, _computer in sd_removers.get(kind, []):
546 flags_to_add = 0
547 flags_to_remove = 0
548 for _keys, sd_computer, _flags in sd_computers.get(kind, []):
549 sidedata, flags = sd_computer(repo, store, rev, sidedata)
550 flags_to_add |= flags[0]
551 flags_to_remove |= flags[1]
552 for keys, _computer, flags in sd_removers.get(kind, []):
541 553 for key in keys:
542 554 sidedata.pop(key, None)
543 return sidedata
555 flags_to_remove |= flags
556 return sidedata, (flags_to_add, flags_to_remove)
544 557
545 558
546 559 def deltaiscensored(delta, baserev, baselenfn):
@@ -16,13 +16,15 b' import struct'
16 16 from mercurial.revlogutils import sidedata as sidedatamod
17 17 from mercurial.revlogutils import constants
18 18
19 NO_FLAGS = (0, 0) # hoot
20
19 21
20 22 def compute_sidedata_1(repo, revlog, rev, sidedata, text=None):
21 23 sidedata = sidedata.copy()
22 24 if text is None:
23 25 text = revlog.revision(rev)
24 26 sidedata[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
25 return sidedata
27 return sidedata, NO_FLAGS
26 28
27 29
28 30 def compute_sidedata_2(repo, revlog, rev, sidedata, text=None):
@@ -31,7 +33,7 b' def compute_sidedata_2(repo, revlog, rev'
31 33 text = revlog.revision(rev)
32 34 sha256 = hashlib.sha256(text).digest()
33 35 sidedata[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
34 return sidedata
36 return sidedata, NO_FLAGS
35 37
36 38
37 39 def reposetup(ui, repo):
@@ -42,10 +44,12 b' def reposetup(ui, repo):'
42 44 sidedatamod.SD_TEST1,
43 45 (sidedatamod.SD_TEST1,),
44 46 compute_sidedata_1,
47 0,
45 48 )
46 49 repo.register_sidedata_computer(
47 50 kind,
48 51 sidedatamod.SD_TEST2,
49 52 (sidedatamod.SD_TEST2,),
50 53 compute_sidedata_2,
54 0,
51 55 )
@@ -22,13 +22,15 b' from mercurial import ('
22 22 from mercurial.revlogutils import sidedata as sidedatamod
23 23 from mercurial.revlogutils import constants
24 24
25 NO_FLAGS = (0, 0)
26
25 27
26 28 def compute_sidedata_1(repo, revlog, rev, sidedata, text=None):
27 29 sidedata = sidedata.copy()
28 30 if text is None:
29 31 text = revlog.revision(rev)
30 32 sidedata[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
31 return sidedata
33 return sidedata, NO_FLAGS
32 34
33 35
34 36 def compute_sidedata_2(repo, revlog, rev, sidedata, text=None):
@@ -37,7 +39,7 b' def compute_sidedata_2(repo, revlog, rev'
37 39 text = revlog.revision(rev)
38 40 sha256 = hashlib.sha256(text).digest()
39 41 sidedata[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
40 return sidedata
42 return sidedata, NO_FLAGS
41 43
42 44
43 45 def compute_sidedata_3(repo, revlog, rev, sidedata, text=None):
@@ -46,7 +48,7 b' def compute_sidedata_3(repo, revlog, rev'
46 48 text = revlog.revision(rev)
47 49 sha384 = hashlib.sha384(text).digest()
48 50 sidedata[sidedatamod.SD_TEST3] = struct.pack('>48s', sha384)
49 return sidedata
51 return sidedata, NO_FLAGS
50 52
51 53
52 54 def wrapaddrevision(
@@ -55,8 +57,8 b' def wrapaddrevision('
55 57 if kwargs.get('sidedata') is None:
56 58 kwargs['sidedata'] = {}
57 59 sd = kwargs['sidedata']
58 sd = compute_sidedata_1(None, self, None, sd, text=text)
59 kwargs['sidedata'] = compute_sidedata_2(None, self, None, sd, text=text)
60 sd, flags = compute_sidedata_1(None, self, None, sd, text=text)
61 kwargs['sidedata'] = compute_sidedata_2(None, self, None, sd, text=text)[0]
60 62 return orig(self, text, transaction, link, p1, p2, *args, **kwargs)
61 63
62 64
@@ -72,18 +74,21 b' def reposetup(ui, repo):'
72 74 sidedatamod.SD_TEST1,
73 75 (sidedatamod.SD_TEST1,),
74 76 compute_sidedata_1,
77 0,
75 78 )
76 79 repo.register_sidedata_computer(
77 80 kind,
78 81 sidedatamod.SD_TEST2,
79 82 (sidedatamod.SD_TEST2,),
80 83 compute_sidedata_2,
84 0,
81 85 )
82 86 repo.register_sidedata_computer(
83 87 kind,
84 88 sidedatamod.SD_TEST3,
85 89 (sidedatamod.SD_TEST3,),
86 90 compute_sidedata_3,
91 0,
87 92 )
88 93 repo.register_wanted_sidedata(sidedatamod.SD_TEST1)
89 94 repo.register_wanted_sidedata(sidedatamod.SD_TEST2)
@@ -23,13 +23,15 b' from mercurial import ('
23 23 from mercurial.revlogutils import sidedata as sidedatamod
24 24 from mercurial.revlogutils import constants
25 25
26 NO_FLAGS = (0, 0)
27
26 28
27 29 def compute_sidedata_1(repo, revlog, rev, sidedata, text=None):
28 30 sidedata = sidedata.copy()
29 31 if text is None:
30 32 text = revlog.revision(rev)
31 33 sidedata[sidedatamod.SD_TEST1] = struct.pack('>I', len(text))
32 return sidedata
34 return sidedata, NO_FLAGS
33 35
34 36
35 37 def compute_sidedata_2(repo, revlog, rev, sidedata, text=None):
@@ -38,7 +40,7 b' def compute_sidedata_2(repo, revlog, rev'
38 40 text = revlog.revision(rev)
39 41 sha256 = hashlib.sha256(text).digest()
40 42 sidedata[sidedatamod.SD_TEST2] = struct.pack('>32s', sha256)
41 return sidedata
43 return sidedata, NO_FLAGS
42 44
43 45
44 46 def reposetup(ui, repo):
@@ -49,12 +51,14 b' def reposetup(ui, repo):'
49 51 sidedatamod.SD_TEST1,
50 52 (sidedatamod.SD_TEST1,),
51 53 compute_sidedata_1,
54 0,
52 55 )
53 56 repo.register_sidedata_computer(
54 57 kind,
55 58 sidedatamod.SD_TEST2,
56 59 (sidedatamod.SD_TEST2,),
57 60 compute_sidedata_2,
61 0,
58 62 )
59 63
60 64 # We don't register sidedata computers because we don't care within these
General Comments 0
You need to be logged in to leave comments. Login now