package concurrent import ( "sync" ) func initElem(v interface{}) *Element { return &Element{ m: new(sync.RWMutex), val: v, } } type Element struct { m *sync.RWMutex prev *Element next *Element val interface{} } func (s *Element) SetVal(val interface{}) { s.m.Lock() s.val = val s.m.Unlock() } func (s *Element) Prev() (elem *Element) { s.m.RLock() elem = s.prev s.m.RUnlock() return } func (s *Element) Next() (elem *Element) { s.m.RLock() elem = s.next s.m.RUnlock() return } func (s *Element) Val() (val interface{}) { s.m.RLock() val = s.val s.m.RUnlock() return } func (s *Element) destroy() { s.m.Lock() if s.prev != nil { s.prev.next = s.next } if s.next != nil { s.next.prev = s.prev } s.prev, s.next = nil, nil s.m.Unlock() } func (s *Element) setNext(elem *Element) { s.m.Lock() if s.next != nil { elem.next, s.next.prev = s.next, elem } s.next, elem.prev = elem, s s.m.Unlock() } func (s *Element) setPrev(elem *Element) { s.m.Lock() if s.prev != nil { elem.prev, s.prev.next = s.prev, elem } s.prev, elem.next = elem, s s.m.Unlock() } func ListFromSlise(sl []interface{}) *List { l := NewList() for _, val := range sl { l.PushBack(val) } return l } func NewList() *List { return &List{ m: new(sync.RWMutex), } } type List struct { m *sync.RWMutex first *Element last *Element size int } func (s *List) PushBackIfNotExists(v interface{}) (elem *Element, added bool) { s.m.Lock() defer s.m.Unlock() if s.search(v) == nil { added = true elem = s.pushBack(v) } return } func (s *List) PushBack(v interface{}) (elem *Element) { s.m.Lock() elem = s.pushBack(v) s.m.Unlock() return } func (s *List) pushBack(v interface{}) *Element { elem := initElem(v) if s.first == nil { s.first, s.last = elem, elem } else { s.last.setNext(elem) s.last = elem } s.size++ return elem } func (s *List) PushFront(v interface{}) (elem *Element) { s.m.Lock() elem = s.pushFront(v) s.m.Unlock() return } func (s *List) PushFrontIfNotExists(v interface{}) (elem *Element, added bool) { s.m.Lock() defer s.m.Unlock() if s.search(v) == nil { added = true elem = s.pushFront(v) } return } func (s *List) pushFront(v interface{}) *Element { elem := initElem(v) if s.first == nil { s.first, s.last = elem, elem } else { s.first.setPrev(elem) s.first = elem } s.size++ return elem } func (s *List) Remove(elem *Element) { if elem == nil { return } s.m.Lock() if elem == s.first { s.first = elem.next } if elem == s.last { s.last = elem.prev } elem.destroy() s.size-- s.m.Unlock() } func (s *List) Size() (size int) { s.m.RLock() size = s.size s.m.RUnlock() return } func (s *List) First() (elem *Element) { s.m.RLock() elem = s.first s.m.RUnlock() return } func (s *List) Last() (elem *Element) { s.m.RLock() elem = s.last s.m.RUnlock() return } func (s *List) Index(index int) (elem *Element) { i := 0 elem = s.First() for elem != nil && i < index { elem, i = elem.Next(), i+1 } return } func (s *List) Slice() []interface{} { s.m.RLock() f, res := s.first, make([]interface{}, 0, s.size) s.m.RUnlock() for f != nil { res, f = append(res, f.Val()), f.Next() } return res } func (s *List) search(val interface{}) *Element { for f := s.first; f != nil; f = f.Next() { if f.Val() == val { return f } } return nil } func (s *List) Search(val interface{}) *Element { for f := s.First(); f != nil; f = f.Next() { if f.Val() == val { return f } } return nil } func (s *List) Each(call func(*Element) bool) { for f := s.First(); f != nil; f = f.Next() { if !call(f) { return } } }