private void Free(Dictionary <string, List <int> > map) { if (map == null) { return; } foreach (var value in map.Values) { if (value == null) { continue; } SharedPools.BigDefault <List <int> >().ClearAndFree(value); } SharedPools.StringIgnoreCaseDictionary <List <int> >().ClearAndFree(map); }
private static Dictionary <string, List <int> > CreateIdentifierLocations(Document document, SyntaxNode root, CancellationToken cancellationToken) { var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); var identifierMap = SharedPools.StringIgnoreCaseDictionary <List <int> >().AllocateAndClear(); foreach (var token in root.DescendantTokens(descendIntoTrivia: true)) { if (token.IsMissing || token.Span.Length == 0) { continue; } if (syntaxFacts.IsIdentifier(token) || syntaxFacts.IsGlobalNamespaceKeyword(token)) { var valueText = token.ValueText; identifierMap.GetOrAdd(valueText, _ => SharedPools.BigDefault <List <int> >().AllocateAndClear()).Add(token.Span.Start); } } return(identifierMap); }
private bool WriteIdentifierLocations(int projectId, int documentId, Document document, VersionStamp version, SyntaxNode root, CancellationToken cancellationToken) { // delete any existing data if (!DeleteIdentifierLocations(projectId, documentId, cancellationToken)) { return(false); } var identifierMap = SharedPools.StringIgnoreCaseDictionary <int>().AllocateAndClear(); Dictionary <string, List <int> > map = null; try { map = CreateIdentifierLocations(document, root, cancellationToken); // okay, write new data using (var accessor = _esentStorage.GetIdentifierLocationTableAccessor()) { // make sure I have all identifier ready before starting big insertion int identifierId; foreach (var identifier in map.Keys) { if (!TryGetUniqueIdentifierId(identifier, out identifierId)) { return(false); } identifierMap[identifier] = identifierId; } // save whole map var uncommittedCount = 0; foreach (var kv in map) { cancellationToken.ThrowIfCancellationRequested(); var identifier = kv.Key; var positions = kv.Value; if ((uncommittedCount + positions.Count) > FlushThreshold) { accessor.Flush(); uncommittedCount = 0; } accessor.PrepareBatchOneInsert(); identifierId = identifierMap[identifier]; using (var stream = accessor.GetBatchInsertStream(projectId, documentId, identifierId)) using (var writer = new ObjectWriter(stream, cancellationToken: cancellationToken)) { writer.WriteString(IdentifierSetSerializationVersion); WriteList(writer, positions); } accessor.FinishBatchOneInsert(); uncommittedCount += positions.Count; } // save special identifier that indicates version for this document if (!TrySaveIdentifierSetVersion(accessor, projectId, documentId, version)) { return(false); } return(accessor.ApplyChanges()); } } finally { SharedPools.StringIgnoreCaseDictionary <int>().ClearAndFree(identifierMap); Free(map); } }