diff --git a/gcc/state.go b/gcc/state.go new file mode 100644 index 0000000..34c99f3 --- /dev/null +++ b/gcc/state.go @@ -0,0 +1,80 @@ +// SPDX-FileCopyrightText: 2025 The Pion community +// SPDX-License-Identifier: MIT + +package gcc + +import "fmt" + +type state int + +const ( + stateDecrease state = -1 + stateHold state = 0 + stateIncrease state = 1 +) + +// unknown states will always transition to increase. +func (s state) transition(u usage) state { + switch s { + case stateHold: + return transitionFromHold(u) + case stateIncrease: + return transitionFromIncrease(u) + case stateDecrease: + return transitionFromDecrease(u) + } + + return stateIncrease +} + +func transitionFromHold(u usage) state { + switch u { + case usageOver: + return stateDecrease + case usageNormal: + return stateIncrease + case usageUnder: + return stateHold + } + + return stateIncrease +} + +func transitionFromIncrease(u usage) state { + switch u { + case usageOver: + return stateDecrease + case usageNormal: + return stateIncrease + case usageUnder: + return stateHold + } + + return stateIncrease +} + +func transitionFromDecrease(u usage) state { + switch u { + case usageOver: + return stateDecrease + case usageNormal: + return stateHold + case usageUnder: + return stateHold + } + + return stateIncrease +} + +func (s state) String() string { + switch s { + case stateIncrease: + return "increase" + case stateDecrease: + return "decrease" + case stateHold: + return "hold" + default: + return fmt.Sprintf("invalid state: %d", s) + } +} diff --git a/gcc/state_test.go b/gcc/state_test.go new file mode 100644 index 0000000..eaad70e --- /dev/null +++ b/gcc/state_test.go @@ -0,0 +1,71 @@ +// SPDX-FileCopyrightText: 2025 The Pion community +// SPDX-License-Identifier: MIT + +package gcc + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestState(t *testing.T) { + t.Run("invalid", func(t *testing.T) { + assert.Equal(t, stateIncrease, state(17).transition(29)) + }) + + t.Run("hold", func(t *testing.T) { + assert.Equal(t, stateDecrease, stateHold.transition(usageOver)) + assert.Equal(t, stateIncrease, stateHold.transition(usageNormal)) + assert.Equal(t, stateHold, stateHold.transition(usageUnder)) + assert.Equal(t, stateIncrease, stateHold.transition(17)) + }) + + t.Run("increase", func(t *testing.T) { + assert.Equal(t, stateDecrease, stateIncrease.transition(usageOver)) + assert.Equal(t, stateIncrease, stateIncrease.transition(usageNormal)) + assert.Equal(t, stateHold, stateIncrease.transition(usageUnder)) + assert.Equal(t, stateIncrease, stateIncrease.transition(17)) + }) + + t.Run("decrease", func(t *testing.T) { + assert.Equal(t, stateDecrease, stateDecrease.transition(usageOver)) + assert.Equal(t, stateHold, stateDecrease.transition(usageNormal)) + assert.Equal(t, stateHold, stateDecrease.transition(usageUnder)) + assert.Equal(t, stateIncrease, stateDecrease.transition(17)) + }) +} + +func TestStateString(t *testing.T) { + cases := []struct { + name string + value state + expected string + }{ + { + name: "decrease", + value: stateDecrease, + expected: "decrease", + }, + { + name: "hold", + value: stateHold, + expected: "hold", + }, + { + name: "increase", + value: stateIncrease, + expected: "increase", + }, + { + name: "invalid", + value: 17, + expected: "invalid state: 17", + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, tc.value.String()) + }) + } +} diff --git a/gcc/usage.go b/gcc/usage.go new file mode 100644 index 0000000..d3ccfac --- /dev/null +++ b/gcc/usage.go @@ -0,0 +1,27 @@ +// SPDX-FileCopyrightText: 2025 The Pion community +// SPDX-License-Identifier: MIT + +package gcc + +import "fmt" + +type usage int + +const ( + usageUnder usage = -1 + usageNormal usage = 0 + usageOver usage = 1 +) + +func (u usage) String() string { + switch u { + case usageOver: + return "overuse" + case usageUnder: + return "underuse" + case usageNormal: + return "normal" + default: + return fmt.Sprintf("invalid usage: %d", u) + } +} diff --git a/gcc/usage_test.go b/gcc/usage_test.go new file mode 100644 index 0000000..e0fc84b --- /dev/null +++ b/gcc/usage_test.go @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: 2025 The Pion community +// SPDX-License-Identifier: MIT + +package gcc + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestUsageString(t *testing.T) { + cases := []struct { + name string + value usage + expected string + }{ + { + name: "under", + value: usageUnder, + expected: "underuse", + }, + { + name: "normal", + value: usageNormal, + expected: "normal", + }, + { + name: "over", + value: usageOver, + expected: "overuse", + }, + { + name: "invalid", + value: 17, + expected: "invalid usage: 17", + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + assert.Equal(t, tc.expected, tc.value.String()) + }) + } +}