42 FORMAT_VARIANT = b'deficiency' |
42 FORMAT_VARIANT = b'deficiency' |
43 OPTIMISATION = b'optimization' |
43 OPTIMISATION = b'optimization' |
44 |
44 |
45 |
45 |
46 class improvement(object): |
46 class improvement(object): |
47 """Represents an improvement that can be made as part of an upgrade. |
47 """Represents an improvement that can be made as part of an upgrade.""" |
48 |
48 |
49 The following attributes are defined on each instance: |
49 ### The following attributes should be defined for each subclass: |
50 |
50 |
51 name |
51 # Either ``FORMAT_VARIANT`` or ``OPTIMISATION``. |
52 Machine-readable string uniquely identifying this improvement. It |
52 # A format variant is where we change the storage format. Not all format |
53 will be mapped to an action later in the upgrade process. |
53 # variant changes are an obvious problem. |
54 |
54 # An optimization is an action (sometimes optional) that |
55 type |
55 # can be taken to further improve the state of the repository. |
56 Either ``FORMAT_VARIANT`` or ``OPTIMISATION``. |
56 type = None |
57 A format variant is where we change the storage format. Not all format |
|
58 variant changes are an obvious problem. |
|
59 An optimization is an action (sometimes optional) that |
|
60 can be taken to further improve the state of the repository. |
|
61 |
|
62 description |
|
63 Message intended for humans explaining the improvement in more detail, |
|
64 including the implications of it. For ``FORMAT_VARIANT`` types, should be |
|
65 worded in the present tense. For ``OPTIMISATION`` types, should be |
|
66 worded in the future tense. |
|
67 |
|
68 upgrademessage |
|
69 Message intended for humans explaining what an upgrade addressing this |
|
70 issue will do. Should be worded in the future tense. |
|
71 |
|
72 postupgrademessage |
|
73 Message intended for humans which will be shown post an upgrade |
|
74 operation when the improvement will be added |
|
75 |
|
76 postdowngrademessage |
|
77 Message intended for humans which will be shown post an upgrade |
|
78 operation in which this improvement was removed |
|
79 |
|
80 touches_filelogs (bool) |
|
81 Whether this improvement touches filelogs |
|
82 |
|
83 touches_manifests (bool) |
|
84 Whether this improvement touches manifests |
|
85 |
|
86 touches_changelog (bool) |
|
87 Whether this improvement touches changelog |
|
88 |
|
89 touches_requirements (bool) |
|
90 Whether this improvement changes repository requirements |
|
91 """ |
|
92 |
|
93 def __init__(self, name, type, description, upgrademessage): |
|
94 self.name = name |
|
95 self.type = type |
|
96 self.description = description |
|
97 self.upgrademessage = upgrademessage |
|
98 self.postupgrademessage = None |
|
99 self.postdowngrademessage = None |
|
100 # By default for now, we assume every improvement touches |
|
101 # all the things |
|
102 self.touches_filelogs = True |
|
103 self.touches_manifests = True |
|
104 self.touches_changelog = True |
|
105 self.touches_requirements = True |
|
106 |
|
107 def __eq__(self, other): |
|
108 if not isinstance(other, improvement): |
|
109 # This is what python tell use to do |
|
110 return NotImplemented |
|
111 return self.name == other.name |
|
112 |
|
113 def __ne__(self, other): |
|
114 return not (self == other) |
|
115 |
|
116 def __hash__(self): |
|
117 return hash(self.name) |
|
118 |
|
119 |
|
120 allformatvariant = [] # type: List[Type['formatvariant']] |
|
121 |
|
122 |
|
123 def registerformatvariant(cls): |
|
124 allformatvariant.append(cls) |
|
125 return cls |
|
126 |
|
127 |
|
128 class formatvariant(improvement): |
|
129 """an improvement subclass dedicated to repository format""" |
|
130 |
|
131 type = FORMAT_VARIANT |
|
132 ### The following attributes should be defined for each class: |
|
133 |
57 |
134 # machine-readable string uniquely identifying this improvement. it will be |
58 # machine-readable string uniquely identifying this improvement. it will be |
135 # mapped to an action later in the upgrade process. |
59 # mapped to an action later in the upgrade process. |
136 name = None |
60 name = None |
137 |
61 |
155 # Message intended for humans which will be shown post an upgrade |
79 # Message intended for humans which will be shown post an upgrade |
156 # operation in which this improvement was removed |
80 # operation in which this improvement was removed |
157 postdowngrademessage = None |
81 postdowngrademessage = None |
158 |
82 |
159 # By default for now, we assume every improvement touches all the things |
83 # By default for now, we assume every improvement touches all the things |
|
84 |
|
85 # Whether this improvement touches filelogs |
160 touches_filelogs = True |
86 touches_filelogs = True |
|
87 |
|
88 # Whether this improvement touches manifests |
161 touches_manifests = True |
89 touches_manifests = True |
|
90 |
|
91 # Whether this improvement touches changelog |
162 touches_changelog = True |
92 touches_changelog = True |
|
93 |
|
94 # Whether this improvement changes repository requirements |
163 touches_requirements = True |
95 touches_requirements = True |
164 |
96 |
165 def __init__(self): |
97 |
166 raise NotImplementedError() |
98 allformatvariant = [] # type: List[Type['formatvariant']] |
|
99 |
|
100 |
|
101 def registerformatvariant(cls): |
|
102 allformatvariant.append(cls) |
|
103 return cls |
|
104 |
|
105 |
|
106 class formatvariant(improvement): |
|
107 """an improvement subclass dedicated to repository format""" |
|
108 |
|
109 type = FORMAT_VARIANT |
167 |
110 |
168 @staticmethod |
111 @staticmethod |
169 def fromrepo(repo): |
112 def fromrepo(repo): |
170 """current value of the variant in the repository""" |
113 """current value of the variant in the repository""" |
171 raise NotImplementedError() |
114 raise NotImplementedError() |
543 def register_optimization(obj): |
486 def register_optimization(obj): |
544 ALL_OPTIMISATIONS.append(obj) |
487 ALL_OPTIMISATIONS.append(obj) |
545 return obj |
488 return obj |
546 |
489 |
547 |
490 |
548 register_optimization( |
491 class optimization(improvement): |
549 improvement( |
492 """an improvement subclass dedicated to optimizations""" |
550 name=b're-delta-parent', |
493 |
551 type=OPTIMISATION, |
494 type = OPTIMISATION |
552 description=_( |
495 |
553 b'deltas within internal storage will be recalculated to ' |
496 |
554 b'choose an optimal base revision where this was not ' |
497 @register_optimization |
555 b'already done; the size of the repository may shrink and ' |
498 class redeltaparents(optimization): |
556 b'various operations may become faster; the first time ' |
499 name = b're-delta-parent' |
557 b'this optimization is performed could slow down upgrade ' |
500 |
558 b'execution considerably; subsequent invocations should ' |
501 type = OPTIMISATION |
559 b'not run noticeably slower' |
502 |
560 ), |
503 description = _( |
561 upgrademessage=_( |
504 b'deltas within internal storage will be recalculated to ' |
562 b'deltas within internal storage will choose a new ' |
505 b'choose an optimal base revision where this was not ' |
563 b'base revision if needed' |
506 b'already done; the size of the repository may shrink and ' |
564 ), |
507 b'various operations may become faster; the first time ' |
565 ) |
508 b'this optimization is performed could slow down upgrade ' |
566 ) |
509 b'execution considerably; subsequent invocations should ' |
567 |
510 b'not run noticeably slower' |
568 register_optimization( |
511 ) |
569 improvement( |
512 |
570 name=b're-delta-multibase', |
513 upgrademessage = _( |
571 type=OPTIMISATION, |
514 b'deltas within internal storage will choose a new ' |
572 description=_( |
515 b'base revision if needed' |
573 b'deltas within internal storage will be recalculated ' |
516 ) |
574 b'against multiple base revision and the smallest ' |
517 |
575 b'difference will be used; the size of the repository may ' |
518 |
576 b'shrink significantly when there are many merges; this ' |
519 @register_optimization |
577 b'optimization will slow down execution in proportion to ' |
520 class redeltamultibase(optimization): |
578 b'the number of merges in the repository and the amount ' |
521 name = b're-delta-multibase' |
579 b'of files in the repository; this slow down should not ' |
522 |
580 b'be significant unless there are tens of thousands of ' |
523 type = OPTIMISATION |
581 b'files and thousands of merges' |
524 |
582 ), |
525 description = _( |
583 upgrademessage=_( |
526 b'deltas within internal storage will be recalculated ' |
584 b'deltas within internal storage will choose an ' |
527 b'against multiple base revision and the smallest ' |
585 b'optimal delta by computing deltas against multiple ' |
528 b'difference will be used; the size of the repository may ' |
586 b'parents; may slow down execution time ' |
529 b'shrink significantly when there are many merges; this ' |
587 b'significantly' |
530 b'optimization will slow down execution in proportion to ' |
588 ), |
531 b'the number of merges in the repository and the amount ' |
589 ) |
532 b'of files in the repository; this slow down should not ' |
590 ) |
533 b'be significant unless there are tens of thousands of ' |
591 |
534 b'files and thousands of merges' |
592 register_optimization( |
535 ) |
593 improvement( |
536 |
594 name=b're-delta-all', |
537 upgrademessage = _( |
595 type=OPTIMISATION, |
538 b'deltas within internal storage will choose an ' |
596 description=_( |
539 b'optimal delta by computing deltas against multiple ' |
597 b'deltas within internal storage will always be ' |
540 b'parents; may slow down execution time ' |
598 b'recalculated without reusing prior deltas; this will ' |
541 b'significantly' |
599 b'likely make execution run several times slower; this ' |
542 ) |
600 b'optimization is typically not needed' |
543 |
601 ), |
544 |
602 upgrademessage=_( |
545 @register_optimization |
603 b'deltas within internal storage will be fully ' |
546 class redeltaall(optimization): |
604 b'recomputed; this will likely drastically slow down ' |
547 name = b're-delta-all' |
605 b'execution time' |
548 |
606 ), |
549 type = OPTIMISATION |
607 ) |
550 |
608 ) |
551 description = _( |
609 |
552 b'deltas within internal storage will always be ' |
610 register_optimization( |
553 b'recalculated without reusing prior deltas; this will ' |
611 improvement( |
554 b'likely make execution run several times slower; this ' |
612 name=b're-delta-fulladd', |
555 b'optimization is typically not needed' |
613 type=OPTIMISATION, |
556 ) |
614 description=_( |
557 |
615 b'every revision will be re-added as if it was new ' |
558 upgrademessage = _( |
616 b'content. It will go through the full storage ' |
559 b'deltas within internal storage will be fully ' |
617 b'mechanism giving extensions a chance to process it ' |
560 b'recomputed; this will likely drastically slow down ' |
618 b'(eg. lfs). This is similar to "re-delta-all" but even ' |
561 b'execution time' |
619 b'slower since more logic is involved.' |
562 ) |
620 ), |
563 |
621 upgrademessage=_( |
564 |
622 b'each revision will be added as new content to the ' |
565 @register_optimization |
623 b'internal storage; this will likely drastically slow ' |
566 class redeltafulladd(optimization): |
624 b'down execution time, but some extensions might need ' |
567 name = b're-delta-fulladd' |
625 b'it' |
568 |
626 ), |
569 type = OPTIMISATION |
627 ) |
570 |
628 ) |
571 description = _( |
|
572 b'every revision will be re-added as if it was new ' |
|
573 b'content. It will go through the full storage ' |
|
574 b'mechanism giving extensions a chance to process it ' |
|
575 b'(eg. lfs). This is similar to "re-delta-all" but even ' |
|
576 b'slower since more logic is involved.' |
|
577 ) |
|
578 |
|
579 upgrademessage = _( |
|
580 b'each revision will be added as new content to the ' |
|
581 b'internal storage; this will likely drastically slow ' |
|
582 b'down execution time, but some extensions might need ' |
|
583 b'it' |
|
584 ) |
629 |
585 |
630 |
586 |
631 def findoptimizations(repo): |
587 def findoptimizations(repo): |
632 """Determine optimisation that could be used during upgrade""" |
588 """Determine optimisation that could be used during upgrade""" |
633 # These are unconditionally added. There is logic later that figures out |
589 # These are unconditionally added. There is logic later that figures out |