You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

whowas.go 1.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. package irc
  2. type WhoWasList struct {
  3. buffer []*WhoWas
  4. start int
  5. end int
  6. }
  7. type WhoWas struct {
  8. nickname Name
  9. username Name
  10. hostname Name
  11. realname Text
  12. }
  13. func NewWhoWasList(size uint) *WhoWasList {
  14. return &WhoWasList{
  15. buffer: make([]*WhoWas, size),
  16. }
  17. }
  18. func (list *WhoWasList) Append(client *Client) {
  19. list.buffer[list.end] = &WhoWas{
  20. nickname: client.Nick(),
  21. username: client.username,
  22. hostname: client.hostname,
  23. realname: client.realname,
  24. }
  25. list.end = (list.end + 1) % len(list.buffer)
  26. if list.end == list.start {
  27. list.start = (list.end + 1) % len(list.buffer)
  28. }
  29. }
  30. func (list *WhoWasList) Find(nickname Name, limit int64) []*WhoWas {
  31. results := make([]*WhoWas, 0)
  32. for whoWas := range list.Each() {
  33. if nickname != whoWas.nickname {
  34. continue
  35. }
  36. results = append(results, whoWas)
  37. if int64(len(results)) >= limit {
  38. break
  39. }
  40. }
  41. return results
  42. }
  43. func (list *WhoWasList) prev(index int) int {
  44. index -= 1
  45. if index < 0 {
  46. index += len(list.buffer)
  47. }
  48. return index
  49. }
  50. // Iterate the buffer in reverse.
  51. func (list *WhoWasList) Each() <-chan *WhoWas {
  52. ch := make(chan *WhoWas)
  53. go func() {
  54. defer close(ch)
  55. if list.start == list.end {
  56. return
  57. }
  58. start := list.prev(list.end)
  59. end := list.prev(list.start)
  60. for start != end {
  61. ch <- list.buffer[start]
  62. start = list.prev(start)
  63. }
  64. }()
  65. return ch
  66. }