1 Star 1 Fork 0

D10.天地弦/gobase

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
dlink.go 5.58 KB
一键复制 编辑 原始数据 按行查看 历史
D10.天地弦 提交于 2023-11-11 11:26 . * gobase 文件整理
package gobase
import (
"sync"
"sync/atomic"
)
/***
dlink 是一个基础类, 一般不直接对外服务
基于dlink进行封装的有 SyncQueue
dlinklist 加入游标
初始化, 游标在头部
SeekFirst 游标移动到头部, 如果没有值返回nil
SeekLast 游标移动到尾部, 如果没有值返回nil
FetchNext 游标移动到下一个, 如果已经到底尾部,返回nil
如果移除元素是当前元素,则游标移动到之前元素的下一个
*/
type DLinkNode struct {
tag byte
owner *DLinklist
pre *DLinkNode
next *DLinkNode
Value interface{}
poolflag int32 // 如果是Pool则1为使用, 2未使用
}
var (
link_node_pool *sync.Pool = &sync.Pool{New: func() interface{} {
return &DLinkNode{
pre: nil,
next: nil,
Value: nil,
poolflag: 2,
}
}}
)
type DLinklist struct {
head *DLinkNode
tail *DLinkNode
fixedHead *DLinkNode
fixedTail *DLinkNode
cursor *DLinkNode
cnt int32
}
func NewDlinknodeFromPool() *DLinkNode {
rval := link_node_pool.Get().(*DLinkNode)
rval.poolflag = 1 // 正在使用
return rval
}
func NewDlinknode() *DLinkNode {
return &DLinkNode{
pre: nil,
next: nil,
Value: nil,
}
}
func (this *DLinkNode) Next() *DLinkNode {
return this.next
}
func (this *DLinkNode) release2Pool() {
if atomic.CompareAndSwapInt32(&this.poolflag, 1, 2) {
this.Value = nil
link_node_pool.Put(this)
}
}
func NewDlinklist() *DLinklist {
rval := &DLinklist{
head: nil,
tail: nil,
fixedHead: NewDlinknode(),
fixedTail: NewDlinknode(),
cnt: 0,
}
rval.init()
return rval
}
func (this *DLinklist) init() {
this.head = this.fixedHead
this.tail = this.fixedTail
this.head.next = this.tail
this.tail.pre = this.head
this.fixedHead.Value = "fixHead"
this.fixedHead.tag = 0xFF
this.fixedTail.Value = "fixTail"
this.fixedTail.tag = 0xFE
this.cursor = this.head
}
/**
* 插入一个节点到头部, 该节点的pre, next会被改变
*/
func (this *DLinklist) InsertToFirst(node *DLinkNode) {
this.head.next.pre = node
node.next = this.head.next
node.pre = this.head
this.head.next = node
node.owner = this
this.cnt++
}
/**
* 插入一个节点到尾部, 该节点的pre, next会被改变
*/
func (this *DLinklist) Append(node *DLinkNode) {
this.tail.pre.next = node
node.pre = this.tail.pre
node.next = this.tail
node.owner = this
this.tail.pre = node
this.cnt++
}
func (this *DLinklist) AppendValue(v interface{}) {
this.Append(&DLinkNode{Value: v})
}
/**
* 移除一个元素,注意该元素必须是列表中的元素,否则 元素数量会出错
*/
func (this *DLinklist) Remove(node *DLinkNode) bool {
if this.cnt == 0 {
return false
}
if node.next == nil || node.pre == nil || node.owner != this {
return false
}
if this.cursor == node {
this.FetchNext()
}
node.pre.next = node.next
node.next.pre = node.pre
// 再次进行移除时, 可以进行判断
node.pre = nil
node.next = nil
this.cnt--
return true
}
func (this *DLinklist) SeekFirst() *DLinkNode {
if this.Count() == 0 {
this.cursor = this.head
return nil
}
this.cursor = this.head.next
return this.cursor
}
func (this *DLinklist) SeekLast() *DLinkNode {
if this.Count() == 0 {
this.cursor = this.tail
return nil
}
this.cursor = this.tail.pre
return this.cursor
}
func (this *DLinklist) FetchNext() *DLinkNode {
if this.cursor == this.tail || this.cursor.next == this.tail {
this.cursor = this.tail
return nil
}
this.cursor = this.cursor.next
return this.cursor
}
func (this *DLinklist) FetchPre() *DLinkNode {
if this.cursor == this.head || this.cursor.pre == this.head {
this.cursor = this.head
return nil
}
this.cursor = this.cursor.pre
return this.cursor
}
/**
* 移除头部一个节点, 返回该节点, 如果为空返回nil
*/
func (this *DLinklist) First() *DLinkNode {
if this.cnt == 0 {
return nil
}
rval := this.head.next
return rval
}
func (this *DLinklist) Count() int32 {
return this.cnt
}
func (this *DLinklist) List() []interface{} {
if this.cnt == 0 {
return nil
}
lst := make([]interface{}, 0, this.cnt)
node := this.head.next
for node != this.tail {
lst = append(lst, node.Value)
node = node.next
}
return lst
}
func (this *DLinklist) Nodes() []*DLinkNode {
if this.cnt == 0 {
return nil
}
lst := make([]*DLinkNode, 0, this.cnt)
node := this.head.next
for node != this.tail {
lst = append(lst, node)
node = node.next
}
return lst
}
/**
* 移除头部一个节点, 返回该节点, 如果为空返回nil
*/
func (this *DLinklist) RemoveFirst() *DLinkNode {
if this.cnt == 0 {
return nil
}
rval := this.head.next
this.Remove(rval)
return rval
}
/**
* 移除尾部一个节点, 返回该节点, 如果为空返回nil
*/
func (this *DLinklist) RemoveLast() *DLinkNode {
if this.cnt == 0 {
return nil
}
rval := this.tail.pre
this.Remove(rval)
return rval
}
/**
* 循环
*/
func (this *DLinklist) Range(cb func(val interface{}) bool) int {
if this.cnt == 0 {
return 0
}
node := this.head.next
i := 0
for node != this.tail {
if cb(node.Value) {
i++
}
node = node.next
}
return i
}
/**
* 循环
*/
func (this *DLinklist) RangeEx(cb func(idx int, val interface{}, removeit *bool) bool, onremove func(node *DLinkNode)) int {
if this.cnt == 0 {
return 0
}
node := this.head.next
i := 0
removeit := false
for node != this.tail {
removeit = false
tmpNode := node
r := cb(i, tmpNode.Value, &removeit)
node = node.next
if removeit {
this.Remove(tmpNode)
if onremove != nil {
onremove(tmpNode)
}
}
if !r {
break
}
i++
}
return i
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ymofen/gobase.git
git@gitee.com:ymofen/gobase.git
ymofen
gobase
gobase
v1.2.24053

搜索帮助

D67c1975 1850385 1daf7b77 1850385