1
0
Fork 0
test/incrementor.go

100 lines
3.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package incrementor
import (
"math"
"sync"
)
type (
// Incrementor является инкрементным числом с настройками поведения, вроде максимально допустимого значения.
Incrementor struct {
// NOTE(toby3d): защита чтения/записи числа в горутинах
mutex *sync.RWMutex
// NOTE(toby3d): непосредственно само инкрементное число
number int64
// NOTE(toby3d): максимально допустимое значение инкрементного числа, по достижении которого оно будет
// сброшено в 0
maxValue int64
}
// Reader описывает действия для чтения текущего значения числа.
Reader interface {
GetNumber() int64
}
// Writer описывает действия для изменения значения числа и управления его максимально допустимым значением.
Writer interface {
IncrementNumber()
SetMaximumValue(maximumValue int)
}
// Incrementer описывает поведение менеджера инкрементного числа.
Incrementer interface {
Reader
Writer
}
)
// DefaultMaximumValue содержит максимально возможное значение числа по-умолчанию в битах.
const DefaultMaximumValue = math.MaxInt64
// New создаёт новую структуру для хранения и управления инкрементным числом.
//
// NOTE(toby3d): в тестовом задании нет сведений по тому возможно ли изменение параметров на этапе инициализации, как
// например отсчёт не с 0 или перезапись максимального порога без отдельного вызова SetMaximumValue. 🤷‍♂
func New() *Incrementor {
i := new(Incrementor)
i.number = 0
i.mutex = new(sync.RWMutex)
i.maxValue = DefaultMaximumValue
return i
}
// GetNumber возвращает текущее число.
func (i *Incrementor) GetNumber() int64 {
i.mutex.RLock()
defer i.mutex.RUnlock()
return i.number
}
// IncrementNumber увеличивает текущее число на 1.
//
// Если в процессе выполнения метода число будет >= максимально допустимого порога, то оно будет сброшено в 0.
func (i *Incrementor) IncrementNumber() {
i.mutex.Lock()
i.number++
if i.number >= i.maxValue {
i.number = 0
}
i.mutex.Unlock()
}
// SetMaximumValue устанавливает максимально возможное значение для числа. По достижении или превышении указанного
// порога число будет сброшено в 0.
//
// Вводимое значение не может быть меньше 0 и больше DefaultMaximumValue.
func (i *Incrementor) SetMaximumValue(maximumValue int64) {
// NOTE(toby3d): предварительно проверяем ввод, косячный сбрасываем в значение по-умолчанию.
if maximumValue <= 0 || maximumValue > DefaultMaximumValue {
maximumValue = DefaultMaximumValue
}
i.mutex.Lock()
i.maxValue = maximumValue
// NOTE(toby3d): если максимум оказывается меньше текущего значения, то сбрасываем число в 0.
if i.number >= i.maxValue {
i.number = 0
}
i.mutex.Unlock()
}