2017-12-29 16:03:30 +08:00
|
|
|
|
// Copyright 2017 gf Author(https://gitee.com/johng/gf). All Rights Reserved.
|
|
|
|
|
|
//
|
|
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
|
|
|
|
|
// You can obtain one at https://gitee.com/johng/gf.
|
|
|
|
|
|
//
|
2017-12-31 18:19:58 +08:00
|
|
|
|
|
2018-02-28 12:01:14 +08:00
|
|
|
|
// 并发安全的双向链表.
|
2017-11-23 10:21:28 +08:00
|
|
|
|
package glist
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
2018-04-15 22:02:06 +08:00
|
|
|
|
"container/list"
|
2018-09-05 18:34:41 +08:00
|
|
|
|
"gitee.com/johng/gf/g/container/internal/rwmutex"
|
2017-11-23 10:21:28 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// 变长双向链表
|
2018-03-01 17:07:53 +08:00
|
|
|
|
type List struct {
|
2018-09-05 18:34:41 +08:00
|
|
|
|
mu *rwmutex.RWMutex
|
2018-01-16 15:38:53 +08:00
|
|
|
|
list *list.List
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获得一个变长链表指针
|
2018-09-05 18:34:41 +08:00
|
|
|
|
func New(safe...bool) *List {
|
|
|
|
|
|
return &List{
|
|
|
|
|
|
mu : rwmutex.New(safe...),
|
|
|
|
|
|
list : list.New(),
|
|
|
|
|
|
}
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 往链表头入栈数据项
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) PushFront(v interface{}) *list.Element {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
e := this.list.PushFront(v)
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return e
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 往链表尾入栈数据项
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) PushBack(v interface{}) *list.Element {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
r := this.list.PushBack(v)
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在list 中元素mark之后插入一个值为v的元素,并返回该元素,如果mark不是list中元素,则list不改变。
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) InsertAfter(v interface{}, mark *list.Element) *list.Element {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
r := this.list.InsertAfter(v, mark)
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 在list 中元素mark之前插入一个值为v的元素,并返回该元素,如果mark不是list中元素,则list不改变。
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) InsertBefore(v interface{}, mark *list.Element) *list.Element {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
r := this.list.InsertBefore(v, mark)
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 批量往链表头入栈数据项
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) BatchPushFront(vs []interface{}) {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
for _, item := range vs {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.list.PushFront(item)
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从链表尾端出栈数据项(删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) PopBack() interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
if elem := this.list.Back(); elem != nil {
|
|
|
|
|
|
item := this.list.Remove(elem)
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return item
|
|
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-15 17:23:22 +08:00
|
|
|
|
// 从链表头端出栈数据项(删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) PopFront() interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
if elem := this.list.Front(); elem != nil {
|
|
|
|
|
|
item := this.list.Remove(elem)
|
|
|
|
|
|
this.mu.Unlock()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
return item
|
|
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-23 10:21:28 +08:00
|
|
|
|
// 批量从链表尾端出栈数据项(删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) BatchPopBack(max int) []interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
count := this.list.Len()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
if count == 0 {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return []interface{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if count > max {
|
|
|
|
|
|
count = max
|
|
|
|
|
|
}
|
2018-01-15 17:23:22 +08:00
|
|
|
|
items := make([]interface{}, count)
|
2017-11-23 10:21:28 +08:00
|
|
|
|
for i := 0; i < count; i++ {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
items[i] = this.list.Remove(this.list.Back())
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return items
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-15 17:23:22 +08:00
|
|
|
|
// 批量从链表头端出栈数据项(删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) BatchPopFront(max int) []interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
count := this.list.Len()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
if count == 0 {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return []interface{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-15 17:23:22 +08:00
|
|
|
|
if count > max {
|
|
|
|
|
|
count = max
|
|
|
|
|
|
}
|
|
|
|
|
|
items := make([]interface{}, count)
|
2017-11-23 10:21:28 +08:00
|
|
|
|
for i := 0; i < count; i++ {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
items[i] = this.list.Remove(this.list.Front())
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
return items
|
|
|
|
|
|
}
|
2017-11-23 10:21:28 +08:00
|
|
|
|
|
2018-01-15 17:23:22 +08:00
|
|
|
|
// 批量从链表尾端依次获取所有数据(删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) PopBackAll() []interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
count := this.list.Len()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
if count == 0 {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
return []interface{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
items := make([]interface{}, count)
|
|
|
|
|
|
for i := 0; i < count; i++ {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
items[i] = this.list.Remove(this.list.Back())
|
2018-01-15 17:23:22 +08:00
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return items
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-15 17:23:22 +08:00
|
|
|
|
// 批量从链表头端依次获取所有数据(删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) PopFrontAll() []interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
count := this.list.Len()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
if count == 0 {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
return []interface{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
items := make([]interface{}, count)
|
|
|
|
|
|
for i := 0; i < count; i++ {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
items[i] = this.list.Remove(this.list.Front())
|
2018-01-15 17:23:22 +08:00
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Unlock()
|
2018-01-15 17:23:22 +08:00
|
|
|
|
return items
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-23 10:21:28 +08:00
|
|
|
|
// 删除数据项
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) Remove(e *list.Element) interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
r := this.list.Remove(e)
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 删除所有数据项
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) RemoveAll() {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.Lock()
|
|
|
|
|
|
this.list = list.New()
|
|
|
|
|
|
this.mu.Unlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从链表头获取所有数据(不删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) FrontAll() []interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
count := this.list.Len()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
if count == 0 {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return []interface{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
items := make([]interface{}, 0, count)
|
2018-01-16 15:38:53 +08:00
|
|
|
|
for e := this.list.Front(); e != nil; e = e.Next() {
|
2017-11-23 10:21:28 +08:00
|
|
|
|
items = append(items, e.Value)
|
|
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return items
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从链表尾获取所有数据(不删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) BackAll() []interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
count := this.list.Len()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
if count == 0 {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return []interface{}{}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
items := make([]interface{}, 0, count)
|
2018-01-16 15:38:53 +08:00
|
|
|
|
for e := this.list.Back(); e != nil; e = e.Prev() {
|
2017-11-23 10:21:28 +08:00
|
|
|
|
items = append(items, e.Value)
|
|
|
|
|
|
}
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return items
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取链表头值(不删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) FrontItem() interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
if f := this.list.Front(); f != nil {
|
|
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return f.Value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取链表尾值(不删除)
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) BackItem() interface{} {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
if f := this.list.Back(); f != nil {
|
|
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return f.Value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return nil
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表头指针
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) Front() *list.Element {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
r := this.list.Front()
|
|
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表位指针
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) Back() *list.Element {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
r := this.list.Back()
|
|
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return r
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取链表长度
|
2018-03-01 17:07:53 +08:00
|
|
|
|
func (this *List) Len() int {
|
2018-01-16 15:38:53 +08:00
|
|
|
|
this.mu.RLock()
|
|
|
|
|
|
length := this.list.Len()
|
|
|
|
|
|
this.mu.RUnlock()
|
2017-11-23 10:21:28 +08:00
|
|
|
|
return length
|
|
|
|
|
|
}
|