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 }