Rework exclude rule merging
As a follow-up to #9197, this commit properly fixes the
exclude rule merging algorithm, by completely rewriting… Show more
As a follow-up to #9197, this commit properly fixes the
exclude rule merging algorithm, by completely rewriting… Show more
Rework exclude rule mergingAs a follow-up to #9197, this commit properly fixes theexclude rule merging algorithm, by completely rewritingit. The new merging algorithm works by implementing theminimal set of algebra operations that make sense tominimize computation durations. In order to do this,this commit introduces a number of exclude specs(found in their own package) and factories to createactual implementation of those specs.Specs represent the different kind of excludes we canfind:- excluding a group- excluding a module (no group defined)- excluding a group+module- excluding an artifact of a group+module- pattern-matching excludes- unions of excludes- intersections of excludesWith all those minimal bricks, factories are responsibleof generating consistent specs. The dumbest factorywill just generate new instances for everything. Thisis the default factory.Minimally, this factory has to be backed by an optimizingfactory, which will take care of handling special cases:- union or intersection of a single spec- union or intersection of 2 specs - when one of them is null - when both are equalThen we have a factory which performs the minimal algebrato minimize specs:- unions of unions- intersections of intersections- union of a union and individual specs- insection of an intersection and individual spec- ...This factory can be as smart as it can, but one must becareful that it's worth it: some previously implementedoptimizations (like (A+B).A = A turned out to be costlyto detect, and didn't make it the final cut.Yet another factory is there to reduce the memory footprintand, as a side effect, make things faster by interningthe specs: equivalent specs are interned and indexed, whichallows us to optimize unions and intersections of specs.Last but not least, a caching factory is there to avoidrecomputing the same intersections and unions of specswhen we have already done the job. This is efficient ifthe underlying (delegate) specs are easily compared,which is the case thanks to the interning factory.All in all, the delegation chain allows us to makethe algorithm fast and hopefully reliable, whilemaking it easier to debug.
Show less