diff --git a/fastmap/fastmap.go b/fastmap/fastmap.go index aaee166..0d24c95 100644 --- a/fastmap/fastmap.go +++ b/fastmap/fastmap.go @@ -4,6 +4,8 @@ import ( "fmt" "strings" + "slices" + "github.com/goccy/go-json" ) @@ -87,6 +89,19 @@ func (m *Fastmap[K, V]) Iter(fn func(key K, value V) bool) { } } +func (m *Fastmap[K, V]) StableSortByKey() { + slices.SortStableFunc(m.store, func(a, b fastmapValue[K, V]) int { + aKey := fmt.Sprint(a.Key) + bKey := fmt.Sprint(b.Key) + return strings.Compare(aKey, bKey) + }) + + // Update the index map after sorting + for i, v := range m.store { + m.idx[v.Key] = i + } +} + func (m *Fastmap[K, V]) MarshalText() ([]byte, error) { var builder strings.Builder for _, v := range m.store { diff --git a/handlers/packages/packages.go b/handlers/packages/packages.go index 603c91d..c4eed24 100644 --- a/handlers/packages/packages.go +++ b/handlers/packages/packages.go @@ -6,7 +6,6 @@ import ( "brunel/helpers" "brunel/packages" "fmt" - "sort" "strings" "github.com/gofiber/fiber/v2" @@ -36,30 +35,9 @@ func Packages(c *fiber.Ctx) error { packs := packages.GetPackages() - // Convert map to slice for sorting - packSlice := make([]struct { - Key string - Value domain.SourcePackage - }, 0, packs.Len()) - - packs.Iter(func(k string, v domain.SourcePackage) bool { - packSlice = append(packSlice, struct { - Key string - Value domain.SourcePackage - }{k, v}) - return true - }) - - // Stable sort the slice - sort.SliceStable(packSlice, func(i, j int) bool { - return packSlice[i].Key < packSlice[j].Key - }) - finalReturn := fastmap.New[string, domain.SourcePackage]() - for _, item := range packSlice { - k, source := item.Key, item.Value - + packs.Iter(func(k string, source domain.SourcePackage) bool { matchesFilter := filter == "" matchesSearch := search == "" || strings.Contains(strings.ToLower(k), search) @@ -70,13 +48,14 @@ func Packages(c *fiber.Ctx) error { if !matchesSearch && strings.Contains(strings.ToLower(key), search) { matchesSearch = true } - return !(matchesFilter && matchesSearch) // stop iterating if we've found matches for both + return !(matchesFilter && matchesSearch) }) if matchesFilter && matchesSearch { finalReturn.Set(k, source) } - } + return true + }) result := finalReturn.GetPage(adjustedPageNum, pageSize) diff --git a/packages/packages.go b/packages/packages.go index 9a8be3b..5425e2a 100644 --- a/packages/packages.go +++ b/packages/packages.go @@ -44,6 +44,7 @@ func ProcessPackages() error { currentPackagesFastMap.Set(k, v) return true }) + currentPackagesFastMap.StableSortByKey() LastUpdateTime = time.Now() helpers.ReloadCache() @@ -129,6 +130,7 @@ func LoadFromDb() error { for _, pkg := range packages { currentPackagesFastMap.Set(pkg.Name, pkg) } + currentPackagesFastMap.StableSortByKey() return nil }