github.com/searKing/golang/go@v1.2.117/sync/lru_pool.want_conn_queue.go (about) 1 // Copyright 2021 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sync 6 7 // A wantResourceQueue is a queue of wantResources. 8 type wantResourceQueue struct { 9 // This is a queue, not a deque. 10 // It is split into two stages - head[headPos:] and tail. 11 // popFront is trivial (headPos++) on the first stage, and 12 // pushBack is trivial (append) on the second stage. 13 // If the first stage is empty, popFront can swap the 14 // first and second stages to remedy the situation. 15 // 16 // This two-stage split is analogous to the use of two lists 17 // in Okasaki's purely functional queue but without the 18 // overhead of reversing the list when swapping stages. 19 head []*wantResource 20 headPos int 21 tail []*wantResource 22 } 23 24 // len returns the number of items in the queue. 25 func (q *wantResourceQueue) len() int { 26 return len(q.head) - q.headPos + len(q.tail) 27 } 28 29 // pushBack adds w to the back of the queue. 30 func (q *wantResourceQueue) pushBack(w *wantResource) { 31 q.tail = append(q.tail, w) 32 } 33 34 // popFront removes and returns the wantResource at the front of the queue. 35 func (q *wantResourceQueue) popFront() *wantResource { 36 if q.headPos >= len(q.head) { 37 if len(q.tail) == 0 { 38 return nil 39 } 40 // Pick up tail as new head, clear tail. 41 q.head, q.headPos, q.tail = q.tail, 0, q.head[:0] 42 } 43 w := q.head[q.headPos] 44 q.head[q.headPos] = nil 45 q.headPos++ 46 return w 47 } 48 49 // peekFront returns the wantResource at the front of the queue without removing it. 50 func (q *wantResourceQueue) peekFront() *wantResource { 51 if q.headPos < len(q.head) { 52 return q.head[q.headPos] 53 } 54 if len(q.tail) > 0 { 55 return q.tail[0] 56 } 57 return nil 58 } 59 60 // cleanFront pops any wantResources that are no longer waiting from the head of the 61 // queue, reporting whether any were popped. 62 func (q *wantResourceQueue) cleanFront() (cleaned bool) { 63 for { 64 w := q.peekFront() 65 if w == nil || w.waiting() { 66 return cleaned 67 } 68 q.popFront() 69 cleaned = true 70 } 71 }