mapx.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. package tinymq
  2. /* 优化连接方式
  3. - 高效匹配字符串算法
  4. - 随机匹配算法
  5. - 排序算法
  6. - 支持万级连接数
  7. */
  8. import (
  9. "math/rand"
  10. "sync"
  11. )
  12. type Mapx struct {
  13. sync.RWMutex
  14. id int // 生成 id 号
  15. lineMap map[int]*Line
  16. randLines []*Line
  17. }
  18. func NewMapx() *Mapx {
  19. return &Mapx{
  20. lineMap: make(map[int]*Line),
  21. randLines: make([]*Line, 0),
  22. }
  23. }
  24. // 存储连接
  25. func (m *Mapx) Store(line *Line) {
  26. m.Lock()
  27. defer m.Unlock()
  28. m.id++
  29. m.lineMap[m.id] = line
  30. m.randLines = append(m.randLines, line)
  31. if len(m.randLines) < 3 {
  32. return
  33. }
  34. // 交换一下位置,随机数组
  35. i := rand.Intn(len(m.randLines) - 1)
  36. t := m.randLines[i]
  37. m.randLines[i] = line
  38. m.randLines[len(m.randLines)-1] = t
  39. }
  40. // 删除连接
  41. func (m *Mapx) Delete(line *Line) {
  42. m.Lock()
  43. defer m.Unlock()
  44. for k, v := range m.lineMap {
  45. if v == line {
  46. delete(m.lineMap, k)
  47. break
  48. }
  49. }
  50. for i, v := range m.randLines {
  51. if v == line {
  52. l := len(m.randLines) - 1
  53. m.randLines[i] = m.randLines[l]
  54. m.randLines = m.randLines[0:l]
  55. break
  56. }
  57. }
  58. }
  59. // ID 方式删除连接
  60. func (m *Mapx) DeleteById(id int) {
  61. m.Lock()
  62. defer m.Unlock()
  63. line, ok := m.lineMap[id]
  64. if !ok {
  65. return
  66. }
  67. delete(m.lineMap, id)
  68. for i, v := range m.randLines {
  69. if v == line {
  70. l := len(m.randLines) - 1
  71. m.randLines[i] = m.randLines[l]
  72. m.randLines = m.randLines[0:l]
  73. break
  74. }
  75. }
  76. }
  77. // 删除不可用连接
  78. func (m *Mapx) DeleteInvalidLines(expired int64) {
  79. m.Lock()
  80. defer m.Unlock()
  81. for id, line := range m.lineMap {
  82. if line.state != Connected && line.updated.UnixMilli() < expired {
  83. delete(m.lineMap, id)
  84. }
  85. }
  86. for i := len(m.randLines) - 1; i >= 0; i-- {
  87. line := m.randLines[i]
  88. if line.state != Connected && line.updated.UnixMilli() < expired {
  89. l := len(m.randLines) - 1
  90. m.randLines[i] = m.randLines[l]
  91. m.randLines = m.randLines[0:l]
  92. }
  93. }
  94. }
  95. // 循环遍历
  96. func (m *Mapx) Range(fn func(id int, line *Line) bool) {
  97. m.RLock()
  98. defer m.RUnlock()
  99. for k, v := range m.lineMap {
  100. if !fn(k, v) {
  101. break
  102. }
  103. }
  104. }
  105. // 打乱随机数组
  106. func (m *Mapx) Rand() {
  107. m.Lock()
  108. defer m.Unlock()
  109. l := len(m.randLines) / 2
  110. for i := range l {
  111. k := rand.Intn(l) + l
  112. v := m.randLines[i]
  113. m.randLines[i] = m.randLines[k]
  114. m.randLines[k] = v
  115. }
  116. }
  117. // 随机遍历
  118. func (m *Mapx) RandRange(fn func(i int, v *Line) bool, rand bool) {
  119. if rand {
  120. m.Rand()
  121. }
  122. m.RLock()
  123. defer m.RUnlock()
  124. for i, v := range m.randLines {
  125. if !fn(i, v) {
  126. break
  127. }
  128. }
  129. }
  130. // 是否存在
  131. func (m *Mapx) Exist(line *Line) bool {
  132. for _, v := range m.lineMap {
  133. if v == line {
  134. return true
  135. }
  136. }
  137. return false
  138. }