github.com/chain5j/chain5j-pkg@v1.0.7/collection/queues/queue/queue.go (about)

     1  // Package queue
     2  //
     3  // @author: xwc1125
     4  package queue
     5  
     6  import (
     7  	"fmt"
     8  	"log"
     9  	"sync"
    10  )
    11  
    12  type Element interface{}
    13  
    14  type Queue interface {
    15  	PushFront(e Element)   // 向队头添加元素
    16  	PushBack(e Element)    // 向队尾添加元素
    17  	PeekFront() Element    // 查看头部的元素
    18  	PeekBack() Element     // 查看尾部的元素
    19  	PollFront() Element    // 移除头部的元素
    20  	PollBack() Element     // 移除尾部的元素
    21  	Remove(e Element) bool // 删除一个值
    22  	Exist(e Element) bool  // 是否存在
    23  	Size() int             // 获取队列的元素个数
    24  	IsEmpty() bool         // 判断队列是否是空
    25  	Clear() bool           // 清空队列
    26  	NewIterator() *Iterator
    27  }
    28  
    29  type node struct {
    30  	value Element // 当前节点的值
    31  	prev  *node   // 前一个节点
    32  	next  *node   // 下一个节点
    33  }
    34  
    35  type LinkedQueue struct {
    36  	m    sync.Mutex
    37  	head *node // 头节点
    38  	tail *node // 尾节点
    39  	size int   // 大小
    40  }
    41  
    42  func NewLinkedQueue() *LinkedQueue {
    43  	return &LinkedQueue{
    44  		size: 0,
    45  	}
    46  }
    47  
    48  func (queue *LinkedQueue) PushFront(e Element) {
    49  	queue.m.Lock()
    50  	defer queue.m.Unlock()
    51  
    52  	newNode := &node{e, nil, queue.head}
    53  	if queue.head == nil {
    54  		queue.head = newNode
    55  		queue.tail = newNode
    56  	} else {
    57  		queue.head.prev = newNode
    58  		queue.head = newNode
    59  	}
    60  	queue.size++
    61  	newNode = nil
    62  }
    63  
    64  func (queue *LinkedQueue) PushBack(e Element) {
    65  	queue.m.Lock()
    66  	defer queue.m.Unlock()
    67  
    68  	newNode := &node{e, queue.tail, nil}
    69  	if queue.tail == nil {
    70  		queue.head = newNode
    71  		queue.tail = newNode
    72  	} else {
    73  		queue.tail.next = newNode
    74  		queue.tail = newNode
    75  	}
    76  	queue.size++
    77  	newNode = nil
    78  }
    79  
    80  func (queue *LinkedQueue) PeekFront() Element {
    81  	if queue.head == nil {
    82  		return nil
    83  	}
    84  	return queue.head.value
    85  }
    86  
    87  func (queue *LinkedQueue) PeekBack() Element {
    88  	if queue.tail == nil {
    89  		return nil
    90  	}
    91  	return queue.tail.value
    92  }
    93  
    94  // 移除队列中最前面的元素
    95  func (queue *LinkedQueue) PollFront() Element {
    96  	queue.m.Lock()
    97  	defer queue.m.Unlock()
    98  	if queue.IsEmpty() {
    99  		return nil
   100  	}
   101  	if queue.head == nil {
   102  		fmt.Println("Poll Empty queue.")
   103  		return nil
   104  	}
   105  	queue.size--
   106  
   107  	firstNode := queue.head
   108  	queue.head = firstNode.next
   109  	if queue.head != nil {
   110  		queue.head.prev = nil
   111  	} else {
   112  		queue.tail = nil
   113  	}
   114  
   115  	return firstNode.value
   116  }
   117  
   118  func (queue *LinkedQueue) PollBack() Element {
   119  	queue.m.Lock()
   120  	defer queue.m.Unlock()
   121  	if queue.IsEmpty() {
   122  		return nil
   123  	}
   124  	if queue.tail == nil {
   125  		fmt.Println("PollBottom Empty queue.")
   126  		return nil
   127  	}
   128  	queue.size--
   129  
   130  	latestNode := queue.tail
   131  	queue.tail = latestNode.prev
   132  	if queue.tail != nil {
   133  		queue.tail.prev = nil
   134  		queue.tail.next = nil
   135  	} else {
   136  		queue.head = nil
   137  	}
   138  
   139  	return latestNode.value
   140  }
   141  
   142  func (queue *LinkedQueue) Remove(e Element) bool {
   143  	queue.m.Lock()
   144  	defer queue.m.Unlock()
   145  	if queue.IsEmpty() {
   146  		return true
   147  	}
   148  	if queue.head == nil {
   149  		return true
   150  	}
   151  	firstNode := queue.head
   152  	queue.del(firstNode, e)
   153  	return true
   154  }
   155  
   156  func (queue *LinkedQueue) del(cNode *node, e Element) *node {
   157  	if queue.IsEmpty() {
   158  		return nil
   159  	}
   160  	if cNode == nil {
   161  		return nil
   162  	}
   163  	nNode := *cNode
   164  	prev := cNode.prev
   165  	next2 := cNode.next
   166  	if cNode.value == e {
   167  		// 查找元素
   168  		if prev == nil && next2 == nil {
   169  			queue.head = nil
   170  			queue.tail = nil
   171  		}
   172  		if prev != nil {
   173  			prev.next = next2
   174  		}
   175  		if next2 != nil {
   176  			next2.prev = prev
   177  		}
   178  		cNode.value = nil
   179  		queue.size--
   180  		return &nNode
   181  	}
   182  	return queue.del(next2, e)
   183  }
   184  
   185  func (queue *LinkedQueue) Exist(e Element) bool {
   186  	queue.m.Lock()
   187  	defer queue.m.Unlock()
   188  	if queue.IsEmpty() {
   189  		return false
   190  	}
   191  	if queue.head == nil {
   192  		return false
   193  	}
   194  	firstNode := queue.head
   195  	return queue.exist(firstNode, e)
   196  }
   197  
   198  func (queue *LinkedQueue) exist(cNode *node, e Element) bool {
   199  	defer func() {
   200  		if err := recover(); err != nil {
   201  			log.Println("LinkedQueue exist", "err", err)
   202  		}
   203  	}()
   204  	if queue.IsEmpty() {
   205  		return false
   206  	}
   207  	next2 := cNode.next
   208  	if cNode.value == e {
   209  		// 查找元素
   210  		return true
   211  	}
   212  	return queue.exist(next2, e)
   213  }
   214  
   215  func (queue *LinkedQueue) Size() int {
   216  	return queue.size
   217  }
   218  
   219  func (queue *LinkedQueue) IsEmpty() bool {
   220  	if queue.size == 0 {
   221  		return true
   222  	}
   223  	return false
   224  }
   225  
   226  func (queue *LinkedQueue) Clear() bool {
   227  	if queue.IsEmpty() {
   228  		return false
   229  	}
   230  	queue.m.Lock()
   231  	defer queue.m.Unlock()
   232  
   233  	queue.remove()
   234  	return true
   235  }
   236  
   237  func (queue *LinkedQueue) remove() {
   238  	if !queue.IsEmpty() {
   239  		firstNode := queue.head
   240  		if firstNode != nil {
   241  			queue.head = firstNode.next
   242  			firstNode.next = nil
   243  			firstNode.value = nil
   244  		}
   245  		queue.size--
   246  		queue.remove()
   247  	}
   248  }
   249  
   250  // NewIterator creates a new iterator for the cache.
   251  func (queue *LinkedQueue) NewIterator() *Iterator {
   252  	return &Iterator{
   253  		current: queue.head,
   254  	}
   255  }