fix: Pass Knapsnak ptr to avoid compact multiple times (#40400)

Related to #40388

The small segments may be put into bucket twice due to value parameter
of Knapsnap.packWith

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>
This commit is contained in:
congqixia 2025-03-06 15:42:03 +08:00 committed by GitHub
parent 80213c0f6f
commit 5c5273f95e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -33,14 +33,14 @@ type Knapsack[T Sizable] struct {
candidates []T
}
func newKnapsack[T Sizable](name string, candidates []T) Knapsack[T] {
func newKnapsack[T Sizable](name string, candidates []T) *Knapsack[T] {
sort.Slice(candidates, func(i, j int) bool {
if candidates[i].getSegmentSize() != candidates[j].getSegmentSize() {
return candidates[i].getSegmentSize() > candidates[j].getSegmentSize()
}
return candidates[i].GetID() < candidates[j].GetID()
})
return Knapsack[T]{
return &Knapsack[T]{
name: name,
candidates: candidates,
}
@ -61,13 +61,7 @@ func (c *Knapsack[T]) tryPack(size, maxLeftSize, minSegs, maxSegs int64) (bitset
}
nSelections := selection.Count()
var minUSegs uint
if minSegs < 0 {
minUSegs = 0
} else {
minUSegs = uint(minSegs)
}
if left > maxLeftSize || nSelections < uint(minUSegs) {
if left > maxLeftSize || int64(nSelections) < minSegs {
selection.ClearAll()
left = size
}
@ -103,7 +97,7 @@ func (c *Knapsack[T]) pack(size, maxLeftSize, minSegs, maxSegs int64) ([]T, int6
return segs, left
}
func (c *Knapsack[T]) packWith(size, maxLeftSize, minSegs, maxSegs int64, other Knapsack[T]) ([]T, int64) {
func (c *Knapsack[T]) packWith(size, maxLeftSize, minSegs, maxSegs int64, other *Knapsack[T]) ([]T, int64) {
selection, left := c.tryPack(size, math.MaxInt64, 0, maxSegs)
if selection.Count() == 0 {
return nil, size
@ -114,7 +108,7 @@ func (c *Knapsack[T]) packWith(size, maxLeftSize, minSegs, maxSegs int64, other
if otherSelection.Count() == 0 {
// If the original selection already satisfied the requirements, return immediately
if left < maxLeftSize && selection.Count() >= uint(minSegs) {
if left < maxLeftSize && int64(selection.Count()) >= minSegs {
return c.commit(selection), left
}
return nil, size
@ -124,6 +118,6 @@ func (c *Knapsack[T]) packWith(size, maxLeftSize, minSegs, maxSegs int64, other
return append(segs, otherSegs...), left
}
func newSegmentPacker(name string, candidates []*SegmentInfo) Knapsack[*SegmentInfo] {
return newKnapsack[*SegmentInfo](name, candidates)
func newSegmentPacker(name string, candidates []*SegmentInfo) *Knapsack[*SegmentInfo] {
return newKnapsack(name, candidates)
}