135 lines
2.3 KiB
Go
135 lines
2.3 KiB
Go
package mysql
|
|
|
|
// coverageNode record tcp package begin and end seq id
|
|
type coverageNode struct {
|
|
begin int64
|
|
end int64
|
|
|
|
next *coverageNode
|
|
crp *coveragePool
|
|
}
|
|
|
|
func newCoverage(begin, end int64) (*coverageNode) {
|
|
return &coverageNode{
|
|
begin: begin,
|
|
end: end,
|
|
}
|
|
}
|
|
|
|
func (crn *coverageNode) Recovery() {
|
|
crn.crp.Enqueue(crn)
|
|
}
|
|
|
|
type coverRanges struct {
|
|
head *coverageNode
|
|
}
|
|
|
|
func NewCoverRanges() *coverRanges {
|
|
return &coverRanges{
|
|
head: &coverageNode{
|
|
begin: -1,
|
|
end: -1,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (crs *coverRanges) clear() {
|
|
currRange := crs.head.next;
|
|
for currRange != nil {
|
|
node := currRange
|
|
currRange = currRange.next
|
|
node.Recovery()
|
|
}
|
|
crs.head.next = nil
|
|
}
|
|
|
|
func (crs *coverRanges) addRange(node *coverageNode) {
|
|
// insert range in asc order
|
|
var currRange = crs.head;
|
|
for currRange != nil && currRange.next != nil {
|
|
checkRange := currRange.next
|
|
if checkRange != nil && checkRange.begin >= node.begin {
|
|
currRange.next = node
|
|
node.next = checkRange
|
|
node = nil
|
|
break
|
|
}
|
|
|
|
currRange = checkRange
|
|
}
|
|
|
|
if node != nil && currRange != nil {
|
|
currRange.next = node
|
|
}
|
|
|
|
crs.mergeRanges()
|
|
}
|
|
|
|
func (crs *coverRanges) mergeRanges() {
|
|
// merge ranges
|
|
currRange := crs.head.next
|
|
for currRange != nil && currRange.next != nil {
|
|
checkRange := currRange.next
|
|
if currRange.begin <= checkRange.begin && currRange.end >= checkRange.begin && currRange.end < checkRange.end {
|
|
currRange.end = checkRange.end
|
|
currRange.next = checkRange.next
|
|
checkRange.Recovery()
|
|
|
|
} else {
|
|
currRange = currRange.next
|
|
}
|
|
}
|
|
}
|
|
|
|
type coveragePool struct {
|
|
queue chan *coverageNode
|
|
}
|
|
|
|
func NewCoveragePool() (cp *coveragePool) {
|
|
return &coveragePool{
|
|
queue: make(chan *coverageNode, 256),
|
|
}
|
|
}
|
|
|
|
func (crp *coveragePool) NewCoverage(begin, end int64) (cn *coverageNode) {
|
|
cn = crp.Dequeue()
|
|
cn.begin = begin
|
|
cn.end = end
|
|
return
|
|
}
|
|
|
|
func (crp *coveragePool) Enqueue(cn *coverageNode) {
|
|
// log.Debugf("coveragePool enqueue: %d", len(crp.queue))
|
|
if cn == nil {
|
|
return
|
|
}
|
|
|
|
select {
|
|
case crp.queue <- cn:
|
|
return
|
|
|
|
default:
|
|
cn = nil
|
|
}
|
|
}
|
|
|
|
func (crp *coveragePool) Dequeue() (cn *coverageNode) {
|
|
// log.Debugf("coveragePool dequeue: %d", len(crp.queue))
|
|
|
|
defer func() {
|
|
cn.begin = -1
|
|
cn.end = -1
|
|
cn.next = nil
|
|
cn.crp = crp
|
|
}()
|
|
|
|
select {
|
|
case cn = <-crp.queue:
|
|
return
|
|
|
|
default:
|
|
cn = &coverageNode{}
|
|
return
|
|
}
|
|
}
|