| 44 | |
| 45 | |
| 46 | class CircularQueue(ctypes.Structure): |
| 47 | _pack_ = 4 |
| 48 | _fields_ = [ |
| 49 | ("items", QueueItem * LIGHTLLM_OUT_TOKEN_QUEUE_SIZE), # 循环队列的元素 |
| 50 | ("head", ctypes.c_int), # 指向队列头部 |
| 51 | ("tail", ctypes.c_int), # 指向队列尾部 |
| 52 | ] |
| 53 | |
| 54 | def __init__(self): |
| 55 | # 初始化头和尾 |
| 56 | self.head = 0 |
| 57 | self.tail = 0 |
| 58 | |
| 59 | def is_empty(self): |
| 60 | return self.head == self.tail |
| 61 | |
| 62 | def is_full(self): |
| 63 | return (self.tail + 1) % LIGHTLLM_OUT_TOKEN_QUEUE_SIZE == self.head |
| 64 | |
| 65 | def push(self, token_str: str, src_index: int, special: bool, count_output_tokens: int): |
| 66 | if self.is_full(): |
| 67 | raise Exception("Queue is full") |
| 68 | |
| 69 | # 添加元素 |
| 70 | item: QueueItem = self.items[self.tail] |
| 71 | item.set(token_str, src_index, special, count_output_tokens) |
| 72 | |
| 73 | # 更新尾部 |
| 74 | self.tail = (self.tail + 1) % LIGHTLLM_OUT_TOKEN_QUEUE_SIZE |
| 75 | |
| 76 | def pop(self) -> Tuple[str, int, bool, int]: |
| 77 | if self.is_empty(): |
| 78 | raise Exception("Queue is empty") |
| 79 | |
| 80 | # 移除元素 |
| 81 | item: QueueItem = self.items[self.head] |
| 82 | result = item.get() |
| 83 | |
| 84 | # 更新头部 |
| 85 | self.head = (self.head + 1) % LIGHTLLM_OUT_TOKEN_QUEUE_SIZE |
| 86 | return result |
| 87 | |
| 88 | def peek(self) -> Tuple[str, int, bool, int]: |
| 89 | if self.is_empty(): |
| 90 | raise Exception("Queue is empty") |
| 91 | |
| 92 | item: QueueItem = self.items[self.head] |
| 93 | result = item.get() |
| 94 | return result |
| 95 | |
| 96 | def pop_no_ret(self) -> None: |
| 97 | """ |
| 98 | 移除一个对象,但是不返回, 与peek配合使用 |
| 99 | """ |
| 100 | if self.is_empty(): |
| 101 | raise Exception("Queue is empty") |
| 102 | self.head = (self.head + 1) % LIGHTLLM_OUT_TOKEN_QUEUE_SIZE |
| 103 | return |
no outgoing calls