forked from Sansui233/proxypool
/
statistic.go
130 lines (118 loc) · 2.73 KB
/
statistic.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
package healthcheck
import "github.com/One-Piecs/proxypool/pkg/proxy"
// Statistic for a proxy
type Stat struct {
Speed float64
Delay uint16
ReqCount uint16
Relay bool
Pool bool
ChatGPT bool
OutIp string
Id string
}
// Statistic array for proxies
type StatList []Stat
// ProxyStats stores proxies' statistics
var ProxyStats StatList
func init() {
ProxyStats = make(StatList, 0)
}
// Update speed for a Stat
func (ps *Stat) UpdatePSSpeed(speed float64) {
if ps.Speed < 60 && ps.Speed != 0 {
ps.Speed = 0.3*ps.Speed + 0.7*speed
} else {
ps.Speed = speed
}
}
// Update delay for a Stat
func (ps *Stat) UpdatePSDelay(delay uint16) {
ps.Delay = delay
}
// Update out ip for a Stat
func (ps *Stat) UpdatePSOutIp(outIp string) {
ps.OutIp = outIp
}
// Count + 1 for a Stat
func (ps *Stat) UpdatePSCount() {
ps.ReqCount++
}
// Find a proxy's Stat in StatList
func (psList StatList) Find(p proxy.Proxy) (*Stat, bool) {
s := p.Identifier()
for i := range psList {
if psList[i].Id == s {
return &psList[i], true
}
}
return nil, false
}
// Return proxies that request count more than a given nubmer
func (psList StatList) ReqCountThan(n uint16, pl []proxy.Proxy, reset bool) []proxy.Proxy {
proxies := make([]proxy.Proxy, 0)
for _, p := range pl {
for j := range psList {
if psList[j].ReqCount > n && p.Identifier() == psList[j].Id {
proxies = append(proxies, p)
}
}
}
// reset request count
if reset {
for i := range psList {
psList[i].ReqCount = 0
}
}
return proxies
}
// Sort proxies by speed. Notice that this returns the same pointer.
func (psList StatList) SortProxiesBySpeed(proxies []proxy.Proxy) []proxy.Proxy {
if ok := checkErrorProxies(proxies); !ok {
return proxies
}
l := len(proxies)
if l == 1 {
return proxies
}
// Classic bubble Sort. Biggest the first
for i := 0; i < l-1; i++ { // i defines unsorted list bound
flag := false
for j := 0; j < l-1-i; j++ {
ps1, ok1 := psList.Find(proxies[j])
ps2, ok2 := psList.Find(proxies[j+1])
// validate records, put no record proxy behind
if !ok2 {
continue
} else if !ok1 && ok2 {
t := proxies[j]
proxies[j] = proxies[j+1]
proxies[j+1] = t
flag = true
continue
}
// else: validate speed value, put zero speed proxy behind
if ps2.Speed == 0 {
continue
} else if ps1.Speed == 0 { // when ps2.speed != 0, validate ps1
t := proxies[j]
proxies[j] = proxies[j+1]
proxies[j+1] = t
flag = true
continue
} else {
// Reach the real speed sort. Too much code on validation. I'm so tired
if ps1.Speed < ps2.Speed {
t := proxies[j]
proxies[j] = proxies[j+1]
proxies[j+1] = t
flag = true
}
}
}
if !flag {
break
}
}
return proxies
}