Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
112 lines
3.2 KiB
Go
112 lines
3.2 KiB
Go
// Copyright (c) 2025 Couchbase, Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package fusion
|
|
|
|
import (
|
|
"sort"
|
|
|
|
"github.com/blevesearch/bleve/v2/search"
|
|
)
|
|
|
|
// sortDocMatchesByScore orders the provided collection in-place by the primary
|
|
// score in descending order, breaking ties with the original `HitNumber` to
|
|
// ensure deterministic output.
|
|
func sortDocMatchesByScore(hits search.DocumentMatchCollection) {
|
|
if len(hits) < 2 {
|
|
return
|
|
}
|
|
|
|
sort.Slice(hits, func(a, b int) bool {
|
|
i := hits[a]
|
|
j := hits[b]
|
|
if i.Score == j.Score {
|
|
return i.HitNumber < j.HitNumber
|
|
}
|
|
return i.Score > j.Score
|
|
})
|
|
}
|
|
|
|
// scoreBreakdownForQuery fetches the score for a specific KNN query index from
|
|
// the provided hit. The boolean return indicates whether the score is present.
|
|
func scoreBreakdownForQuery(hit *search.DocumentMatch, idx int) (float64, bool) {
|
|
if hit == nil || hit.ScoreBreakdown == nil {
|
|
return 0, false
|
|
}
|
|
|
|
score, ok := hit.ScoreBreakdown[idx]
|
|
return score, ok
|
|
}
|
|
|
|
// sortDocMatchesByBreakdown orders the hits in-place using the KNN score for
|
|
// the supplied query index (descending), breaking ties with `HitNumber` and
|
|
// placing hits without a score at the end.
|
|
func sortDocMatchesByBreakdown(hits search.DocumentMatchCollection, queryIdx int) {
|
|
if len(hits) < 2 {
|
|
return
|
|
}
|
|
|
|
sort.SliceStable(hits, func(a, b int) bool {
|
|
left := hits[a]
|
|
right := hits[b]
|
|
|
|
var leftScore float64
|
|
leftOK := false
|
|
if left != nil && left.ScoreBreakdown != nil {
|
|
leftScore, leftOK = left.ScoreBreakdown[queryIdx]
|
|
}
|
|
|
|
var rightScore float64
|
|
rightOK := false
|
|
if right != nil && right.ScoreBreakdown != nil {
|
|
rightScore, rightOK = right.ScoreBreakdown[queryIdx]
|
|
}
|
|
|
|
if leftOK && rightOK {
|
|
if leftScore == rightScore {
|
|
return left.HitNumber < right.HitNumber
|
|
}
|
|
return leftScore > rightScore
|
|
}
|
|
|
|
if leftOK != rightOK {
|
|
return leftOK
|
|
}
|
|
|
|
return left.HitNumber < right.HitNumber
|
|
})
|
|
}
|
|
|
|
// getFusionExplAt copies the existing explanation child at the requested index
|
|
// and wraps it in a new node describing how the fusion algorithm adjusted the
|
|
// score.
|
|
func getFusionExplAt(hit *search.DocumentMatch, i int, value float64, message string) *search.Explanation {
|
|
return &search.Explanation{
|
|
Value: value,
|
|
Message: message,
|
|
Children: []*search.Explanation{hit.Expl.Children[i]},
|
|
}
|
|
}
|
|
|
|
// finalizeFusionExpl installs the collection of fusion explanation children and
|
|
// updates the root message so the caller sees the fused score as the sum of its
|
|
// parts.
|
|
func finalizeFusionExpl(hit *search.DocumentMatch, explChildren []*search.Explanation) {
|
|
hit.Expl.Children = explChildren
|
|
|
|
hit.Expl.Value = hit.Score
|
|
hit.Expl.Message = "sum of"
|
|
}
|