-
Notifications
You must be signed in to change notification settings - Fork 0
/
meta.go
146 lines (123 loc) · 2.6 KB
/
meta.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// Copyright(C) 2021 github.com/fsgo All Rights Reserved.
// Author: fsgo
// Date: 2021/4/12
package fspool
import (
"encoding/json"
"sync"
"time"
)
// CanMarkUsing 用于给 Pool 中的 Item 标记在使用中
type CanMarkUsing interface {
PEMarkUsing()
}
// CanMarkIdle 支持标记当前已处于空闲中
type CanMarkIdle interface {
PEMarkIdle()
}
// NewMetaInfo 创建一个 *MetaInfo
func NewMetaInfo() *MetaInfo {
return &MetaInfo{
meta: &Meta{
CreateTime: time.Now(),
},
}
}
var _ CanMarkUsing = (*MetaInfo)(nil)
var _ CanMarkIdle = (*MetaInfo)(nil)
// MetaInfo 包含创建时间和使用时间、使用次数等元信息
type MetaInfo struct {
meta *Meta
using bool
mu sync.Mutex
}
// PEMarkUsing 标记开始使用
func (w *MetaInfo) PEMarkUsing() {
now := time.Now()
w.mu.Lock()
w.using = true
w.meta.LastUseTime = now
w.meta.UsedTimes++
w.mu.Unlock()
}
// PEMarkIdle 标记当前处于空闲状态
func (w *MetaInfo) PEMarkIdle() {
now := time.Now()
w.mu.Lock()
w.using = false
w.meta.UsedDuration += now.Sub(w.meta.LastUseTime)
w.meta.LastUseTime = now
w.mu.Unlock()
}
// PESetID 给元素设置 ID
func (w *MetaInfo) PESetID(id uint64) {
w.mu.Lock()
w.meta.ID = id
w.mu.Unlock()
}
// Active 是否在有效期内
func (w *MetaInfo) Active(opt Option) error {
w.mu.Lock()
lastUse := w.meta.LastUseTime
w.mu.Unlock()
if opt.MaxIdleTime > 0 && time.Since(lastUse) >= opt.MaxIdleTime {
return ErrOutOfMaxIdleTime
}
if opt.MaxLifeTime > 0 && time.Since(w.meta.CreateTime) >= opt.MaxLifeTime {
return ErrOutOfMaxLife
}
return nil
}
// PEMeta 获取 meta 信息
func (w *MetaInfo) PEMeta() Meta {
w.mu.Lock()
m := *w.meta
w.mu.Unlock()
return m
}
func (w *MetaInfo) cloneMeta() *MetaInfo {
m := w.PEMeta()
return &MetaInfo{
meta: &m,
}
}
// HasMeta 判断是否支持读取 Meta 信息
type HasMeta interface {
PEMeta() Meta
}
// Meta 元信息
type Meta struct {
// CreateTime 创建时间
CreateTime time.Time
// LastUseTime 最后使用时间
LastUseTime time.Time
// ID 当前 Pool 创建的第N个元素
ID uint64
// UsedTimes 使用总次数
UsedTimes uint64
// UsedDuration 被使用的总时长
UsedDuration time.Duration
}
// String 序列化,调试用
func (m Meta) String() string {
bf, _ := json.Marshal(m)
return string(bf)
}
// ReadMeta 获取缓存信息的元信息,若没有,会返回 nil
func ReadMeta(item any) *Meta {
val := item
for {
if val == nil {
return nil
}
if ri, ok := val.(HasMeta); ok {
m := ri.PEMeta()
return &m
}
if rr, ok := val.(HasPERaw); ok {
val = rr.PERaw()
} else {
return nil
}
}
}