From 560481026db3052b801189bb8d3a452ca252ebbf Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 23 Jan 2014 06:43:50 -0800 Subject: [PATCH] Add port allocator and move ipset into orderedintset Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- collections/orderedintset.go | 89 ++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 collections/orderedintset.go diff --git a/collections/orderedintset.go b/collections/orderedintset.go new file mode 100644 index 0000000..456975c --- /dev/null +++ b/collections/orderedintset.go @@ -0,0 +1,89 @@ +package collections + +import ( + "sort" + "sync" +) + +// OrderedIntSet is a thread-safe sorted set and a stack. +type OrderedIntSet struct { + sync.RWMutex + set []int +} + +// NewOrderedSet returns an initialized OrderedSet +func NewOrderedIntSet() *OrderedIntSet { + return &OrderedIntSet{} +} + +// Push takes a string and adds it to the set. If the elem aready exists, it has no effect. +func (s *OrderedIntSet) Push(elem int) { + s.RLock() + for _, e := range s.set { + if e == elem { + s.RUnlock() + return + } + } + s.RUnlock() + + s.Lock() + s.set = append(s.set, elem) + // Make sure the list is always sorted + sort.Ints(s.set) + s.Unlock() +} + +// Pop is an alias to PopFront() +func (s *OrderedIntSet) Pop() int { + return s.PopFront() +} + +// Pop returns the first elemen from the list and removes it. +// If the list is empty, it returns 0 +func (s *OrderedIntSet) PopFront() int { + s.RLock() + + for i, e := range s.set { + ret := e + s.RUnlock() + s.Lock() + s.set = append(s.set[:i], s.set[i+1:]...) + s.Unlock() + return ret + } + s.RUnlock() + + return 0 +} + +// PullBack retrieve the last element of the list. +// The element is not removed. +// If the list is empty, an empty element is returned. +func (s *OrderedIntSet) PullBack() int { + if len(s.set) == 0 { + return 0 + } + return s.set[len(s.set)-1] +} + +// Exists checks if the given element present in the list. +func (s *OrderedIntSet) Exists(elem int) bool { + for _, e := range s.set { + if e == elem { + return true + } + } + return false +} + +// Remove removes an element from the list. +// If the element is not found, it has no effect. +func (s *OrderedIntSet) Remove(elem int) { + for i, e := range s.set { + if e == elem { + s.set = append(s.set[:i], s.set[i+1:]...) + return + } + } +}