--- /dev/null
+package utils
+
+import (
+ "fmt"
+ "sync"
+)
+
+type (
+ SimpleLockStack struct {
+ Current *SimpleLockStackElement
+ Creator func() interface{}
+ len int
+ capacity int
+ active int
+ maxsize int
+ lock sync.Mutex
+ }
+ SimpleLockStackElement struct {
+ Value interface{}
+ Previous *SimpleLockStackElement
+ Next *SimpleLockStackElement
+ }
+ ObjectDestroy interface {
+ Destroy()
+ }
+)
+
+func NewStackLock(startsize, maxsize int, creator func() interface{}) *SimpleLockStack {
+ ss := &SimpleLockStack{lock: sync.Mutex{}, Current: &SimpleLockStackElement{Value: creator()}, Creator: creator, maxsize: maxsize}
+ if startsize > 0 {
+ elements := make([]SimpleLockStackElement, startsize-1)
+ current := ss.Current
+ for i := range elements {
+ e := elements[i]
+ if creator != nil {
+ e.Value = creator()
+ }
+ current.Next = &e
+ e.Previous = current
+ current = &e
+ }
+ ss.capacity, ss.len, ss.active = startsize, startsize, 0
+
+ ss.Current = current
+ }
+ return ss
+}
+func (s *SimpleLockStack) Pop() (value interface{}) {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+ if s.len == 0 {
+ // Pool is empty, create a new item to return
+ if s.Creator != nil {
+ value = s.Creator()
+ }
+ } else {
+ value = s.Current.Value
+ s.len--
+ if s.Current.Previous != nil {
+ s.Current = s.Current.Previous
+ }
+ }
+ // println("Pop ",value, s.len, s.active, s.capacity, s.Current.Next)
+ s.active++
+ return
+}
+func (s *SimpleLockStack) Push(value interface{}) {
+ if d, ok := value.(ObjectDestroy); ok {
+ d.Destroy()
+ }
+ s.lock.Lock()
+ defer s.lock.Unlock()
+ if s.len == 0 {
+ s.Current.Value = value
+ } else if s.len < s.maxsize {
+ if s.Current.Next == nil {
+ s.Current.Next = &SimpleLockStackElement{Value: value, Previous: s.Current}
+ s.capacity++
+ } else {
+ s.Current.Next.Value = value
+ }
+ s.Current = s.Current.Next
+ } else {
+ // If we exceeded the capacity of stack do not store the created object
+ return
+ }
+ s.len++
+ s.active--
+ //println("Push ",value, s.len, s.active, s.capacity)
+ return
+}
+func (s *SimpleLockStack) Len() int {
+ return s.len
+}
+func (s *SimpleLockStack) Capacity() int {
+ return s.capacity
+}
+func (s *SimpleLockStack) Active() int {
+ return s.active
+}
+func (s *SimpleLockStack) String() string {
+ return fmt.Sprintf("SS: Capacity:%d Active:%d Stored:%d", s.capacity, s.active, s.len)
+}