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.
47 lines
1.7 KiB
Diff
47 lines
1.7 KiB
Diff
--- a/models/asymkey/ssh_key.go
|
|
+++ b/models/asymkey/ssh_key.go
|
|
@@ -378,19 +378,22 @@ func synchronizePublicKeys(ctx context.Context, s *auth.Source, usr *user_model.
|
|
// Process the provided keys to remove duplicates and name part
|
|
- var providedKeys []string
|
|
+ providedKeysSet := make(map[string]struct{})
|
|
+ var providedKeys []string
|
|
for _, v := range sshPublicKeys {
|
|
sshKeySplit := strings.Split(v, " ")
|
|
if len(sshKeySplit) > 1 {
|
|
key := strings.Join(sshKeySplit[:2], " ")
|
|
- if !util.SliceContainsString(providedKeys, key) {
|
|
+ if _, exists := providedKeysSet[key]; !exists {
|
|
+ providedKeysSet[key] = struct{}{}
|
|
providedKeys = append(providedKeys, key)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if Public Key sync is needed
|
|
@@ -399,14 +402,16 @@ func synchronizePublicKeys(ctx context.Context, s *auth.Source, usr *user_model.
|
|
|
|
// Add new Public SSH Keys that doesn't already exist in DB
|
|
+ giteaKeysSet := make(map[string]struct{}, len(giteaKeys))
|
|
+ for _, k := range giteaKeys {
|
|
+ giteaKeysSet[k] = struct{}{}
|
|
+ }
|
|
var newKeys []string
|
|
for _, key := range providedKeys {
|
|
- if !util.SliceContainsString(giteaKeys, key) {
|
|
+ if _, exists := giteaKeysSet[key]; !exists {
|
|
newKeys = append(newKeys, key)
|
|
}
|
|
}
|
|
if AddPublicKeysBySource(ctx, usr, s, newKeys) {
|
|
sshKeysNeedUpdate = true
|
|
}
|
|
|
|
// Mark keys from DB that no longer exist in the source for deletion
|
|
var giteaKeysToDelete []string
|
|
for _, giteaKey := range giteaKeys {
|
|
- if !util.SliceContainsString(providedKeys, giteaKey) {
|
|
+ if _, exists := providedKeysSet[giteaKey]; !exists {
|
|
log.Trace("synchronizePublicKeys[%s]: Marking Public SSH Key for deletion for user %s: %v", s.Name, usr.Name, giteaKey)
|
|
giteaKeysToDelete = append(giteaKeysToDelete, giteaKey)
|
|
}
|
|
}
|