Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(213)

Unified Diff: pkg/analysis_server/lib/src/services/index/store/split_store.dart

Issue 1359023002: Extract Dart specific node management into DartUnitIndexObjectManager. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/lib/src/services/index/store/split_store.dart
diff --git a/pkg/analysis_server/lib/src/services/index/store/split_store.dart b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
index 8d94d740adb63dd3b424b6263a85224f644683d2..a66b2710c9d48c33e0042275759836c8fe3c8ed9 100644
--- a/pkg/analysis_server/lib/src/services/index/store/split_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
@@ -22,6 +22,190 @@ import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
/**
+ * The implementation of [IndexObjectManager] for indexing
+ * [CompilationUnitElement]s.
+ */
+class DartUnitIndexObjectManager extends IndexObjectManager {
+ /**
+ * The mapping of library [Source] to the [Source]s of part units.
+ */
+ Map<AnalysisContext, Map<Source, Set<Source>>> _contextToLibraryToUnits =
+ new HashMap<AnalysisContext, Map<Source, Set<Source>>>();
+
+ /**
+ * The mapping of unit [Source] to the [Source]s of libraries it is used in.
+ */
+ Map<AnalysisContext, Map<Source, Set<Source>>> _contextToUnitToLibraries =
+ new HashMap<AnalysisContext, Map<Source, Set<Source>>>();
+
+ @override
+ String aboutToIndex(AnalysisContext context, Object object) {
+ // may be already disposed in other thread
Brian Wilkerson 2015/09/22 19:22:37 nit: Minimally, the comment is out of date, given
+ if (context.isDisposed) {
+ return null;
+ }
+ // validate object
+ if (object is! CompilationUnitElement) {
+ return null;
+ }
+ CompilationUnitElement unitElement = object;
+ // validate unit
+ if (unitElement == null) {
+ return null;
+ }
+ LibraryElement libraryElement = unitElement.library;
+ if (libraryElement == null) {
+ return null;
+ }
+ CompilationUnitElement definingUnitElement =
+ libraryElement.definingCompilationUnit;
+ if (definingUnitElement == null) {
+ return null;
+ }
+ // prepare sources
+ Source library = definingUnitElement.source;
+ Source unit = unitElement.source;
+ // special handling for the defining library unit
+ if (unit == library) {
+ // prepare new parts
+ HashSet<Source> newParts = new HashSet<Source>();
+ for (CompilationUnitElement part in libraryElement.parts) {
+ newParts.add(part.source);
+ }
+ // prepare old parts
+ Map<Source, Set<Source>> libraryToUnits =
+ _contextToLibraryToUnits[context];
+ if (libraryToUnits == null) {
+ libraryToUnits = new HashMap<Source, Set<Source>>();
+ _contextToLibraryToUnits[context] = libraryToUnits;
+ }
+ Set<Source> oldParts = libraryToUnits[library];
+ // check if some parts are not in the library now
+ if (oldParts != null) {
+ Set<Source> noParts = oldParts.difference(newParts);
+ for (Source noPart in noParts) {
+ String nodeName = _getNodeName(library, noPart);
+ site.removeNodeByName(context, nodeName);
+ site.removeSource(library);
+ site.removeSource(noPart);
+ }
+ }
+ // remember new parts
+ libraryToUnits[library] = newParts;
+ }
+ // remember library/unit relations
+ _recordUnitInLibrary(context, library, unit);
+ _recordLibraryWithUnit(context, library, unit);
+ site.addSource(library);
+ site.addSource(unit);
+ // prepare node
+ String nodeName = _getNodeName(library, unit);
+ return nodeName;
+ }
+
+ @override
+ void removeContext(AnalysisContext context) {
+ _contextToLibraryToUnits.remove(context);
+ _contextToUnitToLibraries.remove(context);
+ }
+
+ @override
+ void removeSource(AnalysisContext context, Source source) {
+ // remove nodes for unit/library pairs
+ Map<Source, Set<Source>> unitToLibraries =
+ _contextToUnitToLibraries[context];
+ if (unitToLibraries != null) {
+ Set<Source> libraries = unitToLibraries.remove(source);
+ if (libraries != null) {
+ for (Source library in libraries) {
+ String nodeName = _getNodeName(library, source);
+ site.removeNodeByName(context, nodeName);
+ site.removeSource(library);
+ site.removeSource(source);
+ }
+ }
+ }
+ // remove nodes for library/unit pairs
+ Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
+ if (libraryToUnits != null) {
+ Set<Source> units = libraryToUnits.remove(source);
+ if (units != null) {
+ for (Source unit in units) {
+ String nodeName = _getNodeName(source, unit);
+ site.removeNodeByName(context, nodeName);
+ site.removeSource(source);
+ site.removeSource(unit);
+ }
+ }
+ }
+ }
+
+ @override
+ void removeSources(AnalysisContext context, SourceContainer container) {
+ // remove nodes for unit/library pairs
+ Map<Source, Set<Source>> unitToLibraries =
+ _contextToUnitToLibraries[context];
+ if (unitToLibraries != null) {
+ List<Source> units = unitToLibraries.keys.toList();
+ for (Source source in units) {
+ if (container == null || container.contains(source)) {
+ removeSource(context, source);
+ }
+ }
+ }
+ // remove nodes for library/unit pairs
+ Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
+ if (libraryToUnits != null) {
+ List<Source> libraries = libraryToUnits.keys.toList();
+ for (Source source in libraries) {
+ if (container == null || container.contains(source)) {
+ removeSource(context, source);
+ }
+ }
+ }
+ }
+
+ String _getNodeName(Source library, Source unit) {
+ String libraryName = library != null ? library.fullName : null;
+ String unitName = unit.fullName;
+ int libraryNameIndex = site.encodeString(libraryName);
+ int unitNameIndex = site.encodeString(unitName);
+ return 'DartUnitElement_${libraryNameIndex}_${unitNameIndex}.index';
+ }
+
+ void _recordLibraryWithUnit(
+ AnalysisContext context, Source library, Source unit) {
+ Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
+ if (libraryToUnits == null) {
+ libraryToUnits = new HashMap<Source, Set<Source>>();
+ _contextToLibraryToUnits[context] = libraryToUnits;
+ }
+ Set<Source> units = libraryToUnits[library];
+ if (units == null) {
+ units = new HashSet<Source>();
+ libraryToUnits[library] = units;
+ }
+ units.add(unit);
+ }
+
+ void _recordUnitInLibrary(
+ AnalysisContext context, Source library, Source unit) {
+ Map<Source, Set<Source>> unitToLibraries =
+ _contextToUnitToLibraries[context];
+ if (unitToLibraries == null) {
+ unitToLibraries = new HashMap<Source, Set<Source>>();
+ _contextToUnitToLibraries[context] = unitToLibraries;
+ }
+ Set<Source> libraries = unitToLibraries[unit];
+ if (libraries == null) {
+ libraries = new HashSet<Source>();
+ unitToLibraries[unit] = libraries;
+ }
+ libraries.add(library);
+ }
+}
+
+/**
* A manager for files content.
*/
abstract class FileManager {
@@ -341,6 +525,36 @@ class IndexNode {
}
}
+/**
+ * [SplitIndexStore] uses instances of this class to manager index nodes.
+ */
+abstract class IndexObjectManager {
+ SplitIndexStoreSite site;
+
+ /**
+ * Notifies the manager that the given [object] is to be indexed.
+ * Returns the name of the index node to put information into.
+ */
+ String aboutToIndex(AnalysisContext context, Object object);
+
+ /**
+ * Notifies the manager that the given [context] is disposed.
+ */
+ void removeContext(AnalysisContext context);
+
+ /**
+ * Notifies the manager that the given [source] is no longer part of
+ * the given [context].
+ */
+ void removeSource(AnalysisContext context, Source source);
+
+ /**
+ * Notifies the manager that the sources described by the given [container]
+ * are no longer part of the given [context].
+ */
+ void removeSources(AnalysisContext context, SourceContainer container);
+}
+
class InspectLocation {
final String nodeName;
final RelationshipImpl relationship;
@@ -526,70 +740,62 @@ class RelationKeyData {
*/
class SplitIndexStore implements InternalIndexStore {
/**
- * The [ContextCodec] to encode/decode [AnalysisContext]s.
+ * The [NodeManager] to get/put [IndexNode]s.
*/
- ContextCodec _contextCodec;
+ final NodeManager _nodeManager;
+
+ final List<IndexObjectManager> _objectManagers;
/**
- * Information about top-level elements.
- * We need to keep them together to avoid loading of all index nodes.
- *
- * Order of keys: contextId, nodeId.
+ * The [ContextCodec] to encode/decode [AnalysisContext]s.
*/
- Map<int, Map<int, List<_TopElementData>>> _topDeclarations =
- new Map<int, Map<int, List<_TopElementData>>>();
+ final ContextCodec _contextCodec;
/**
- * The mapping of library [Source] to the [Source]s of part units.
+ * The [ElementCodec] to encode/decode [Element]s.
*/
- Map<AnalysisContext, Map<Source, Set<Source>>> _contextToLibraryToUnits =
- new HashMap<AnalysisContext, Map<Source, Set<Source>>>();
+ final ElementCodec _elementCodec;
/**
- * The mapping of unit [Source] to the [Source]s of libraries it is used in.
+ * The [StringCodec] to encode/decode [String]s.
*/
- Map<AnalysisContext, Map<Source, Set<Source>>> _contextToUnitToLibraries =
- new HashMap<AnalysisContext, Map<Source, Set<Source>>>();
-
- int _currentContextId = 0;
-
- IndexNode _currentNode;
-
- String _currentNodeName;
-
- int _currentNodeNameId = 0;
+ final StringCodec _stringCodec;
/**
- * The [ElementCodec] to encode/decode [Element]s.
+ * Information about top-level elements.
+ * We need to keep them together to avoid loading of all index nodes.
+ *
+ * Order of keys: contextId, nodeId.
*/
- ElementCodec _elementCodec;
+ final Map<int, Map<int, List<_TopElementData>>> _topDeclarations =
+ new Map<int, Map<int, List<_TopElementData>>>();
+
+ int _currentContextId;
+ String _currentNodeName;
+ int _currentNodeNameId;
+ IndexNode _currentNode;
/**
* A table mapping element names to the node names that may have relations with elements with
* these names.
*/
- Map<RelationshipImpl, IntToIntSetMap> _relToNameMap =
+ final Map<RelationshipImpl, IntToIntSetMap> _relToNameMap =
new HashMap<RelationshipImpl, IntToIntSetMap>();
/**
- * The [NodeManager] to get/put [IndexNode]s.
- */
- final NodeManager _nodeManager;
-
- /**
* The set of known [Source]s.
*/
- Set<Source> _sources = new HashSet<Source>();
-
- /**
- * The [StringCodec] to encode/decode [String]s.
- */
- StringCodec _stringCodec;
-
- SplitIndexStore(this._nodeManager) {
- this._contextCodec = _nodeManager.contextCodec;
- this._elementCodec = _nodeManager.elementCodec;
- this._stringCodec = _nodeManager.stringCodec;
+ final Set<Source> _sources = new HashSet<Source>();
+
+ SplitIndexStore(NodeManager _nodeManager, this._objectManagers)
+ : _nodeManager = _nodeManager,
+ _contextCodec = _nodeManager.contextCodec,
+ _elementCodec = _nodeManager.elementCodec,
+ _stringCodec = _nodeManager.stringCodec {
+ SplitIndexStoreSiteImpl site = new SplitIndexStoreSiteImpl(this);
+ for (IndexObjectManager manager in _objectManagers) {
+ manager.site = site;
+ }
}
@override
@@ -608,64 +814,23 @@ class SplitIndexStore implements InternalIndexStore {
}
@override
- bool aboutToIndexDart(
- AnalysisContext context, CompilationUnitElement unitElement) {
+ bool aboutToIndex(AnalysisContext context, Object object) {
// may be already disposed in other thread
if (context.isDisposed) {
return false;
}
- // validate unit
- if (unitElement == null) {
- return false;
+ // try to find a node name
+ _currentNodeName = null;
+ for (IndexObjectManager manager in _objectManagers) {
+ _currentNodeName = manager.aboutToIndex(context, object);
+ if (_currentNodeName != null) {
+ break;
+ }
}
- LibraryElement libraryElement = unitElement.library;
- if (libraryElement == null) {
+ if (_currentNodeName == null) {
return false;
}
- CompilationUnitElement definingUnitElement =
- libraryElement.definingCompilationUnit;
- if (definingUnitElement == null) {
- return false;
- }
- // prepare sources
- Source library = definingUnitElement.source;
- Source unit = unitElement.source;
- // special handling for the defining library unit
- if (unit == library) {
- // prepare new parts
- HashSet<Source> newParts = new HashSet<Source>();
- for (CompilationUnitElement part in libraryElement.parts) {
- newParts.add(part.source);
- }
- // prepare old parts
- Map<Source, Set<Source>> libraryToUnits =
- _contextToLibraryToUnits[context];
- if (libraryToUnits == null) {
- libraryToUnits = new HashMap<Source, Set<Source>>();
- _contextToLibraryToUnits[context] = libraryToUnits;
- }
- Set<Source> oldParts = libraryToUnits[library];
- // check if some parts are not in the library now
- if (oldParts != null) {
- Set<Source> noParts = oldParts.difference(newParts);
- for (Source noPart in noParts) {
- _removeLocations(context, library, noPart);
- }
- }
- // remember new parts
- libraryToUnits[library] = newParts;
- }
- // remember library/unit relations
- _recordUnitInLibrary(context, library, unit);
- _recordLibraryWithUnit(context, library, unit);
- _sources.add(library);
- _sources.add(unit);
// prepare node
- String libraryName = library.fullName;
- String unitName = unit.fullName;
- int libraryNameIndex = _stringCodec.encode(libraryName);
- int unitNameIndex = _stringCodec.encode(unitName);
- _currentNodeName = '${libraryNameIndex}_${unitNameIndex}.index';
_currentNodeNameId = _stringCodec.encode(_currentNodeName);
_currentNode = _nodeManager.newNode(context);
_currentContextId = _contextCodec.encode(context);
@@ -678,27 +843,7 @@ class SplitIndexStore implements InternalIndexStore {
}
@override
- bool aboutToIndexHtml(AnalysisContext context, HtmlElement htmlElement) {
- // may be already disposed in other thread
- if (context.isDisposed) {
- return false;
- }
- // remove locations
- Source source = htmlElement.source;
- _removeLocations(context, null, source);
- // remember library/unit relations
- _recordUnitInLibrary(context, null, source);
- // prepare node
- String sourceName = source.fullName;
- int sourceNameIndex = _stringCodec.encode(sourceName);
- _currentNodeName = '${sourceNameIndex}.index';
- _currentNodeNameId = _stringCodec.encode(_currentNodeName);
- _currentNode = _nodeManager.newNode(context);
- return true;
- }
-
- @override
- void cancelIndexDart() {
+ void cancelIndex() {
if (_currentNode != null) {
// remove top-level information for the current node
for (Map<int, dynamic> nodeRelations in _topDeclarations.values) {
@@ -875,8 +1020,9 @@ class SplitIndexStore implements InternalIndexStore {
// remove sources
removeSources(context, null);
// remove context information
- _contextToLibraryToUnits.remove(context);
- _contextToUnitToLibraries.remove(context);
+ for (IndexObjectManager manager in _objectManagers) {
+ manager.removeContext(context);
+ }
_topDeclarations.remove(_contextCodec.encode(context));
// remove context from codec
_contextCodec.remove(context);
@@ -887,26 +1033,8 @@ class SplitIndexStore implements InternalIndexStore {
if (context == null) {
return;
}
- // remove nodes for unit/library pairs
- Map<Source, Set<Source>> unitToLibraries =
- _contextToUnitToLibraries[context];
- if (unitToLibraries != null) {
- Set<Source> libraries = unitToLibraries.remove(source);
- if (libraries != null) {
- for (Source library in libraries) {
- _removeLocations(context, library, source);
- }
- }
- }
- // remove nodes for library/unit pairs
- Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
- if (libraryToUnits != null) {
- Set<Source> units = libraryToUnits.remove(source);
- if (units != null) {
- for (Source unit in units) {
- _removeLocations(context, source, unit);
- }
- }
+ for (IndexObjectManager manager in _objectManagers) {
+ manager.removeSource(context, source);
}
}
@@ -915,44 +1043,11 @@ class SplitIndexStore implements InternalIndexStore {
if (context == null) {
return;
}
- // remove nodes for unit/library pairs
- Map<Source, Set<Source>> unitToLibraries =
- _contextToUnitToLibraries[context];
- if (unitToLibraries != null) {
- List<Source> units = new List<Source>.from(unitToLibraries.keys);
- for (Source source in units) {
- if (container == null || container.contains(source)) {
- removeSource(context, source);
- }
- }
- }
- // remove nodes for library/unit pairs
- Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
- if (libraryToUnits != null) {
- List<Source> libraries = new List<Source>.from(libraryToUnits.keys);
- for (Source source in libraries) {
- if (container == null || container.contains(source)) {
- removeSource(context, source);
- }
- }
+ for (IndexObjectManager manager in _objectManagers) {
+ manager.removeSources(context, container);
}
}
- void _recordLibraryWithUnit(
- AnalysisContext context, Source library, Source unit) {
- Map<Source, Set<Source>> libraryToUnits = _contextToLibraryToUnits[context];
- if (libraryToUnits == null) {
- libraryToUnits = new HashMap<Source, Set<Source>>();
- _contextToLibraryToUnits[context] = libraryToUnits;
- }
- Set<Source> units = libraryToUnits[library];
- if (units == null) {
- units = new HashSet<Source>();
- libraryToUnits[library] = units;
- }
- units.add(unit);
- }
-
void _recordNodeNameForElement(
IndexableObject indexable, RelationshipImpl relationship) {
IntToIntSetMap nameToNodeNames = _relToNameMap[relationship];
@@ -964,37 +1059,9 @@ class SplitIndexStore implements InternalIndexStore {
nameToNodeNames.add(nameId, _currentNodeNameId);
}
- void _recordUnitInLibrary(
- AnalysisContext context, Source library, Source unit) {
- Map<Source, Set<Source>> unitToLibraries =
- _contextToUnitToLibraries[context];
- if (unitToLibraries == null) {
- unitToLibraries = new HashMap<Source, Set<Source>>();
- _contextToUnitToLibraries[context] = unitToLibraries;
- }
- Set<Source> libraries = unitToLibraries[unit];
- if (libraries == null) {
- libraries = new HashSet<Source>();
- unitToLibraries[unit] = libraries;
- }
- libraries.add(library);
- }
-
- /**
- * Removes locations recorded in the given library/unit pair.
- */
- void _removeLocations(AnalysisContext context, Source library, Source unit) {
- // remove node
- String libraryName = library != null ? library.fullName : null;
- String unitName = unit.fullName;
- int libraryNameIndex = _stringCodec.encode(libraryName);
- int unitNameIndex = _stringCodec.encode(unitName);
- String nodeName = '${libraryNameIndex}_${unitNameIndex}.index';
+ void _removeNodeByName(AnalysisContext context, String nodeName) {
int nodeNameId = _stringCodec.encode(nodeName);
_nodeManager.removeNode(nodeName);
- // remove source
- _sources.remove(library);
- _sources.remove(unit);
// remove top-level relations
{
int contextId = _contextCodec.encode(context);
@@ -1006,6 +1073,45 @@ class SplitIndexStore implements InternalIndexStore {
}
}
+/**
+ * Interface to [SplitIndexStore] for [IndexObjectManager] implementations.
+ */
+abstract class SplitIndexStoreSite {
+ void addSource(Source source);
+ int encodeString(String str);
+ void removeNodeByName(AnalysisContext context, String nodeName);
+ void removeSource(Source source);
+}
+
+/**
+ * The implementaiton of [SplitIndexStoreSite].
+ */
+class SplitIndexStoreSiteImpl implements SplitIndexStoreSite {
+ final SplitIndexStore store;
+
+ SplitIndexStoreSiteImpl(this.store);
+
+ @override
+ void addSource(Source source) {
+ store._sources.add(source);
+ }
+
+ @override
+ int encodeString(String str) {
+ return store._stringCodec.encode(str);
+ }
+
+ @override
+ void removeNodeByName(AnalysisContext context, String nodeName) {
+ store._removeNodeByName(context, nodeName);
+ }
+
+ @override
+ void removeSource(Source source) {
+ store._sources.remove(source);
+ }
+}
+
class _DataInputStream {
ByteData _byteData;
int _byteOffset = 0;

Powered by Google App Engine
This is Rietveld 408576698