glist.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. // Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with l file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. //
  7. // Package glist provides most commonly used doubly linked list container which also supports concurrent-safe/unsafe switch feature.
  8. package glist
  9. import (
  10. "bytes"
  11. "container/list"
  12. "github.com/gogf/gf/internal/json"
  13. "github.com/gogf/gf/util/gconv"
  14. "github.com/gogf/gf/internal/rwmutex"
  15. )
  16. type (
  17. // List is a doubly linked list containing a concurrent-safe/unsafe switch.
  18. // The switch should be set when its initialization and cannot be changed then.
  19. List struct {
  20. mu rwmutex.RWMutex
  21. list *list.List
  22. }
  23. // Element the item type of the list.
  24. Element = list.Element
  25. )
  26. // New creates and returns a new empty doubly linked list.
  27. func New(safe ...bool) *List {
  28. return &List{
  29. mu: rwmutex.Create(safe...),
  30. list: list.New(),
  31. }
  32. }
  33. // NewFrom creates and returns a list from a copy of given slice <array>.
  34. // The parameter <safe> is used to specify whether using list in concurrent-safety,
  35. // which is false in default.
  36. func NewFrom(array []interface{}, safe ...bool) *List {
  37. l := list.New()
  38. for _, v := range array {
  39. l.PushBack(v)
  40. }
  41. return &List{
  42. mu: rwmutex.Create(safe...),
  43. list: l,
  44. }
  45. }
  46. // PushFront inserts a new element <e> with value <v> at the front of list <l> and returns <e>.
  47. func (l *List) PushFront(v interface{}) (e *Element) {
  48. l.mu.Lock()
  49. if l.list == nil {
  50. l.list = list.New()
  51. }
  52. e = l.list.PushFront(v)
  53. l.mu.Unlock()
  54. return
  55. }
  56. // PushBack inserts a new element <e> with value <v> at the back of list <l> and returns <e>.
  57. func (l *List) PushBack(v interface{}) (e *Element) {
  58. l.mu.Lock()
  59. if l.list == nil {
  60. l.list = list.New()
  61. }
  62. e = l.list.PushBack(v)
  63. l.mu.Unlock()
  64. return
  65. }
  66. // PushFronts inserts multiple new elements with values <values> at the front of list <l>.
  67. func (l *List) PushFronts(values []interface{}) {
  68. l.mu.Lock()
  69. if l.list == nil {
  70. l.list = list.New()
  71. }
  72. for _, v := range values {
  73. l.list.PushFront(v)
  74. }
  75. l.mu.Unlock()
  76. }
  77. // PushBacks inserts multiple new elements with values <values> at the back of list <l>.
  78. func (l *List) PushBacks(values []interface{}) {
  79. l.mu.Lock()
  80. if l.list == nil {
  81. l.list = list.New()
  82. }
  83. for _, v := range values {
  84. l.list.PushBack(v)
  85. }
  86. l.mu.Unlock()
  87. }
  88. // PopBack removes the element from back of <l> and returns the value of the element.
  89. func (l *List) PopBack() (value interface{}) {
  90. l.mu.Lock()
  91. defer l.mu.Unlock()
  92. if l.list == nil {
  93. l.list = list.New()
  94. return
  95. }
  96. if e := l.list.Back(); e != nil {
  97. value = l.list.Remove(e)
  98. }
  99. return
  100. }
  101. // PopFront removes the element from front of <l> and returns the value of the element.
  102. func (l *List) PopFront() (value interface{}) {
  103. l.mu.Lock()
  104. defer l.mu.Unlock()
  105. if l.list == nil {
  106. l.list = list.New()
  107. return
  108. }
  109. if e := l.list.Front(); e != nil {
  110. value = l.list.Remove(e)
  111. }
  112. return
  113. }
  114. // PopBacks removes <max> elements from back of <l>
  115. // and returns values of the removed elements as slice.
  116. func (l *List) PopBacks(max int) (values []interface{}) {
  117. l.mu.Lock()
  118. defer l.mu.Unlock()
  119. if l.list == nil {
  120. l.list = list.New()
  121. return
  122. }
  123. length := l.list.Len()
  124. if length > 0 {
  125. if max > 0 && max < length {
  126. length = max
  127. }
  128. values = make([]interface{}, length)
  129. for i := 0; i < length; i++ {
  130. values[i] = l.list.Remove(l.list.Back())
  131. }
  132. }
  133. return
  134. }
  135. // PopFronts removes <max> elements from front of <l>
  136. // and returns values of the removed elements as slice.
  137. func (l *List) PopFronts(max int) (values []interface{}) {
  138. l.mu.Lock()
  139. defer l.mu.Unlock()
  140. if l.list == nil {
  141. l.list = list.New()
  142. return
  143. }
  144. length := l.list.Len()
  145. if length > 0 {
  146. if max > 0 && max < length {
  147. length = max
  148. }
  149. values = make([]interface{}, length)
  150. for i := 0; i < length; i++ {
  151. values[i] = l.list.Remove(l.list.Front())
  152. }
  153. }
  154. return
  155. }
  156. // PopBackAll removes all elements from back of <l>
  157. // and returns values of the removed elements as slice.
  158. func (l *List) PopBackAll() []interface{} {
  159. return l.PopBacks(-1)
  160. }
  161. // PopFrontAll removes all elements from front of <l>
  162. // and returns values of the removed elements as slice.
  163. func (l *List) PopFrontAll() []interface{} {
  164. return l.PopFronts(-1)
  165. }
  166. // FrontAll copies and returns values of all elements from front of <l> as slice.
  167. func (l *List) FrontAll() (values []interface{}) {
  168. l.mu.RLock()
  169. defer l.mu.RUnlock()
  170. if l.list == nil {
  171. return
  172. }
  173. length := l.list.Len()
  174. if length > 0 {
  175. values = make([]interface{}, length)
  176. for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
  177. values[i] = e.Value
  178. }
  179. }
  180. return
  181. }
  182. // BackAll copies and returns values of all elements from back of <l> as slice.
  183. func (l *List) BackAll() (values []interface{}) {
  184. l.mu.RLock()
  185. defer l.mu.RUnlock()
  186. if l.list == nil {
  187. return
  188. }
  189. length := l.list.Len()
  190. if length > 0 {
  191. values = make([]interface{}, length)
  192. for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
  193. values[i] = e.Value
  194. }
  195. }
  196. return
  197. }
  198. // FrontValue returns value of the first element of <l> or nil if the list is empty.
  199. func (l *List) FrontValue() (value interface{}) {
  200. l.mu.RLock()
  201. defer l.mu.RUnlock()
  202. if l.list == nil {
  203. return
  204. }
  205. if e := l.list.Front(); e != nil {
  206. value = e.Value
  207. }
  208. return
  209. }
  210. // BackValue returns value of the last element of <l> or nil if the list is empty.
  211. func (l *List) BackValue() (value interface{}) {
  212. l.mu.RLock()
  213. defer l.mu.RUnlock()
  214. if l.list == nil {
  215. return
  216. }
  217. if e := l.list.Back(); e != nil {
  218. value = e.Value
  219. }
  220. return
  221. }
  222. // Front returns the first element of list <l> or nil if the list is empty.
  223. func (l *List) Front() (e *Element) {
  224. l.mu.RLock()
  225. defer l.mu.RUnlock()
  226. if l.list == nil {
  227. return
  228. }
  229. e = l.list.Front()
  230. return
  231. }
  232. // Back returns the last element of list <l> or nil if the list is empty.
  233. func (l *List) Back() (e *Element) {
  234. l.mu.RLock()
  235. defer l.mu.RUnlock()
  236. if l.list == nil {
  237. return
  238. }
  239. e = l.list.Back()
  240. return
  241. }
  242. // Len returns the number of elements of list <l>.
  243. // The complexity is O(1).
  244. func (l *List) Len() (length int) {
  245. l.mu.RLock()
  246. defer l.mu.RUnlock()
  247. if l.list == nil {
  248. return
  249. }
  250. length = l.list.Len()
  251. return
  252. }
  253. // Size is alias of Len.
  254. func (l *List) Size() int {
  255. return l.Len()
  256. }
  257. // MoveBefore moves element <e> to its new position before <p>.
  258. // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
  259. // The element and <p> must not be nil.
  260. func (l *List) MoveBefore(e, p *Element) {
  261. l.mu.Lock()
  262. defer l.mu.Unlock()
  263. if l.list == nil {
  264. l.list = list.New()
  265. }
  266. l.list.MoveBefore(e, p)
  267. }
  268. // MoveAfter moves element <e> to its new position after <p>.
  269. // If <e> or <p> is not an element of <l>, or <e> == <p>, the list is not modified.
  270. // The element and <p> must not be nil.
  271. func (l *List) MoveAfter(e, p *Element) {
  272. l.mu.Lock()
  273. defer l.mu.Unlock()
  274. if l.list == nil {
  275. l.list = list.New()
  276. }
  277. l.list.MoveAfter(e, p)
  278. }
  279. // MoveToFront moves element <e> to the front of list <l>.
  280. // If <e> is not an element of <l>, the list is not modified.
  281. // The element must not be nil.
  282. func (l *List) MoveToFront(e *Element) {
  283. l.mu.Lock()
  284. defer l.mu.Unlock()
  285. if l.list == nil {
  286. l.list = list.New()
  287. }
  288. l.list.MoveToFront(e)
  289. }
  290. // MoveToBack moves element <e> to the back of list <l>.
  291. // If <e> is not an element of <l>, the list is not modified.
  292. // The element must not be nil.
  293. func (l *List) MoveToBack(e *Element) {
  294. l.mu.Lock()
  295. defer l.mu.Unlock()
  296. if l.list == nil {
  297. l.list = list.New()
  298. }
  299. l.list.MoveToBack(e)
  300. }
  301. // PushBackList inserts a copy of an other list at the back of list <l>.
  302. // The lists <l> and <other> may be the same, but they must not be nil.
  303. func (l *List) PushBackList(other *List) {
  304. if l != other {
  305. other.mu.RLock()
  306. defer other.mu.RUnlock()
  307. }
  308. l.mu.Lock()
  309. defer l.mu.Unlock()
  310. if l.list == nil {
  311. l.list = list.New()
  312. }
  313. l.list.PushBackList(other.list)
  314. }
  315. // PushFrontList inserts a copy of an other list at the front of list <l>.
  316. // The lists <l> and <other> may be the same, but they must not be nil.
  317. func (l *List) PushFrontList(other *List) {
  318. if l != other {
  319. other.mu.RLock()
  320. defer other.mu.RUnlock()
  321. }
  322. l.mu.Lock()
  323. defer l.mu.Unlock()
  324. if l.list == nil {
  325. l.list = list.New()
  326. }
  327. l.list.PushFrontList(other.list)
  328. }
  329. // InsertAfter inserts a new element <e> with value <v> immediately after <p> and returns <e>.
  330. // If <p> is not an element of <l>, the list is not modified.
  331. // The <p> must not be nil.
  332. func (l *List) InsertAfter(p *Element, v interface{}) (e *Element) {
  333. l.mu.Lock()
  334. defer l.mu.Unlock()
  335. if l.list == nil {
  336. l.list = list.New()
  337. }
  338. e = l.list.InsertAfter(v, p)
  339. return
  340. }
  341. // InsertBefore inserts a new element <e> with value <v> immediately before <p> and returns <e>.
  342. // If <p> is not an element of <l>, the list is not modified.
  343. // The <p> must not be nil.
  344. func (l *List) InsertBefore(p *Element, v interface{}) (e *Element) {
  345. l.mu.Lock()
  346. defer l.mu.Unlock()
  347. if l.list == nil {
  348. l.list = list.New()
  349. }
  350. e = l.list.InsertBefore(v, p)
  351. return
  352. }
  353. // Remove removes <e> from <l> if <e> is an element of list <l>.
  354. // It returns the element value e.Value.
  355. // The element must not be nil.
  356. func (l *List) Remove(e *Element) (value interface{}) {
  357. l.mu.Lock()
  358. defer l.mu.Unlock()
  359. if l.list == nil {
  360. l.list = list.New()
  361. }
  362. value = l.list.Remove(e)
  363. return
  364. }
  365. // Removes removes multiple elements <es> from <l> if <es> are elements of list <l>.
  366. func (l *List) Removes(es []*Element) {
  367. l.mu.Lock()
  368. defer l.mu.Unlock()
  369. if l.list == nil {
  370. l.list = list.New()
  371. }
  372. for _, e := range es {
  373. l.list.Remove(e)
  374. }
  375. return
  376. }
  377. // RemoveAll removes all elements from list <l>.
  378. func (l *List) RemoveAll() {
  379. l.mu.Lock()
  380. l.list = list.New()
  381. l.mu.Unlock()
  382. }
  383. // See RemoveAll().
  384. func (l *List) Clear() {
  385. l.RemoveAll()
  386. }
  387. // RLockFunc locks reading with given callback function <f> within RWMutex.RLock.
  388. func (l *List) RLockFunc(f func(list *list.List)) {
  389. l.mu.RLock()
  390. defer l.mu.RUnlock()
  391. if l.list != nil {
  392. f(l.list)
  393. }
  394. }
  395. // LockFunc locks writing with given callback function <f> within RWMutex.Lock.
  396. func (l *List) LockFunc(f func(list *list.List)) {
  397. l.mu.Lock()
  398. defer l.mu.Unlock()
  399. if l.list == nil {
  400. l.list = list.New()
  401. }
  402. f(l.list)
  403. }
  404. // Iterator is alias of IteratorAsc.
  405. func (l *List) Iterator(f func(e *Element) bool) {
  406. l.IteratorAsc(f)
  407. }
  408. // IteratorAsc iterates the list readonly in ascending order with given callback function <f>.
  409. // If <f> returns true, then it continues iterating; or false to stop.
  410. func (l *List) IteratorAsc(f func(e *Element) bool) {
  411. l.mu.RLock()
  412. defer l.mu.RUnlock()
  413. if l.list == nil {
  414. return
  415. }
  416. length := l.list.Len()
  417. if length > 0 {
  418. for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
  419. if !f(e) {
  420. break
  421. }
  422. }
  423. }
  424. }
  425. // IteratorDesc iterates the list readonly in descending order with given callback function <f>.
  426. // If <f> returns true, then it continues iterating; or false to stop.
  427. func (l *List) IteratorDesc(f func(e *Element) bool) {
  428. l.mu.RLock()
  429. defer l.mu.RUnlock()
  430. if l.list == nil {
  431. return
  432. }
  433. length := l.list.Len()
  434. if length > 0 {
  435. for i, e := 0, l.list.Back(); i < length; i, e = i+1, e.Prev() {
  436. if !f(e) {
  437. break
  438. }
  439. }
  440. }
  441. }
  442. // Join joins list elements with a string <glue>.
  443. func (l *List) Join(glue string) string {
  444. l.mu.RLock()
  445. defer l.mu.RUnlock()
  446. if l.list == nil {
  447. return ""
  448. }
  449. buffer := bytes.NewBuffer(nil)
  450. length := l.list.Len()
  451. if length > 0 {
  452. for i, e := 0, l.list.Front(); i < length; i, e = i+1, e.Next() {
  453. buffer.WriteString(gconv.String(e.Value))
  454. if i != length-1 {
  455. buffer.WriteString(glue)
  456. }
  457. }
  458. }
  459. return buffer.String()
  460. }
  461. // String returns current list as a string.
  462. func (l *List) String() string {
  463. return "[" + l.Join(",") + "]"
  464. }
  465. // MarshalJSON implements the interface MarshalJSON for json.Marshal.
  466. func (l *List) MarshalJSON() ([]byte, error) {
  467. return json.Marshal(l.FrontAll())
  468. }
  469. // UnmarshalJSON implements the interface UnmarshalJSON for json.Unmarshal.
  470. func (l *List) UnmarshalJSON(b []byte) error {
  471. l.mu.Lock()
  472. defer l.mu.Unlock()
  473. if l.list == nil {
  474. l.list = list.New()
  475. }
  476. var array []interface{}
  477. if err := json.Unmarshal(b, &array); err != nil {
  478. return err
  479. }
  480. l.PushBacks(array)
  481. return nil
  482. }
  483. // UnmarshalValue is an interface implement which sets any type of value for list.
  484. func (l *List) UnmarshalValue(value interface{}) (err error) {
  485. l.mu.Lock()
  486. defer l.mu.Unlock()
  487. if l.list == nil {
  488. l.list = list.New()
  489. }
  490. var array []interface{}
  491. switch value.(type) {
  492. case string, []byte:
  493. err = json.Unmarshal(gconv.Bytes(value), &array)
  494. default:
  495. array = gconv.SliceAny(value)
  496. }
  497. l.PushBacks(array)
  498. return err
  499. }