@@ -4,8 +4,11 @@ import (
44 "container/heap"
55)
66
7+ // TopObjects is a slice of ObjectMetadata pointers that implements the heap.Interface
8+ // for maintaining a priority queue of objects, typically sorted by size.
79type TopObjects []* ObjectMetadata
810
11+ // NewTopObjects creates and returns a new, empty TopObjects slice with a specified capacity.
912func NewTopObjects (n int ) TopObjects {
1013 if n < 1 {
1114 n = 1
@@ -14,34 +17,51 @@ func NewTopObjects(n int) TopObjects {
1417 return make (TopObjects , 0 , n )
1518}
1619
20+ // Len returns the number of elements in the TopObjects slice.
1721func (to TopObjects ) Len () int { return len (to ) }
1822
23+ // Less compares two elements in the slice for sorting.
24+ // Nil elements are considered smaller than non-nil elements.
25+ // Two nil elements are considered equal.
1926func (to TopObjects ) Less (i , j int ) bool {
20- if to [i ] == nil && to [j ] != nil {
21- return true
27+ // Handle cases where either element is nil
28+ if to [i ] == nil && to [j ] == nil {
29+ return false // Equal, so not less than
2230 }
23- if to [i ] != nil && to [ j ] == nil {
24- return false
31+ if to [i ] == nil {
32+ return true // nil is considered smaller than non-nil
2533 }
26- if to [i ] == nil && to [ j ] == nil {
27- return false
34+ if to [j ] == nil {
35+ return false // Non-nil is considered larger than nil
2836 }
29-
37+ // Both elements are non-nil, compare their sizes
3038 return to [i ].Size < to [j ].Size
3139}
3240
41+ // Swap swaps the elements with indexes i and j.
42+ // It performs bounds checking to prevent panics.
3343func (to TopObjects ) Swap (i , j int ) {
44+ if i < 0 || i >= len (to ) || j < 0 || j >= len (to ) {
45+ return // Out of bounds, no-op
46+ }
3447 to [i ], to [j ] = to [j ], to [i ]
3548}
3649
50+ // Push adds an element to the heap. It handles nil values safely and only adds
51+ // valid *ObjectMetadata pointers to the slice.
3752func (to * TopObjects ) Push (x interface {}) {
38- item := x .(* ObjectMetadata )
39- if item == nil {
53+ if x == nil {
54+ return
55+ }
56+ item , ok := x .(* ObjectMetadata )
57+ if ! ok || item == nil {
4058 return
4159 }
4260 * to = append (* to , item )
4361}
4462
63+ // Pop removes and returns the smallest element from the heap.
64+ // The result is the element that would be returned by Pop() from the heap package.
4565func (to * TopObjects ) Pop () interface {} {
4666 old := * to
4767 n := len (old )
@@ -51,14 +71,24 @@ func (to *TopObjects) Pop() interface{} {
5171 return item
5272}
5373
74+ // List returns a sorted slice of ObjectMetadata, with the largest elements first.
75+ // It creates a copy of the underlying data to preserve the original heap.
76+ // Returns nil if the receiver is nil.
5477func (to TopObjects ) List () []* ObjectMetadata {
55- list := []* ObjectMetadata {}
56- for len (to ) > 0 {
57- item := heap .Pop (& to ).(* ObjectMetadata )
58- if item == nil {
59- continue
78+ if to == nil {
79+ return nil
80+ }
81+
82+ tmp := make (TopObjects , len (to ))
83+ copy (tmp , to )
84+ heap .Init (& tmp )
85+
86+ list := make ([]* ObjectMetadata , 0 , len (to ))
87+ for tmp .Len () > 0 {
88+ item := heap .Pop (& tmp ).(* ObjectMetadata )
89+ if item != nil {
90+ list = append ([]* ObjectMetadata {item }, list ... ) // prepend to maintain order
6091 }
61- list = append ([]* ObjectMetadata {item }, list ... )
6292 }
6393
6494 return list
0 commit comments