101 lines
2.1 KiB
Go
101 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"git.gammaspectra.live/P2Pool/p2pool-observer/utils"
|
|
"golang.org/x/exp/slices"
|
|
)
|
|
|
|
type PositionChart struct {
|
|
totalItems uint64
|
|
bucket []uint64
|
|
idle byte
|
|
}
|
|
|
|
func (p *PositionChart) Add(index int, value uint64) {
|
|
if index < 0 || index > int(p.totalItems) {
|
|
return
|
|
}
|
|
if len(p.bucket) == 1 {
|
|
p.bucket[0] += value
|
|
return
|
|
}
|
|
i := uint64(index) * uint64(len(p.bucket)-1) / (p.totalItems - 1)
|
|
p.bucket[i] += value
|
|
}
|
|
|
|
func (p *PositionChart) Total() (result uint64) {
|
|
for _, e := range p.bucket {
|
|
result += e
|
|
}
|
|
return
|
|
}
|
|
|
|
func (p *PositionChart) Size() uint64 {
|
|
return uint64(len(p.bucket))
|
|
}
|
|
|
|
func (p *PositionChart) Resolution() uint64 {
|
|
return p.totalItems / uint64(len(p.bucket))
|
|
}
|
|
|
|
func (p *PositionChart) SetIdle(idleChar byte) {
|
|
p.idle = idleChar
|
|
}
|
|
|
|
func (p *PositionChart) String() string {
|
|
position := make([]byte, 2*2+len(p.bucket))
|
|
position[0], position[1] = '[', '<'
|
|
position[len(position)-2], position[len(position)-1] = '<', ']'
|
|
for i, e := range utils.ReverseSlice(slices.Clone(p.bucket)) {
|
|
if e > 0 {
|
|
if e > 9 {
|
|
position[2+i] = '+'
|
|
} else {
|
|
position[2+i] = 0x30 + byte(e)
|
|
}
|
|
} else {
|
|
position[2+i] = p.idle
|
|
}
|
|
}
|
|
|
|
return string(position)
|
|
}
|
|
|
|
func (p *PositionChart) StringWithSeparator(index int) string {
|
|
if index < 0 || index > int(p.totalItems) {
|
|
return p.String()
|
|
}
|
|
separatorIndex := index * (len(p.bucket) - 1) / int(p.totalItems-1)
|
|
position := make([]byte, 1+2*2+len(p.bucket))
|
|
position[0], position[1] = '[', '<'
|
|
position[2+separatorIndex] = '|'
|
|
position[len(position)-2], position[len(position)-1] = '<', ']'
|
|
for i, e := range utils.ReverseSlice(slices.Clone(p.bucket)) {
|
|
if i >= separatorIndex {
|
|
i++
|
|
}
|
|
if e > 0 {
|
|
if e > 9 {
|
|
position[2+i] = '+'
|
|
} else {
|
|
position[2+i] = 0x30 + byte(e)
|
|
}
|
|
} else {
|
|
position[2+i] = p.idle
|
|
}
|
|
}
|
|
|
|
return string(position)
|
|
}
|
|
|
|
func NewPositionChart(size uint64, totalItems uint64) *PositionChart {
|
|
if size < 1 {
|
|
size = 1
|
|
}
|
|
return &PositionChart{
|
|
totalItems: totalItems,
|
|
bucket: make([]uint64, size),
|
|
idle: '.',
|
|
}
|
|
}
|