in src/scip-lib/partialloader/index.go [132:203]
func (p *PartialLoadedIndex) LoadIndex(indexPath string, indexReader scanner.ScipReader) error {
localPrefixTree := &SymbolPrefixTreeNode{
Children: make(map[model.Descriptor]*SymbolPrefixTreeNode),
}
localDocTreeNodes := make(map[string]*docNodes)
localUpdatedDocs := make(map[string]int64)
localDocToIndex := make(map[string]string)
localImplementorsBySymbol := make(map[string]map[string]struct{})
loadScanner := &scanner.IndexScannerImpl{
Pool: p.pool,
MatchSymbol: func(symbol []byte) bool {
return !scip.IsLocalSymbol(string(symbol))
},
MatchDocumentPath: func(indexDocPath string) bool {
docPath := filepath.Clean(indexDocPath)
localDocToIndex[docPath] = indexPath
if localDocTreeNodes[docPath] == nil {
localDocTreeNodes[docPath] = &docNodes{
nodes: make([]*SymbolPrefixTreeNode, 0),
revision: p.revision.Add(1),
}
}
localUpdatedDocs[docPath] = localDocTreeNodes[docPath].revision
p.loadedDocsMu.RLock()
_, docLoaded := p.LoadedDocuments[docPath]
p.loadedDocsMu.RUnlock()
return docLoaded // We should only load the document if it had already been loaded
},
VisitSymbol: func(indexDocPath string, info *scip.SymbolInformation) {
docPath := filepath.Clean(indexDocPath)
modelInfo := mapper.ScipSymbolInformationToModelSymbolInformation(info)
leafNode, isNew := localPrefixTree.AddSymbol(docPath, modelInfo, p.revision.Load())
// Populate reverse implementors for quick lookup (impl -> abs)
for _, rel := range modelInfo.Relationships {
if rel != nil && rel.IsImplementation {
abs := rel.Symbol
if localImplementorsBySymbol[abs] == nil {
localImplementorsBySymbol[abs] = make(map[string]struct{})
}
localImplementorsBySymbol[abs][modelInfo.Symbol] = struct{}{}
}
}
if isNew {
localDocTreeNodes[docPath].nodes = append(localDocTreeNodes[docPath].nodes, leafNode)
}
},
VisitDocument: func(doc *scip.Document) {
docPath := filepath.Clean(doc.RelativePath)
modelDoc := mapper.ScipDocumentToModelDocument(doc)
p.loadedDocsMu.Lock()
p.LoadedDocuments[docPath] = modelDoc
p.loadedDocsMu.Unlock()
p.onDocumentLoaded(modelDoc)
},
}
loadScanner.InitBuffers()
defer func() {
p.modificationMu.Lock()
defer p.modificationMu.Unlock()
p.mergePrefixTree(localPrefixTree)
p.mergeDocTreeNodes(localDocTreeNodes)
p.mergeUpdatedDocs(localUpdatedDocs)
p.mergeDocToIndex(localDocToIndex)
p.mergeImplementors(localImplementorsBySymbol)
}()
return loadScanner.ScanIndexReader(indexReader)
}