mirror of
https://github.com/duanhf2012/origin.git
synced 2026-02-03 22:45:13 +08:00
109 lines
2.5 KiB
Go
109 lines
2.5 KiB
Go
package messagequeueservice
|
||
|
||
import (
|
||
"github.com/duanhf2012/origin/v2/util/algorithms"
|
||
"sync"
|
||
)
|
||
|
||
type MemoryQueue struct {
|
||
subscriber *Subscriber
|
||
|
||
topicQueue []TopicData
|
||
head int32
|
||
tail int32
|
||
|
||
locker sync.RWMutex
|
||
}
|
||
|
||
func (mq *MemoryQueue) Init(cap int32) {
|
||
mq.topicQueue = make([]TopicData, cap+1)
|
||
}
|
||
|
||
// 从队尾Push数据
|
||
func (mq *MemoryQueue) Push(topicData *TopicData) bool {
|
||
mq.locker.Lock()
|
||
defer mq.locker.Unlock()
|
||
|
||
nextPos := (mq.tail + 1) % int32(len(mq.topicQueue))
|
||
//如果队列满了
|
||
if nextPos == mq.head {
|
||
//将对首的数据删除掉
|
||
mq.head++
|
||
mq.head = mq.head % int32(len(mq.topicQueue))
|
||
}
|
||
|
||
mq.tail = nextPos
|
||
mq.topicQueue[mq.tail] = *topicData
|
||
return true
|
||
}
|
||
|
||
func (mq *MemoryQueue) findData(startPos int32, startIndex uint64, limit int32) ([]TopicData, bool) {
|
||
//空队列,无数据
|
||
if mq.head == mq.tail {
|
||
return nil, true
|
||
}
|
||
|
||
var findStartPos int32
|
||
var findEndPos int32
|
||
findStartPos = startPos //(mq.head + 1) % cap(mq.topicQueue)
|
||
if findStartPos <= mq.tail {
|
||
findEndPos = mq.tail + 1
|
||
} else {
|
||
findEndPos = int32(len(mq.topicQueue))
|
||
}
|
||
|
||
if findStartPos >= findEndPos {
|
||
return nil, false
|
||
}
|
||
|
||
// 要取的Seq 比内存中最小的数据的Seq还小,那么需要返回错误
|
||
if mq.topicQueue[findStartPos].Seq > startIndex {
|
||
return nil, false
|
||
}
|
||
|
||
//二分查找位置
|
||
pos := int32(algorithms.BiSearch(mq.topicQueue[findStartPos:findEndPos], startIndex, 1))
|
||
if pos == -1 {
|
||
return nil, false
|
||
}
|
||
|
||
pos += findStartPos
|
||
//取得结束位置
|
||
endPos := limit + pos
|
||
if endPos > findEndPos {
|
||
endPos = findEndPos
|
||
}
|
||
|
||
return mq.topicQueue[pos:endPos], true
|
||
}
|
||
|
||
// FindData 返回参数[]TopicData 表示查找到的数据,nil表示无数据。bool表示是否不应该在内存中来查
|
||
func (mq *MemoryQueue) FindData(startIndex uint64, limit int32, dataQueue []TopicData) ([]TopicData, bool) {
|
||
mq.locker.RLock()
|
||
defer mq.locker.RUnlock()
|
||
|
||
//队列为空时,应该从数据库查找
|
||
if mq.head == mq.tail {
|
||
return nil, false
|
||
} else if mq.head < mq.tail {
|
||
// 队列没有折叠
|
||
datas,ret := mq.findData(mq.head + 1, startIndex, limit)
|
||
if ret {
|
||
dataQueue = append(dataQueue, datas...)
|
||
}
|
||
return dataQueue, ret
|
||
} else {
|
||
// 折叠先找后面的部分
|
||
datas,ret := mq.findData(mq.head+1, startIndex, limit)
|
||
if ret {
|
||
dataQueue = append(dataQueue, datas...)
|
||
return dataQueue, ret
|
||
}
|
||
|
||
// 后面没找到,从前面开始找
|
||
datas,ret = mq.findData(0, startIndex, limit)
|
||
dataQueue = append(dataQueue, datas...)
|
||
return dataQueue, ret
|
||
}
|
||
}
|