github.com/whatap/golib@v0.0.22/util/list/LinkedList.go (about)

     1  package list
     2  
     3  import (
     4  	"bytes"
     5  	"sync"
     6  )
     7  
     8  type LinkedList struct {
     9  	size  int
    10  	first *LinkedListEntity
    11  	last  *LinkedListEntity
    12  	lock  sync.Mutex
    13  }
    14  
    15  func NewLinkedList() *LinkedList {
    16  	o := new(LinkedList)
    17  	return o
    18  }
    19  
    20  func (o *LinkedList) AddFirst(v interface{}) {
    21  	o.lock.Lock()
    22  	defer o.lock.Unlock()
    23  
    24  	newNode := &LinkedListEntity{prev: nil, Value: v, next: o.first}
    25  
    26  	f := o.first
    27  	o.first = newNode
    28  	if f == nil {
    29  		o.last = newNode
    30  	} else {
    31  		f.prev = newNode
    32  	}
    33  	o.size++
    34  }
    35  
    36  func (o *LinkedList) AddLast(v interface{}) {
    37  	o.lock.Lock()
    38  	defer o.lock.Unlock()
    39  
    40  	newNode := &LinkedListEntity{prev: o.last, Value: v, next: nil}
    41  	l := o.last
    42  	o.last = newNode
    43  	if l == nil {
    44  		o.first = newNode
    45  	} else {
    46  		l.next = newNode
    47  	}
    48  	o.size++
    49  }
    50  
    51  func (o *LinkedList) PutBefore(v interface{}, succ *LinkedListEntity) *LinkedListEntity {
    52  	o.lock.Lock()
    53  	defer o.lock.Unlock()
    54  	prev := succ.prev
    55  
    56  	newNode := &LinkedListEntity{prev: prev, Value: v, next: succ}
    57  
    58  	succ.prev = newNode
    59  	if prev == nil {
    60  		o.first = newNode
    61  	} else {
    62  		prev.next = newNode
    63  	}
    64  	o.size++
    65  	return newNode
    66  }
    67  
    68  func (o *LinkedList) Remove(x *LinkedListEntity) interface{} {
    69  	o.lock.Lock()
    70  	defer o.lock.Unlock()
    71  	return o.remove(x)
    72  }
    73  
    74  func (o *LinkedList) remove(x *LinkedListEntity) interface{} {
    75  
    76  	v := x.Value
    77  
    78  	if x.prev == nil {
    79  		o.first = x.next
    80  	} else {
    81  		x.prev.next = x.next
    82  	}
    83  	if x.next == nil {
    84  		o.last = x.prev
    85  	} else {
    86  		x.next.prev = x.prev
    87  	}
    88  	o.size--
    89  	
    90  	// avoid memory leaks
    91  	x.next = nil
    92  	x.prev = nil
    93  	x.Value = nil
    94  	x = nil
    95  	
    96  	return v
    97  }
    98  
    99  func (o *LinkedList) GetFirst() *LinkedListEntity {
   100  	return o.first
   101  }
   102  
   103  func (o *LinkedList) GetLast() *LinkedListEntity {
   104  	return o.last
   105  }
   106  
   107  func (o *LinkedList) GetNext(e *LinkedListEntity) *LinkedListEntity {
   108  	return e.next
   109  }
   110  
   111  func (o *LinkedList) RemoveFirst() interface{} {
   112  	o.lock.Lock()
   113  	defer o.lock.Unlock()
   114  
   115  	if o.first != nil {
   116  		return o.remove(o.first)
   117  	}
   118  	return nil
   119  }
   120  
   121  func (o *LinkedList) RemoveLast() interface{} {
   122  	o.lock.Lock()
   123  	defer o.lock.Unlock()
   124  
   125  	if o.last != nil {
   126  		return o.remove(o.last)
   127  	}
   128  	return nil
   129  }
   130  
   131  func (o *LinkedList) Size() int {
   132  	return o.size
   133  }
   134  
   135  func (o *LinkedList) Add(v interface{}) bool {
   136  	o.AddLast(v)
   137  	return true
   138  }
   139  
   140  func (o *LinkedList) Clear() {
   141  	o.lock.Lock()
   142  	defer o.lock.Unlock()
   143  
   144  	o.first = nil
   145  	o.last = nil
   146  	o.size = 0
   147  }
   148  
   149  func (o *LinkedList) ToArray() []interface{} {
   150  	o.lock.Lock()
   151  	defer o.lock.Unlock()
   152  
   153  	result := make([]interface{}, o.size)
   154  	x := o.first
   155  	for i := 0; i < o.size; i++ {
   156  		result[i] = x.Value
   157  		x = x.next
   158  	}
   159  	return result
   160  }
   161  
   162  func (o *LinkedList) ToString() string {
   163  	o.lock.Lock()
   164  	defer o.lock.Unlock()
   165  
   166  	var buffer bytes.Buffer
   167  	x := o.first
   168  	for i := 0; i < o.size; i++ {
   169  		if i > 0 {
   170  			buffer.WriteString(",")
   171  		}
   172  		buffer.WriteString(x.ToString())
   173  		x = x.next
   174  	}
   175  	return buffer.String()
   176  }