Cédric Champeau

Cache `DefaultModuleIdentifier` hash code

This hash code is used several times during dependency resolution. It's also worth

adding it to the `equals` method since we hit the `equals` path several times without

having visited `hashCode` before.

Avoid the creation of a string to build the path in the file store

This creates a significant amount of garbage. Assuming we read from the store

more often than we write to, this commit builds an array corresponding to the

path in the store, rather than a string.

Avoid the realization of local component project metadata when not needed

Don't create a composite artifact set

... if the configuration cannot be mutated, and that the configuration doesn't have

any parent then it's useless to create a composite, we can just return the existing,

own, artifact set.

Avoid creating a linked hash set for outgoing variants

In most cases there's only one child, so it's a waste of resources to

create a fully fledged linked hashset.

Avoid creating a linked hash set for outgoing variants

In most cases there's only one child, so it's a waste of resources to

create a fully fledged linked hashset.

Avoid creating multiple nodes for attributes when the value is a string coercing value

Equals/HashCode wasn't implemented for `CoercingStringValueSnapshot`, which lead to a growing

immutable attributes children table.

Don't use `getConfigDependencies` when setting attributes

This would cause the resolution of the dependencies, which we want to defer.

So instead of calling `getConfigDependencies`, we actually create a copy of

the configuration with a factory that will delegate to `getConfigDependencies`.

Don't use `getConfigDependencies` when setting attributes

This would cause the resolution of the dependencies, which we want to defer.

So instead of calling `getConfigDependencies`, we actually create a copy of

the configuration with a factory that will delegate to `getConfigDependencies`.

Don't use `getConfigDependencies` when setting attributes

This would cause the resolution of the dependencies, which we want to defer.

So instead of calling `getConfigDependencies`, we actually create a copy of

the configuration with a factory that will delegate to `getConfigDependencies`.

Don't use `getConfigDependencies` when setting attributes

This would cause the resolution of the dependencies, which we want to defer.

Avoid filtering dependencies when not necessary

Instead of setting the list of dependencies explicitly, set a factory that creates the list.

Avoid filtering dependencies when not necessary

Instead of setting the list of dependencies explicitly, set a factory that creates the list.

Avoid filtering dependencies when not necessary

Instead of setting the list of dependencies explicitly, set a factory that creates the list.

Lazily compute derived dependencies

Whenever we compute derived variants, we need to create new `ConfigurationMetadata`. Before, we used to compute

the dependencies of those derived metadata immediately, even if in practice there were a lot of chances that

they would only be needed on the selected variant. The only thing that we need to compute eagerly is the transformed

attributes. However, because attributes can be mutated by component metadata rules, we cannot create a lazy

wrapper on top of `ComponentMetadata`, so this commit bakes in the performance improvement directly to the

default configuration metadata class, which is now lazily computing a derived view of the dependencies based

on a enum corresponding to the different possible cases.

Lazily compute derived dependencies

Whenever we compute derived variants, we need to create new `ConfigurationMetadata`. Before, we used to compute

the dependencies of those derived metadata immediately, even if in practice there were a lot of chances that

they would only be needed on the selected variant. The only thing that we need to compute eagerly is the transformed

attributes. However, because attributes can be mutated by component metadata rules, we cannot create a lazy

wrapper on top of `ComponentMetadata`, so this commit bakes in the performance improvement directly to the

default configuration metadata class, which is now lazily computing a derived view of the dependencies based

on a enum corresponding to the different possible cases.

Lazily compute derived dependencies

Whenever we compute derived variants, we need to create new `ConfigurationMetadata`. Before, we used to compute

the dependencies of those derived metadata immediately, even if in practice there were a lot of chances that

they would only be needed on the selected variant. The only thing that we need to compute eagerly is the transformed

attributes. However, because attributes can be mutated by component metadata rules, we cannot create a lazy

wrapper on top of `ComponentMetadata`, so this commit bakes in the performance improvement directly to the

default configuration metadata class, which is now lazily computing a derived view of the dependencies based

on a enum corresponding to the different possible cases.

Fix incorrect dependency notation

Fix incorrect dependency notation

Fix incorrect dependency notation

Known packagings should be a set, because we always test for presence in the set

Known packagings should be a set, because we always test for presence in the set

Known packagings should be a set, because we always test for presence in the set

Known packagings should be a set, because we always test for presence in the set

Known packagings should be a set, because we always test for presence in the set

Optimize `filterDependencies` for the 1 and many cases

Optimize `filterDependencies` for the 1 and many cases

Optimize `filterDependencies` for the 1 and many cases

Optimize `filterDependencies` for the 1 and many cases

Optimize `filterDependencies` for the 1 and many cases