safeslice.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package utils
  2. import "sync"
  3. // SyncSlice type that can be safely shared between goroutines
  4. type SyncSlice struct {
  5. sync.RWMutex
  6. items []interface{}
  7. }
  8. // SyncSliceItem slice item
  9. type SyncSliceItem struct {
  10. Index int
  11. Value interface{}
  12. }
  13. // Reset slice item to the concurrent slice
  14. func (cs *SyncSlice) Reset() []interface{} {
  15. slice := cs.items
  16. cs.Clear()
  17. return slice
  18. }
  19. // Values an item to the concurrent slice
  20. func (cs *SyncSlice) Values() []interface{} {
  21. return cs.items
  22. }
  23. // Clear an item to the concurrent slice
  24. func (cs *SyncSlice) Clear() {
  25. cs.Lock()
  26. defer cs.Unlock()
  27. cs.items = []interface{}{}
  28. }
  29. // Append pends an item to the concurrent slice
  30. func (cs *SyncSlice) Append(item interface{}) {
  31. cs.Lock()
  32. defer cs.Unlock()
  33. cs.items = append(cs.items, item)
  34. }
  35. // Iter over the items in the concurrent slice
  36. // Each item is sent over a channel, so that
  37. // we can iterate over the slice using the builin range keyword
  38. func (cs *SyncSlice) Iter() <-chan SyncSliceItem {
  39. c := make(chan SyncSliceItem)
  40. f := func() {
  41. cs.Lock()
  42. defer cs.Unlock()
  43. for index, value := range cs.items {
  44. c <- SyncSliceItem{index, value}
  45. }
  46. close(c)
  47. }
  48. go f()
  49. return c
  50. }