refactor(metrics): remove pointers from type parameter T to avoid unnecessary indirection

This commit is contained in:
yusing
2025-08-28 22:30:40 +08:00
parent 205928a741
commit 0a5df1bd7f
4 changed files with 20 additions and 23 deletions

View File

@@ -6,7 +6,7 @@ import (
)
type Entries[T any] struct {
entries [maxEntries]*T
entries [maxEntries]T
index int
count int
interval time.Duration
@@ -16,17 +16,14 @@ type Entries[T any] struct {
const maxEntries = 100
func newEntries[T any](duration time.Duration) *Entries[T] {
interval := duration / maxEntries
if interval < time.Second {
interval = time.Second
}
interval := max(duration/maxEntries, time.Second)
return &Entries[T]{
interval: interval,
lastAdd: time.Now(),
}
}
func (e *Entries[T]) Add(now time.Time, info *T) {
func (e *Entries[T]) Add(now time.Time, info T) {
if now.Sub(e.lastAdd) < e.interval {
return
}
@@ -38,11 +35,11 @@ func (e *Entries[T]) Add(now time.Time, info *T) {
e.lastAdd = now
}
func (e *Entries[T]) Get() []*T {
func (e *Entries[T]) Get() []T {
if e.count < maxEntries {
return e.entries[:e.count]
}
res := make([]*T, maxEntries)
res := make([]T, maxEntries)
copy(res, e.entries[e.index:])
copy(res[maxEntries-e.index:], e.entries[:e.index])
return res
@@ -57,7 +54,7 @@ func (e *Entries[T]) MarshalJSON() ([]byte, error) {
func (e *Entries[T]) UnmarshalJSON(data []byte) error {
var v struct {
Entries []*T `json:"entries"`
Entries []T `json:"entries"`
Interval time.Duration `json:"interval"`
}
if err := json.Unmarshal(data, &v); err != nil {

View File

@@ -3,6 +3,7 @@ package period
import (
"errors"
"net/http"
"net/url"
"time"
"github.com/gin-gonic/gin"
@@ -29,6 +30,7 @@ type ResponseType[AggregateT any] struct {
//
// If the request is a websocket request, it serves the data for the given period for every interval.
func (p *Poller[T, AggregateT]) ServeHTTP(c *gin.Context) {
period := Filter(c.Query("period"))
query := c.Request.URL.Query()
if httpheaders.IsWebsocket(c.Request.Header) {
@@ -42,10 +44,10 @@ func (p *Poller[T, AggregateT]) ServeHTTP(c *gin.Context) {
interval = minInterval
}
websocket.PeriodicWrite(c, interval, func() (any, error) {
return p.getRespData(c.Request)
return p.getRespData(period, query)
})
} else {
data, err := p.getRespData(c.Request)
data, err := p.getRespData(period, query)
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to get response data"))
return
@@ -58,13 +60,11 @@ func (p *Poller[T, AggregateT]) ServeHTTP(c *gin.Context) {
}
}
func (p *Poller[T, AggregateT]) getRespData(r *http.Request) (any, error) {
query := r.URL.Query()
period := query.Get("period")
func (p *Poller[T, AggregateT]) getRespData(period Filter, query url.Values) (any, error) {
if period == "" {
return p.GetLastResult(), nil
}
rangeData, ok := p.Get(Filter(period))
rangeData, ok := p.Get(period)
if !ok {
return nil, errors.New("invalid period")
}

View File

@@ -32,7 +32,7 @@ func NewPeriod[T any]() *Period[T] {
}
}
func (p *Period[T]) Add(info *T) {
func (p *Period[T]) Add(info T) {
p.mu.Lock()
defer p.mu.Unlock()
now := time.Now()
@@ -41,7 +41,7 @@ func (p *Period[T]) Add(info *T) {
}
}
func (p *Period[T]) Get(filter Filter) ([]*T, bool) {
func (p *Period[T]) Get(filter Filter) ([]T, bool) {
p.mu.RLock()
defer p.mu.RUnlock()
period, ok := p.Entries[filter]

View File

@@ -17,16 +17,16 @@ import (
)
type (
PollFunc[T any] func(ctx context.Context, lastResult *T) (*T, error)
AggregateFunc[T any, AggregateT json.Marshaler] func(entries []*T, query url.Values) (total int, result AggregateT)
FilterFunc[T any] func(entries []*T, keyword string) (filtered []*T)
PollFunc[T any] func(ctx context.Context, lastResult T) (T, error)
AggregateFunc[T any, AggregateT json.Marshaler] func(entries []T, query url.Values) (total int, result AggregateT)
FilterFunc[T any] func(entries []T, keyword string) (filtered []T)
Poller[T any, AggregateT json.Marshaler] struct {
name string
poll PollFunc[T]
aggregate AggregateFunc[T, AggregateT]
resultFilter FilterFunc[T]
period *Period[T]
lastResult atomic.Value[*T]
lastResult atomic.Value[T]
errs []pollErr
}
pollErr struct {
@@ -188,10 +188,10 @@ func (p *Poller[T, AggregateT]) Start() {
}()
}
func (p *Poller[T, AggregateT]) Get(filter Filter) ([]*T, bool) {
func (p *Poller[T, AggregateT]) Get(filter Filter) ([]T, bool) {
return p.period.Get(filter)
}
func (p *Poller[T, AggregateT]) GetLastResult() *T {
func (p *Poller[T, AggregateT]) GetLastResult() T {
return p.lastResult.Load()
}