list.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. package util
  2. // 带回收功能的泛型双向链表
  3. type IList[T any] interface {
  4. Push(*ListItem[T])
  5. Shift() *ListItem[T]
  6. Clear()
  7. }
  8. type ListItem[T any] struct {
  9. Value T
  10. Next, Pre *ListItem[T] `json:"-" yaml:"-"`
  11. Pool *List[T] `json:"-" yaml:"-"` // 回收池
  12. list *List[T]
  13. reset bool // 是否需要重置
  14. }
  15. func NewListItem[T any](value T) *ListItem[T] {
  16. return &ListItem[T]{Value: value, reset: true}
  17. }
  18. func (item *ListItem[T]) InsertBefore(insert *ListItem[T]) {
  19. if insert.list != nil {
  20. panic("item already in list")
  21. }
  22. item.Pre.InsertAfter(insert)
  23. }
  24. func (item *ListItem[T]) InsertBeforeValue(value T) (result *ListItem[T]) {
  25. result = &ListItem[T]{Value: value}
  26. item.InsertBefore(result)
  27. return
  28. }
  29. func (item *ListItem[T]) InsertAfter(insert *ListItem[T]) {
  30. if insert.list != nil {
  31. panic("item already in list")
  32. }
  33. insert.list = item.list
  34. insert.Next = item.Next
  35. insert.Pre = item
  36. item.Next.Pre = insert
  37. item.Next = insert
  38. item.list.Length++
  39. }
  40. func (item *ListItem[T]) InsertAfterValue(value T) (result *ListItem[T]) {
  41. result = &ListItem[T]{Value: value}
  42. item.InsertAfter(result)
  43. return
  44. }
  45. func (item *ListItem[T]) IsRoot() bool {
  46. return &item.list.ListItem == item
  47. }
  48. func (item *ListItem[T]) Recycle() {
  49. hasPool := item.list != item.Pool && item.Pool != nil && item.Pool.Length < PoolSize
  50. if item.reset || !hasPool {
  51. var null T
  52. item.Value = null
  53. }
  54. if hasPool {
  55. item.Pool.Push(item)
  56. } else {
  57. item.Pool = nil
  58. item.list = nil
  59. item.Next = nil
  60. item.Pre = nil
  61. }
  62. }
  63. func (item *ListItem[T]) Range(do func(value T) bool) {
  64. item.RangeItem(func(item *ListItem[T]) bool {
  65. return do(item.Value)
  66. })
  67. }
  68. func (item *ListItem[T]) RangeItem(do func(*ListItem[T]) bool) {
  69. for ; item != nil && item.list != nil && !item.IsRoot() && do(item); item = item.Next {
  70. }
  71. }
  72. type List[T any] struct {
  73. ListItem[T]
  74. Length int
  75. }
  76. func (p *List[T]) PushValue(value T) {
  77. p.Push(&ListItem[T]{Value: value, reset: true})
  78. }
  79. func (p *List[T]) Push(item *ListItem[T]) {
  80. if item.list != nil {
  81. panic("item already in list")
  82. }
  83. if p.Length == 0 {
  84. p.Next = &p.ListItem
  85. p.Pre = &p.ListItem
  86. p.ListItem.list = p
  87. }
  88. p.Pre.InsertAfter(item)
  89. }
  90. func (p *List[T]) UnshiftValue(value T) {
  91. p.Unshift(&ListItem[T]{Value: value})
  92. }
  93. func (p *List[T]) Unshift(item *ListItem[T]) {
  94. if item.list != nil {
  95. panic("item already in list")
  96. }
  97. if p.Length == 0 {
  98. p.Next = &p.ListItem
  99. p.Pre = &p.ListItem
  100. p.ListItem.list = p
  101. }
  102. p.Next.InsertBefore(item)
  103. }
  104. func (p *List[T]) ShiftValue() T {
  105. return p.Shift().Value
  106. }
  107. func (p *List[T]) PoolShift() (head *ListItem[T]) {
  108. if head = p.Shift(); head == nil {
  109. head = &ListItem[T]{Pool: p}
  110. }
  111. return
  112. }
  113. func (p *List[T]) Shift() (head *ListItem[T]) {
  114. if p.Length == 0 {
  115. return
  116. }
  117. head = p.Next
  118. p.Next = head.Next
  119. head.Pre = nil
  120. head.Next = nil
  121. head.list = nil
  122. p.Length--
  123. return
  124. }
  125. func (p *List[T]) Clear() {
  126. p.Next = &p.ListItem
  127. p.Pre = &p.ListItem
  128. p.Length = 0
  129. }
  130. func (p *List[T]) Range(do func(value T) bool) {
  131. if p.Length > 0 {
  132. p.Next.Range(do)
  133. }
  134. }
  135. func (p *List[T]) RangeItem(do func(*ListItem[T]) bool) {
  136. if p.Length > 0 {
  137. p.Next.RangeItem(do)
  138. }
  139. }
  140. func (p *List[T]) Recycle() {
  141. for item := p.Shift(); item != nil; item = p.Shift() {
  142. item.Recycle()
  143. }
  144. if p.Length != 0 {
  145. panic("recycle list error")
  146. }
  147. }
  148. // Transfer 把链表中的所有元素转移到另一个链表中
  149. func (p *List[T]) Transfer(target IList[T]) {
  150. for item := p.Shift(); item != nil; item = p.Shift() {
  151. target.Push(item)
  152. }
  153. if p.Length != 0 {
  154. panic("transfer list error")
  155. }
  156. }