mirror of
https://github.com/pese-git/cherrypick.git
synced 2026-01-25 05:59:55 +00:00
perf(scope): speed up dependency lookup with Map-based binding resolver index
Optimize resolve()/tryResolve() to use O(1) Map-based lookup by type and name instead of iterating through all modules and bindings. Behavior of factory, singleton, instance, and named bindings is preserved.
This commit is contained in:
@@ -39,6 +39,10 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
|
|
||||||
final Set<Module> _modulesList = HashSet();
|
final Set<Module> _modulesList = HashSet();
|
||||||
|
|
||||||
|
// индекс для мгновенного поиска binding’ов
|
||||||
|
final Map<Object, Map<String?, BindingResolver>> _bindingResolvers = {};
|
||||||
|
|
||||||
|
|
||||||
/// RU: Генерирует уникальный идентификатор для скоупа.
|
/// RU: Генерирует уникальный идентификатор для скоупа.
|
||||||
/// ENG: Generates unique identifier for scope.
|
/// ENG: Generates unique identifier for scope.
|
||||||
String _generateScopeId() {
|
String _generateScopeId() {
|
||||||
@@ -96,6 +100,7 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
for (var module in modules) {
|
for (var module in modules) {
|
||||||
module.builder(this);
|
module.builder(this);
|
||||||
}
|
}
|
||||||
|
_rebuildResolversIndex();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,7 +112,7 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
Scope dropModules() {
|
Scope dropModules() {
|
||||||
// [AlexeyYuPopkov](https://github.com/AlexeyYuPopkov) Thank you for the [Removed exception "ConcurrentModificationError"](https://github.com/pese-git/cherrypick/pull/2)
|
// [AlexeyYuPopkov](https://github.com/AlexeyYuPopkov) Thank you for the [Removed exception "ConcurrentModificationError"](https://github.com/pese-git/cherrypick/pull/2)
|
||||||
_modulesList.clear();
|
_modulesList.clear();
|
||||||
|
_rebuildResolversIndex();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,16 +259,20 @@ class Scope with CycleDetectionMixin, GlobalCycleDetectionMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BindingResolver<T>? _findBindingResolver<T>(String? named) {
|
BindingResolver<T>? _findBindingResolver<T>(String? named) {
|
||||||
for (var module in _modulesList) {
|
final byType = _bindingResolvers[T];
|
||||||
for (var binding in module.bindingSet) {
|
if (byType == null) return null;
|
||||||
if (binding.key == T &&
|
return byType[named] as BindingResolver<T>?;
|
||||||
((!binding.isNamed && named == null) ||
|
|
||||||
(binding.isNamed && named == binding.name))) {
|
|
||||||
return binding.resolver as BindingResolver<T>?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
// Индексируем все binding’и после каждого installModules/dropModules
|
||||||
|
void _rebuildResolversIndex() {
|
||||||
|
_bindingResolvers.clear();
|
||||||
|
for (var module in _modulesList) {
|
||||||
|
for (var binding in module.bindingSet) {
|
||||||
|
_bindingResolvers.putIfAbsent(binding.key, () => {});
|
||||||
|
final nameKey = binding.isNamed ? binding.name : null;
|
||||||
|
_bindingResolvers[binding.key]![nameKey] = binding.resolver!;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user