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.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright (c) 2012-2014 Jeremy Latt
  2. // Copyright (c) 2016- Daniel Oaks <daniel@danieloaks.net>
  3. // released under the MIT license
  4. package irc
  5. type WhoWasList struct {
  6. buffer []*WhoWas
  7. start int
  8. end int
  9. }
  10. type WhoWas struct {
  11. nicknameCasefolded string
  12. nickname string
  13. username string
  14. hostname string
  15. realname string
  16. }
  17. func NewWhoWasList(size uint) *WhoWasList {
  18. return &WhoWasList{
  19. buffer: make([]*WhoWas, size+1),
  20. }
  21. }
  22. func (list *WhoWasList) Append(client *Client) {
  23. list.buffer[list.end] = &WhoWas{
  24. nicknameCasefolded: client.nickCasefolded,
  25. nickname: client.nick,
  26. username: client.username,
  27. hostname: client.hostname,
  28. realname: client.realname,
  29. }
  30. list.end = (list.end + 1) % len(list.buffer)
  31. if list.end == list.start {
  32. list.start = (list.end + 1) % len(list.buffer)
  33. }
  34. }
  35. func (list *WhoWasList) Find(nickname string, limit int64) []*WhoWas {
  36. results := make([]*WhoWas, 0)
  37. casefoldedNickname, err := CasefoldName(nickname)
  38. if err != nil {
  39. return results
  40. }
  41. for whoWas := range list.Each() {
  42. if casefoldedNickname != whoWas.nicknameCasefolded {
  43. continue
  44. }
  45. results = append(results, whoWas)
  46. if int64(len(results)) >= limit {
  47. break
  48. }
  49. }
  50. return results
  51. }
  52. func (list *WhoWasList) prev(index int) int {
  53. index -= 1
  54. if index < 0 {
  55. index += len(list.buffer)
  56. }
  57. return index
  58. }
  59. // Iterate the buffer in reverse.
  60. func (list *WhoWasList) Each() <-chan *WhoWas {
  61. ch := make(chan *WhoWas)
  62. go func() {
  63. defer close(ch)
  64. if list.start == list.end {
  65. return
  66. }
  67. start := list.prev(list.end)
  68. end := list.prev(list.start)
  69. for start != end {
  70. ch <- list.buffer[start]
  71. start = list.prev(start)
  72. }
  73. }()
  74. return ch
  75. }