mirror of
https://dev.azure.com/schwarzit/schwarzit.stackit-public/_git/audit-go
synced 2026-02-08 00:57:24 +00:00
60 lines
1.6 KiB
Go
60 lines
1.6 KiB
Go
package utils
|
|
|
|
import (
|
|
"slices"
|
|
"sync"
|
|
)
|
|
|
|
// SequenceNumberGenerator can be used to generate increasing numbers.
|
|
type SequenceNumberGenerator interface {
|
|
|
|
// Next returns the next number
|
|
Next() uint64
|
|
|
|
// Revert can be used to revert a specific number (e.g. in case of an error)
|
|
Revert(uint64)
|
|
}
|
|
|
|
// DefaultSequenceNumberGenerator is a mutex protected implementation of SequenceNumberGenerator
|
|
type DefaultSequenceNumberGenerator struct {
|
|
backlog []uint64
|
|
sequenceNumber uint64
|
|
sequenceNumberLock sync.Mutex
|
|
}
|
|
|
|
// NewDefaultSequenceNumberGenerator returns an instance of DefaultSequenceNumberGenerator as pointer
|
|
// of SequenceNumberGenerator.
|
|
func NewDefaultSequenceNumberGenerator() SequenceNumberGenerator {
|
|
var generator SequenceNumberGenerator = &DefaultSequenceNumberGenerator{
|
|
backlog: make([]uint64, 0),
|
|
sequenceNumber: 0,
|
|
sequenceNumberLock: sync.Mutex{},
|
|
}
|
|
return generator
|
|
}
|
|
|
|
// Next implements SequenceNumberGenerator.Next
|
|
func (g *DefaultSequenceNumberGenerator) Next() uint64 {
|
|
g.sequenceNumberLock.Lock()
|
|
defer g.sequenceNumberLock.Unlock()
|
|
var next uint64
|
|
if len(g.backlog) == 0 {
|
|
next = g.sequenceNumber
|
|
g.sequenceNumber++
|
|
} else {
|
|
next = g.backlog[0]
|
|
g.backlog = g.backlog[1:]
|
|
}
|
|
return next
|
|
}
|
|
|
|
// Revert implements SequenceNumberGenerator.Revert
|
|
func (g *DefaultSequenceNumberGenerator) Revert(value uint64) {
|
|
g.sequenceNumberLock.Lock()
|
|
defer g.sequenceNumberLock.Unlock()
|
|
if value == g.sequenceNumber-1 {
|
|
g.sequenceNumber--
|
|
} else if !slices.Contains(g.backlog, value) {
|
|
g.backlog = append(g.backlog, value)
|
|
}
|
|
}
|