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  }