Convert sort.Slice -> slices.SortFunc (#4472)

* Convert sort.Slice -> slices.SortFunc

* active speaker loudness in descending order
This commit is contained in:
Raja Subramanian
2026-04-23 15:12:24 +05:30
committed by GitHub
parent 85be9d70fb
commit 701a37c2d1
10 changed files with 83 additions and 53 deletions
+20 -19
View File
@@ -16,7 +16,7 @@ package selector
import (
"math/rand/v2"
"sort"
"slices"
"time"
"github.com/thoas/go-funk"
@@ -24,6 +24,7 @@ import (
"github.com/livekit/protocol/livekit"
"github.com/livekit/livekit-server/pkg/config"
"github.com/livekit/livekit-server/pkg/utils"
)
const AvailableSeconds = 5
@@ -124,42 +125,42 @@ func selectLowestSortedNode(nodes []*livekit.Node, sortBy string) (*livekit.Node
idx := funk.RandomInt(0, len(nodes))
return nodes[idx], nil
case "sysload":
sort.Slice(nodes, func(i, j int) bool {
return GetNodeSysload(nodes[i]) < GetNodeSysload(nodes[j])
slices.SortFunc(nodes, func(a, b *livekit.Node) int {
return utils.Signum(GetNodeSysload(a) - GetNodeSysload(b))
})
return nodes[0], nil
case "cpuload":
sort.Slice(nodes, func(i, j int) bool {
return nodes[i].Stats.CpuLoad < nodes[j].Stats.CpuLoad
slices.SortFunc(nodes, func(a, b *livekit.Node) int {
return utils.Signum(a.Stats.CpuLoad - b.Stats.CpuLoad)
})
return nodes[0], nil
case "rooms":
sort.Slice(nodes, func(i, j int) bool {
return nodes[i].Stats.NumRooms < nodes[j].Stats.NumRooms
slices.SortFunc(nodes, func(a, b *livekit.Node) int {
return utils.Signum(a.Stats.NumRooms - b.Stats.NumRooms)
})
return nodes[0], nil
case "clients":
sort.Slice(nodes, func(i, j int) bool {
return nodes[i].Stats.NumClients < nodes[j].Stats.NumClients
slices.SortFunc(nodes, func(a, b *livekit.Node) int {
return utils.Signum(a.Stats.NumClients - b.Stats.NumClients)
})
return nodes[0], nil
case "tracks":
sort.Slice(nodes, func(i, j int) bool {
return nodes[i].Stats.NumTracksIn+nodes[i].Stats.NumTracksOut < nodes[j].Stats.NumTracksIn+nodes[j].Stats.NumTracksOut
slices.SortFunc(nodes, func(a, b *livekit.Node) int {
return utils.Signum((a.Stats.NumTracksIn + a.Stats.NumTracksOut) - (b.Stats.NumTracksIn + b.Stats.NumTracksOut))
})
return nodes[0], nil
case "bytespersec":
sort.Slice(nodes, func(i, j int) bool {
ratei := &livekit.NodeStatsRate{}
if len(nodes[i].Stats.Rates) > 0 {
ratei = nodes[i].Stats.Rates[0]
slices.SortFunc(nodes, func(a, b *livekit.Node) int {
ratea := &livekit.NodeStatsRate{}
if len(a.Stats.Rates) > 0 {
ratea = a.Stats.Rates[0]
}
ratej := &livekit.NodeStatsRate{}
if len(nodes[j].Stats.Rates) > 0 {
ratej = nodes[j].Stats.Rates[0]
rateb := &livekit.NodeStatsRate{}
if len(b.Stats.Rates) > 0 {
rateb = b.Stats.Rates[0]
}
return ratei.BytesIn+ratei.BytesOut < ratej.BytesIn+ratej.BytesOut
return utils.Signum((ratea.BytesIn + ratea.BytesOut) - (rateb.BytesIn + rateb.BytesOut))
})
return nodes[0], nil
default:
+16 -9
View File
@@ -15,7 +15,8 @@
package dynacast
import (
"sort"
"slices"
"strings"
"sync"
"testing"
"time"
@@ -498,19 +499,25 @@ func TestCodecRegression(t *testing.T) {
}
func subscribedCodecsAsString(c1 []*livekit.SubscribedCodec) string {
sort.Slice(c1, func(i, j int) bool { return c1[i].Codec < c1[j].Codec })
var s1 string
slices.SortFunc(c1, func(a, b *livekit.SubscribedCodec) int {
return strings.Compare(a.Codec, b.Codec)
})
var s1 strings.Builder
for _, c := range c1 {
s1 += c.String()
s1.WriteString(c.String())
}
return s1
return s1.String()
}
func subscribedAudioCodecsAsString(c1 []*livekit.SubscribedAudioCodec) string {
sort.Slice(c1, func(i, j int) bool { return c1[i].Codec < c1[j].Codec })
var s1 string
slices.SortFunc(c1, func(a, b *livekit.SubscribedAudioCodec) int {
return strings.Compare(a.Codec, b.Codec)
})
var s1 strings.Builder
for _, c := range c1 {
s1 += c.String()
s1.WriteString(c.String())
}
return s1
return s1.String()
}
+5 -8
View File
@@ -18,7 +18,6 @@ import (
"errors"
"fmt"
"slices"
"sort"
"strings"
"sync"
@@ -207,8 +206,8 @@ func (t *MediaTrackReceiver) SetupReceiver(receiver sfu.TrackReceiver, priority
receivers = append(receivers, &simulcastReceiver{TrackReceiver: receiver, priority: priority})
}
sort.Slice(receivers, func(i, j int) bool {
return receivers[i].Priority() < receivers[j].Priority()
slices.SortFunc(receivers, func(a, b *simulcastReceiver) int {
return sutils.Signum(a.Priority() - b.Priority())
})
if mid != "" {
@@ -349,8 +348,8 @@ func (t *MediaTrackReceiver) SetPotentialCodecs(codecs []webrtc.RTPCodecParamete
})
}
}
sort.Slice(receivers, func(i, j int) bool {
return receivers[i].Priority() < receivers[j].Priority()
slices.SortFunc(receivers, func(a, b *simulcastReceiver) int {
return sutils.Signum(a.Priority() - b.Priority())
})
t.receivers = receivers
t.lock.Unlock()
@@ -1090,9 +1089,7 @@ func (t *MediaTrackReceiver) GetQualityForDimension(mimeType mime.MimeType, widt
layerSizes = providedSizes
// comparing height always
requestedSize = height
sort.Slice(layerSizes, func(i, j int) bool {
return layerSizes[i] < layerSizes[j]
})
slices.Sort(layerSizes)
}
// finds the highest layer with smallest dimensions that still satisfy client demands
+2 -3
View File
@@ -20,7 +20,6 @@ import (
"maps"
"math"
"slices"
"sort"
"strings"
"sync"
"time"
@@ -393,8 +392,8 @@ func (r *Room) GetActiveSpeakers() []*livekit.SpeakerInfo {
})
}
sort.Slice(speakers, func(i, j int) bool {
return speakers[i].Level > speakers[j].Level
slices.SortFunc(speakers, func(a, b *livekit.SpeakerInfo) int {
return sutils.Signum(b.Level - a.Level)
})
// quantize to smooth out small changes
+1 -1
View File
@@ -664,7 +664,7 @@ func (b *BufferBase) SendPLI(force bool) {
pliThrottle := b.pliThrottle
b.RUnlock()
if (rtpStats == nil && !force) || !rtpStats.CheckAndUpdatePli(pliThrottle, force) {
if rtpStats == nil || !rtpStats.CheckAndUpdatePli(pliThrottle, force) {
return
}
+9 -3
View File
@@ -16,7 +16,7 @@ package buffer
import (
"fmt"
"sort"
"slices"
"sync"
"time"
@@ -288,8 +288,14 @@ func ProcessFrameDependencyStructure(structure *dd.FrameDependencyStructure) []D
}
// sort decode target layer by spatial and temporal from high to low
sort.Slice(decodeTargets, func(i, j int) bool {
return decodeTargets[i].Layer.GreaterThan(decodeTargets[j].Layer)
slices.SortFunc(decodeTargets, func(a, b DependencyDescriptorDecodeTarget) int {
if a.Layer.GreaterThan(b.Layer) {
return -1
}
if b.Layer.GreaterThan(a.Layer) {
return 1
}
return 0
})
return decodeTargets
+3
View File
@@ -159,6 +159,9 @@ func (w *WebRTCReceiver) GetConnectionScoreAndQuality() (float32, livekit.Connec
}
func (w *WebRTCReceiver) ssrc(layer int) uint32 {
w.upTracksMu.Lock()
defer w.upTracksMu.Unlock()
if track := w.upTracks[layer]; track != nil {
return uint32(track.SSRC())
}
@@ -15,7 +15,7 @@
package videolayerselector
import (
"sort"
"slices"
"testing"
"github.com/pion/rtp"
@@ -287,8 +287,14 @@ func createDDFrames(maxLayer buffer.VideoLayer, startFrameNumber uint16) []*buff
activeBitMask |= 1 << uint(i*int(maxLayer.Temporal+1)+j)
}
}
sort.Slice(decodeTargets, func(i, j int) bool {
return decodeTargets[i].Layer.GreaterThan(decodeTargets[j].Layer)
slices.SortFunc(decodeTargets, func(a, b buffer.DependencyDescriptorDecodeTarget) int {
if a.Layer.GreaterThan(b.Layer) {
return -1
}
if b.Layer.GreaterThan(a.Layer) {
return 1
}
return 0
})
chainDiffs := make([]int, int(maxLayer.Spatial)+1)
+1 -1
View File
@@ -310,7 +310,7 @@ func coalesce(stats []*livekit.AnalyticsStat) *livekit.AnalyticsStat {
stat := &livekit.AnalyticsStat{
MinScore: minScore,
MedianScore: utils.MedianFloat32(scores),
MedianScore: utils.Median(scores),
Streams: []*livekit.AnalyticsStream{coalescedStream},
Mime: stats[len(stats)-1].Mime, // use the latest Mime
}
+17 -6
View File
@@ -14,10 +14,10 @@
package utils
import "sort"
import "slices"
// MedianFloat32 gets median value for an array of float32
func MedianFloat32(input []float32) float32 {
// Median gets median value for an array
func Median[T float32](input []T) T {
num := len(input)
switch num {
case 0:
@@ -25,9 +25,7 @@ func MedianFloat32(input []float32) float32 {
case 1:
return input[0]
}
sort.Slice(input, func(i, j int) bool {
return input[i] < input[j]
})
slices.Sort(input)
if num%2 != 0 {
return input[num/2]
}
@@ -35,3 +33,16 @@ func MedianFloat32(input []float32) float32 {
right := input[num/2]
return (left + right) / 2
}
func Signum[T int | int32 | float32](val T) int {
switch {
case val < 0:
return -1
case val > 0:
return 1
default:
return 0
}
}