comparison mercurial/utils/storageutil.py @ 47095:223b47235d1c

sidedata: enable sidedata computers to optionally rewrite flags Sidedata computers may want to influence the flags of the revision they touch. For example, the computer for changelog-based copytracing can add a flag to signify that this revision might affect copytracing, inversely removing said flag if the information is no longer applicable. See inline documentation in `storageutil` for more details. Differential Revision: https://phab.mercurial-scm.org/D10344
author Rapha?l Gom?s <rgomes@octobus.net>
date Thu, 08 Apr 2021 16:55:17 +0200
parents 119790e1c67c
children 3aab2330b7d3
comparison
equal deleted inserted replaced
47094:119790e1c67c 47095:223b47235d1c
364 ``assumehaveparentrevisions`` 364 ``assumehaveparentrevisions``
365 ``sidedata_helpers`` (optional) 365 ``sidedata_helpers`` (optional)
366 If not None, means that sidedata should be included. 366 If not None, means that sidedata should be included.
367 A dictionary of revlog type to tuples of `(repo, computers, removers)`: 367 A dictionary of revlog type to tuples of `(repo, computers, removers)`:
368 * `repo` is used as an argument for computers 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 compute the missing sidedata categories that were asked: 370 compute the missing sidedata categories that were asked:
371 * `category` is the sidedata category 371 * `category` is the sidedata category
372 * `keys` are the sidedata keys to be affected 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 * `computer` is the function `(repo, store, rev, sidedata)` that 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 * `removers` will remove the keys corresponding to the categories 380 * `removers` will remove the keys corresponding to the categories
376 that are present, but not needed. 381 that are present, but not needed.
377 If both `computers` and `removers` are empty, sidedata are simply not 382 If both `computers` and `removers` are empty, sidedata are simply not
378 transformed. 383 transformed.
379 Revlog types are `changelog`, `manifest` or `filelog`. 384 Revlog types are `changelog`, `manifest` or `filelog`.
489 ) 494 )
490 495
491 available.add(rev) 496 available.add(rev)
492 497
493 serialized_sidedata = None 498 serialized_sidedata = None
499 sidedata_flags = (0, 0)
494 if sidedata_helpers: 500 if sidedata_helpers:
495 sidedata = store.sidedata(rev) 501 old_sidedata = store.sidedata(rev)
496 sidedata = run_sidedata_helpers( 502 sidedata, sidedata_flags = run_sidedata_helpers(
497 store=store, 503 store=store,
498 sidedata_helpers=sidedata_helpers, 504 sidedata_helpers=sidedata_helpers,
499 sidedata=sidedata, 505 sidedata=old_sidedata,
500 rev=rev, 506 rev=rev,
501 ) 507 )
502 if sidedata: 508 if sidedata:
503 serialized_sidedata = sidedatamod.serialize_sidedata(sidedata) 509 serialized_sidedata = sidedatamod.serialize_sidedata(sidedata)
504 510
505 flags = flagsfn(rev) if flagsfn else 0 511 flags = flagsfn(rev) if flagsfn else 0
506 protocol_flags = 0 512 protocol_flags = 0
507 if serialized_sidedata: 513 if serialized_sidedata:
508 # Advertise that sidedata exists to the other side 514 # Advertise that sidedata exists to the other side
509 protocol_flags |= CG_FLAG_SIDEDATA 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 yield resultcls( 519 yield resultcls(
512 node=node, 520 node=node,
513 p1node=fnode(p1rev), 521 p1node=fnode(p1rev),
514 p2node=fnode(p2rev), 522 p2node=fnode(p2rev),
533 - `sidedata`: previous sidedata at the given rev, if any 541 - `sidedata`: previous sidedata at the given rev, if any
534 - `rev`: affected rev of `store` 542 - `rev`: affected rev of `store`
535 """ 543 """
536 repo, sd_computers, sd_removers = sidedata_helpers 544 repo, sd_computers, sd_removers = sidedata_helpers
537 kind = store.revlog_kind 545 kind = store.revlog_kind
538 for _keys, sd_computer in sd_computers.get(kind, []): 546 flags_to_add = 0
539 sidedata = sd_computer(repo, store, rev, sidedata) 547 flags_to_remove = 0
540 for keys, _computer in sd_removers.get(kind, []): 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 for key in keys: 553 for key in keys:
542 sidedata.pop(key, None) 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 def deltaiscensored(delta, baserev, baselenfn): 559 def deltaiscensored(delta, baserev, baselenfn):
547 """Determine if a delta represents censored revision data. 560 """Determine if a delta represents censored revision data.
548 561