|
|
@ -12,9 +12,15 @@ to ensure garbage collection of removed elements. |
|
|
|
*/ |
|
|
|
|
|
|
|
import ( |
|
|
|
"fmt" |
|
|
|
"sync" |
|
|
|
) |
|
|
|
|
|
|
|
// MaxLength is the max allowed number of elements a linked list is
|
|
|
|
// allowed to contain.
|
|
|
|
// If more elements are pushed to the list it will panic.
|
|
|
|
const MaxLength = int(^uint(0) >> 1) |
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
CElement is an element of a linked-list |
|
|
@ -210,6 +216,7 @@ func (e *CElement) SetRemoved() { |
|
|
|
// CList represents a linked list.
|
|
|
|
// The zero value for CList is an empty list ready to use.
|
|
|
|
// Operations are goroutine-safe.
|
|
|
|
// Panics if length grows beyond the max.
|
|
|
|
type CList struct { |
|
|
|
mtx sync.RWMutex |
|
|
|
wg *sync.WaitGroup |
|
|
@ -217,6 +224,7 @@ type CList struct { |
|
|
|
head *CElement // first element
|
|
|
|
tail *CElement // last element
|
|
|
|
len int // list length
|
|
|
|
maxLen int // max list length
|
|
|
|
} |
|
|
|
|
|
|
|
func (l *CList) Init() *CList { |
|
|
@ -231,7 +239,16 @@ func (l *CList) Init() *CList { |
|
|
|
return l |
|
|
|
} |
|
|
|
|
|
|
|
func New() *CList { return new(CList).Init() } |
|
|
|
// Return CList with MaxLength. CList will panic if it goes beyond MaxLength.
|
|
|
|
func New() *CList { return newWithMax(MaxLength) } |
|
|
|
|
|
|
|
// Return CList with given maxLength.
|
|
|
|
// Will panic if list exceeds given maxLength.
|
|
|
|
func newWithMax(maxLength int) *CList { |
|
|
|
l := new(CList) |
|
|
|
l.maxLen = maxLength |
|
|
|
return l.Init() |
|
|
|
} |
|
|
|
|
|
|
|
func (l *CList) Len() int { |
|
|
|
l.mtx.RLock() |
|
|
@ -295,6 +312,7 @@ func (l *CList) WaitChan() <-chan struct{} { |
|
|
|
return l.waitCh |
|
|
|
} |
|
|
|
|
|
|
|
// Panics if list grows beyond its max length.
|
|
|
|
func (l *CList) PushBack(v interface{}) *CElement { |
|
|
|
l.mtx.Lock() |
|
|
|
|
|
|
@ -315,6 +333,9 @@ func (l *CList) PushBack(v interface{}) *CElement { |
|
|
|
l.wg.Done() |
|
|
|
close(l.waitCh) |
|
|
|
} |
|
|
|
if l.len >= l.maxLen { |
|
|
|
panic(fmt.Sprintf("clist: maximum length list reached %d", l.maxLen)) |
|
|
|
} |
|
|
|
l.len++ |
|
|
|
|
|
|
|
// Modify the tail
|
|
|
|