trpc.group/trpc-go/trpc-go@v1.0.3/rpcz/spanarray.go (about)

     1  //
     2  //
     3  // Tencent is pleased to support the open source community by making tRPC available.
     4  //
     5  // Copyright (C) 2023 THL A29 Limited, a Tencent company.
     6  // All rights reserved.
     7  //
     8  // If you have downloaded a copy of the tRPC source code from Tencent,
     9  // please note that tRPC source code is licensed under the  Apache 2.0 License,
    10  // A copy of the Apache 2.0 License is included in this file.
    11  //
    12  //
    13  
    14  package rpcz
    15  
    16  // spanArray is a non-empty circular array to store spans to avoid dynamic allocation of memory.
    17  type spanArray struct {
    18  	// assert(capacity > 0) should always be true.
    19  	capacity uint32
    20  	length   uint32
    21  	data     []*span
    22  	// head is the index for next dequeue.
    23  	head uint32
    24  	// tail is the index for next enqueue.
    25  	tail uint32
    26  }
    27  
    28  // doBackward calls function f sequentially for each span present in the array
    29  // in backward order (from tail to head) until f returns false.
    30  func (a *spanArray) doBackward(f func(*span) bool) {
    31  	iter := a.tail
    32  	for i := uint32(0); i < a.length; i++ {
    33  		iter = a.previousIndex(iter)
    34  		if !f(a.data[iter]) {
    35  			break
    36  		}
    37  	}
    38  }
    39  
    40  func (a *spanArray) enqueue(value *span) {
    41  	if a.full() {
    42  		a.dequeue()
    43  	}
    44  	a.data[a.tail] = value
    45  	a.tail = a.nextIndex(a.tail)
    46  	a.length++
    47  }
    48  
    49  func (a *spanArray) dequeue() {
    50  	a.head = a.nextIndex(a.head)
    51  	a.length--
    52  }
    53  
    54  func (a *spanArray) front() *span {
    55  	return a.data[a.head]
    56  }
    57  
    58  func (a *spanArray) full() bool {
    59  	return a.length >= a.capacity
    60  }
    61  
    62  func (a *spanArray) nextIndex(index uint32) uint32 {
    63  	return (index + 1) % a.capacity
    64  }
    65  
    66  func (a *spanArray) previousIndex(index uint32) uint32 {
    67  	return (index + a.capacity - 1) % a.capacity
    68  }
    69  
    70  func newSpanArray(capacity uint32) *spanArray {
    71  	if capacity == 0 {
    72  		panic("capacity should be greater than 0")
    73  	}
    74  	return &spanArray{
    75  		capacity: capacity,
    76  		data:     make([]*span, capacity),
    77  	}
    78  }