ordered_map.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package maps
  2. import "sync/atomic"
  3. type (
  4. OrderedMap[K comparable, V any] struct {
  5. batchLoop int // 批量处理循环次数
  6. writeChan chan any // 写入缓冲区
  7. stopChan chan struct{} // 停止信号
  8. closed int32 // 原子关闭标记
  9. }
  10. queueCmdSet[K comparable, V any] struct {
  11. key K
  12. value V
  13. }
  14. queueCmdPop[K comparable, V any] struct {
  15. limit int
  16. result chan []V
  17. }
  18. queueCmdLen struct {
  19. result chan int
  20. }
  21. // internal data structure
  22. // orderQueue 封装了有序队列的底层实现,包含 Map 和 Slice 的管理
  23. orderQueue[K comparable, V any] struct {
  24. pairs map[K]V // 所有数据
  25. keys []K // 所有key(保证先进先出)
  26. head int // 记录当前有效数据的起始索引
  27. }
  28. )
  29. func newOrderQueue[K comparable, V any]() *orderQueue[K, V] {
  30. return &orderQueue[K, V]{
  31. pairs: make(map[K]V),
  32. keys: make([]K, 0, 1024),
  33. head: 0,
  34. }
  35. }
  36. func (q *orderQueue[K, V]) set(key K, value V) {
  37. if _, found := q.pairs[key]; found {
  38. q.pairs[key] = value
  39. } else {
  40. q.keys = append(q.keys, key)
  41. q.pairs[key] = value
  42. }
  43. }
  44. func (q *orderQueue[K, V]) pop(limit int) []V {
  45. total := len(q.keys) - q.head
  46. if total <= 0 {
  47. return nil
  48. }
  49. batchSize := limit
  50. if batchSize > total {
  51. batchSize = total
  52. }
  53. if batchSize <= 0 {
  54. return nil
  55. }
  56. result := make([]V, 0, batchSize)
  57. for i := 0; i < batchSize; i++ {
  58. k := q.keys[q.head]
  59. v := q.pairs[k]
  60. result = append(result, v)
  61. delete(q.pairs, k)
  62. var zero K
  63. q.keys[q.head] = zero // free reference
  64. q.head++
  65. }
  66. // incremental compaction
  67. if q.head > 1024 && q.head > len(q.keys)/2 {
  68. newKeys := make([]K, len(q.keys)-q.head)
  69. copy(newKeys, q.keys[q.head:])
  70. q.keys = newKeys
  71. q.head = 0
  72. }
  73. return result
  74. }
  75. func (q *orderQueue[K, V]) len() int {
  76. return len(q.pairs)
  77. }
  78. func NewOrderMap[K comparable, V any](chanSize, batchLoop int) *OrderedMap[K, V] {
  79. if chanSize <= 0 {
  80. chanSize = 10000
  81. }
  82. if batchLoop <= 0 {
  83. batchLoop = 10
  84. }
  85. om := &OrderedMap[K, V]{
  86. batchLoop: batchLoop,
  87. writeChan: make(chan any, chanSize),
  88. stopChan: make(chan struct{}),
  89. }
  90. go om.loop()
  91. return om
  92. }
  93. func (om *OrderedMap[K, V]) loop() {
  94. queue := newOrderQueue[K, V]()
  95. // processCmd 处理单个命令
  96. processCmd := func(cmd any) {
  97. switch c := cmd.(type) {
  98. case *queueCmdSet[K, V]:
  99. queue.set(c.key, c.value)
  100. case *queueCmdPop[K, V]:
  101. c.result <- queue.pop(c.limit)
  102. case *queueCmdLen:
  103. c.result <- queue.len()
  104. }
  105. }
  106. for {
  107. // 1. 阻塞等待:如果没有任务,在这里让出 CPU
  108. select {
  109. case <-om.stopChan:
  110. return
  111. case cmd := <-om.writeChan:
  112. // 收到第一个任务,立即处理
  113. processCmd(cmd)
  114. }
  115. // 2. 批量消费:唤醒后,贪婪地消费所有积压任务
  116. // 设置一个最大批量限制,防止单个协程长期霸占 CPU
  117. BatchLoop:
  118. for i := 0; i < om.batchLoop; i++ {
  119. select {
  120. case cmd := <-om.writeChan:
  121. processCmd(cmd)
  122. case <-om.stopChan:
  123. return
  124. default:
  125. // Channel 空了,回到外层阻塞
  126. break BatchLoop
  127. }
  128. }
  129. }
  130. }
  131. func (om *OrderedMap[K, V]) isClosed() bool {
  132. return atomic.LoadInt32(&om.closed) == 1
  133. }
  134. // Set 是异步的 (fire and forget)
  135. func (om *OrderedMap[K, V]) Set(key K, value V) {
  136. if om.isClosed() {
  137. return
  138. }
  139. // 直接发送,如果满则阻塞(背压)
  140. om.writeChan <- &queueCmdSet[K, V]{key: key, value: value}
  141. }
  142. func (om *OrderedMap[K, V]) Len() int {
  143. if om.isClosed() {
  144. return 0
  145. }
  146. resultChan := make(chan int, 1)
  147. om.writeChan <- &queueCmdLen{result: resultChan}
  148. return <-resultChan
  149. }
  150. // PopBatch 高效批量弹出
  151. func (om *OrderedMap[K, V]) PopBatch(limit int) []V {
  152. if limit <= 0 || om.isClosed() {
  153. return nil
  154. }
  155. resultChan := make(chan []V, 1)
  156. om.writeChan <- &queueCmdPop[K, V]{limit: limit, result: resultChan}
  157. return <-resultChan
  158. }
  159. func (om *OrderedMap[K, V]) Pop() (V, bool) {
  160. batch := om.PopBatch(1)
  161. if len(batch) > 0 {
  162. return batch[0], true
  163. }
  164. var zero V
  165. return zero, false
  166. }
  167. func (om *OrderedMap[K, V]) Close() {
  168. if !atomic.CompareAndSwapInt32(&om.closed, 0, 1) {
  169. return
  170. }
  171. close(om.stopChan)
  172. }
  173. func (om *OrderedMap[K, V]) GetStopChan() <-chan struct{} {
  174. return om.stopChan
  175. }