chore: better time storage in rule wrapper

This commit is contained in:
wwqgtxx
2026-01-12 00:50:55 +08:00
parent ae6069c178
commit 0cf37de1a8

View File

@@ -11,9 +11,9 @@ type RuleWrapper struct {
C.Rule
disabled atomic.Bool
hitCount atomic.Uint64
hitAt atomic.Int64 // unix microsecond
hitAt atomicTime
missCount atomic.Uint64
missAt atomic.Int64 // unix microsecond
missAt atomicTime
}
func (r *RuleWrapper) IsDisabled() bool {
@@ -29,7 +29,7 @@ func (r *RuleWrapper) HitCount() uint64 {
}
func (r *RuleWrapper) HitAt() time.Time {
return time.UnixMicro(r.hitAt.Load())
return r.hitAt.Load()
}
func (r *RuleWrapper) MissCount() uint64 {
@@ -37,7 +37,7 @@ func (r *RuleWrapper) MissCount() uint64 {
}
func (r *RuleWrapper) MissAt() time.Time {
return time.UnixMicro(r.missAt.Load())
return r.missAt.Load()
}
func (r *RuleWrapper) Unwrap() C.Rule {
@@ -46,12 +46,12 @@ func (r *RuleWrapper) Unwrap() C.Rule {
func (r *RuleWrapper) Hit() {
r.hitCount.Add(1)
r.hitAt.Store(time.Now().UnixMicro())
r.hitAt.Store(time.Now())
}
func (r *RuleWrapper) Miss() {
r.missCount.Add(1)
r.missAt.Store(time.Now().UnixMicro())
r.missAt.Store(time.Now())
}
func (r *RuleWrapper) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (bool, string) {
@@ -70,3 +70,41 @@ func (r *RuleWrapper) Match(metadata *C.Metadata, helper C.RuleMatchHelper) (boo
func NewRuleWrapper(rule C.Rule) C.RuleWrapper {
return &RuleWrapper{Rule: rule}
}
// atomicTime is a wrapper of [atomic.Int64] to provide atomic time storage.
// it only saves unix nanosecond export from time.Time.
// unlike atomic.TypedValue[time.Time] always escapes a new time.Time to heap when storing.
// that will lead to higher GC pressure during high frequency writes.
// be careful, it discards monotime so should not be used for internal time comparisons.
type atomicTime struct {
i atomic.Int64
}
func (t *atomicTime) Load() time.Time {
return time.Unix(0, t.i.Load())
}
func (t *atomicTime) Store(v time.Time) {
t.i.Store(v.UnixNano())
}
func (t *atomicTime) Swap(v time.Time) time.Time {
return time.Unix(0, t.i.Swap(v.UnixNano()))
}
func (t *atomicTime) CompareAndSwap(old, new time.Time) bool {
return t.i.CompareAndSwap(old.UnixNano(), new.UnixNano())
}
func (t *atomicTime) MarshalText() ([]byte, error) {
return t.Load().MarshalText()
}
func (t *atomicTime) UnmarshalText(text []byte) error {
var v time.Time
if err := v.UnmarshalText(text); err != nil {
return err
}
t.Store(v)
return nil
}