langchain-0001: MultiVectorRetriever._get_relevant_documents() dedup IDs from vectorstore sub_docs uses list.contains() inside loop, O(k^2). k is unbounded in production RAG pipelines (configurable via search_kwargs). Fix: track seen IDs in a set, keep list for order. 499.5x at k=1000. forgejo-0002: LoadRepoConfig() license sort O(P*L) where L=776 licenses. Two SliceContainsString calls in back-to-back loops iterate full license list for each preferred license and vice versa. Fix: build lookup sets before loops. 19.5x at P=20 preferred licenses. forgejo-0003: synchronizePublicKeys() three O(N*M) scans per LDAP sync. Dedup of providedKeys is O(K^2), plus two O(P*G) set-difference loops. Runs per user per sync cycle. Fix: use maps for O(1) membership. 178.6x at K=G=500. forgejo-0001 (search.go RepoIDs) already patched in prior scan. MOADs 0002-0005 CLEAN for both targets.
32 lines
1.5 KiB
Diff
32 lines
1.5 KiB
Diff
--- a/libs/langchain/langchain_classic/retrievers/multi_vector.py
|
|
+++ b/libs/langchain/langchain_classic/retrievers/multi_vector.py
|
|
@@ -105,9 +105,10 @@ class MultiVectorRetriever(BaseRetriever):
|
|
sub_docs = self.vectorstore.similarity_search(query, **self.search_kwargs)
|
|
|
|
# We do this to maintain the order of the IDs that are returned
|
|
- ids = []
|
|
+ seen_ids: set = set()
|
|
+ ids = []
|
|
for d in sub_docs:
|
|
- if self.id_key in d.metadata and d.metadata[self.id_key] not in ids:
|
|
+ if self.id_key in d.metadata and d.metadata[self.id_key] not in seen_ids:
|
|
+ seen_ids.add(d.metadata[self.id_key])
|
|
ids.append(d.metadata[self.id_key])
|
|
docs = self.docstore.mget(ids)
|
|
return [d for d in docs if d is not None]
|
|
@@ -147,9 +148,10 @@ class MultiVectorRetriever(BaseRetriever):
|
|
sub_docs = await self.vectorstore.asimilarity_search(
|
|
query, **self.search_kwargs
|
|
)
|
|
|
|
# We do this to maintain the order of the IDs that are returned
|
|
- ids = []
|
|
+ seen_ids_async: set = set()
|
|
+ ids = []
|
|
for d in sub_docs:
|
|
- if self.id_key in d.metadata and d.metadata[self.id_key] not in ids:
|
|
+ if self.id_key in d.metadata and d.metadata[self.id_key] not in seen_ids_async:
|
|
+ seen_ids_async.add(d.metadata[self.id_key])
|
|
ids.append(d.metadata[self.id_key])
|
|
docs = await self.docstore.amget(ids)
|
|
return [d for d in docs if d is not None]
|