[release-12.3.1] LibraryPanels: Improve getAllLibraryElements filter performance (#113601)

LibraryPanels: Improve `getAllLibraryElements` filter performance (#113544)

(cherry picked from commit 33390a1483)

Co-authored-by: Juan Cabanas <juan.cabanas@grafana.com>
This commit is contained in:
grafana-delivery-bot[bot]
2025-11-07 12:25:56 -03:00
committed by GitHub
co-authored by Juan Cabanas
parent 1cbbeee10b
commit d5d73bb189
2 changed files with 181 additions and 15 deletions
+24 -15
View File
@@ -473,17 +473,22 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
if err != nil {
return err
}
// Every signed in user can see the general folder. The general folder might have "general" or the empty string as its UID.
var folderUIDS = []string{"general", ""}
folderMap := map[string]string{}
// Using a map for O(1) lookup instead of O(n) slice iteration
folderUIDSet := make(map[string]bool, len(fs)+2)
folderUIDSet["general"] = true
folderUIDSet[""] = true
folderMap := make(map[string]string, len(fs))
for _, f := range fs {
folderUIDS = append(folderUIDS, f.UID)
folderUIDSet[f.UID] = true
folderMap[f.UID] = f.Title
}
// if the user is not an admin, we need to filter out elements that are not in folders the user can see
for _, element := range elements {
if !signedInUser.HasRole(org.RoleAdmin) {
if !contains(folderUIDS, element.FolderUID) {
if !folderUIDSet[element.FolderUID] {
continue
}
}
@@ -522,10 +527,11 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
})
}
var libraryElements []model.LibraryElement
var libraryElements []model.LibraryElementWithMeta
countBuilder := db.SQLBuilder{}
if folderFilter.includeGeneralFolder {
countBuilder.Write(selectLibraryElementDTOWithMeta)
countBuilder.Write(", '' as folder_uid ")
countBuilder.Write(getFromLibraryElementDTOWithMeta(l.SQLStore.GetDialect()))
countBuilder.Write(` WHERE le.org_id=? AND le.folder_id=0`, signedInUser.GetOrgID())
writeKindSQL(query, &countBuilder)
@@ -537,6 +543,7 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
countBuilder.Write(" ")
}
countBuilder.Write(selectLibraryElementDTOWithMeta)
countBuilder.Write(", le.folder_uid as folder_uid ")
countBuilder.Write(getFromLibraryElementDTOWithMeta(l.SQLStore.GetDialect()))
countBuilder.Write(` WHERE le.org_id=? AND le.folder_id<>0`, signedInUser.GetOrgID())
writeKindSQL(query, &countBuilder)
@@ -550,8 +557,19 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI
return err
}
// Apply the same folder permission filtering to the count for non-admin users
totalCount := int64(len(libraryElements))
if !signedInUser.HasRole(org.RoleAdmin) {
totalCount = 0
for _, element := range libraryElements {
if folderUIDSet[element.FolderUID] {
totalCount++
}
}
}
result = model.LibraryElementSearchResult{
TotalCount: int64(len(libraryElements)),
TotalCount: totalCount,
Elements: retDTOs,
Page: query.Page,
PerPage: query.PerPage,
@@ -878,15 +896,6 @@ func (l *LibraryElementService) deleteLibraryElementsInFolderUID(c context.Conte
})
}
func contains(slice []string, element string) bool {
for _, item := range slice {
if item == element {
return true
}
}
return false
}
func getFoldersWithMatchingTitles(c context.Context, l *LibraryElementService, signedInUser identity.Requester, query model.SearchLibraryElementsQuery) ([]string, error) {
if len(strings.TrimSpace(query.SearchString)) <= 0 {
return nil, nil