github.com/aacfactory/rings@v1.1.2/ring.go (about)

     1  /*
     2   * Copyright 2021 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package rings
    18  
    19  import (
    20  	"bytes"
    21  	"sync"
    22  )
    23  
    24  type node[E Entry] struct {
    25  	next, prev *node[E]
    26  	value      E
    27  }
    28  
    29  func New[E Entry](key string, values ...E) (r *Ring[E]) {
    30  	r = &Ring[E]{
    31  		mutex: sync.RWMutex{},
    32  		key:   key,
    33  		head:  nil,
    34  		size:  0,
    35  	}
    36  	if values != nil && len(values) > 0 {
    37  		for _, value := range values {
    38  			r.Push(value)
    39  		}
    40  	}
    41  	return
    42  }
    43  
    44  type Ring[E Entry] struct {
    45  	mutex sync.RWMutex
    46  	key   string
    47  	head  *node[E]
    48  	size  int
    49  }
    50  
    51  func (r *Ring[E]) Key() (key string) {
    52  	key = r.key
    53  	return
    54  }
    55  
    56  func (r *Ring[E]) Push(v E) (ok bool) {
    57  	r.mutex.Lock()
    58  	_, has := r.get(v.Key())
    59  	if has {
    60  		r.mutex.Unlock()
    61  		return
    62  	}
    63  	e := &node[E]{
    64  		value: v,
    65  	}
    66  	if r.head == nil {
    67  		e.next = e
    68  		e.prev = e
    69  		r.head = e
    70  	} else {
    71  		prev := r.head.prev
    72  		prev.next = e
    73  		e.prev = prev
    74  		e.next = r.head
    75  		r.head.prev = e
    76  	}
    77  	r.size++
    78  	ok = true
    79  	r.mutex.Unlock()
    80  	return
    81  }
    82  
    83  func (r *Ring[E]) Pop() (e E, ok bool) {
    84  	r.mutex.Lock()
    85  	if r.head == nil {
    86  		r.mutex.Unlock()
    87  		return
    88  	}
    89  	head := r.head
    90  	e = head.value
    91  	r.size--
    92  	if r.size == 0 {
    93  		head = nil
    94  	} else {
    95  		next := head.next
    96  		next.prev = head.prev
    97  		head = next
    98  	}
    99  	r.head = head
   100  	r.mutex.Unlock()
   101  	return
   102  }
   103  
   104  func (r *Ring[E]) Remove(key string) {
   105  	r.mutex.Lock()
   106  	if r.head == nil {
   107  		r.mutex.Unlock()
   108  		return
   109  	}
   110  	head := r.head
   111  	for i := 0; i < r.size; i++ {
   112  		e := r.next()
   113  		if e.value.Key() == key {
   114  			if e.prev.value.Key() == key && e.next.value.Key() == key {
   115  				head = nil
   116  				break
   117  			}
   118  			prev := e.prev
   119  			next := e.next
   120  			prev.next = next
   121  			if head.value.Key() == key {
   122  				head = next
   123  			}
   124  			break
   125  		}
   126  	}
   127  	r.head = head
   128  	r.size--
   129  	r.mutex.Unlock()
   130  }
   131  
   132  func (r *Ring[E]) Next() (value E) {
   133  	r.mutex.RLock()
   134  	if r.size == 0 {
   135  		r.mutex.RUnlock()
   136  		return
   137  	}
   138  	value = r.next().value
   139  	r.mutex.RUnlock()
   140  	return
   141  }
   142  
   143  func (r *Ring[E]) SeekTo(key string) (has bool) {
   144  	r.mutex.RLock()
   145  	if r.size == 0 {
   146  		r.mutex.RUnlock()
   147  		return
   148  	}
   149  	for i := 0; i < r.size; i++ {
   150  		n := r.next()
   151  		if n.value.Key() == key {
   152  			r.head = n
   153  			has = true
   154  			break
   155  		}
   156  	}
   157  	r.mutex.RUnlock()
   158  	return
   159  }
   160  
   161  func (r *Ring[E]) Head() (value E, has bool) {
   162  	r.mutex.RLock()
   163  	if r.size == 0 {
   164  		r.mutex.RUnlock()
   165  		return
   166  	}
   167  	value = r.head.value
   168  	has = true
   169  	r.mutex.RUnlock()
   170  	return
   171  }
   172  
   173  func (r *Ring[E]) Get(key string) (value E, has bool) {
   174  	r.mutex.RLock()
   175  	if r.size == 0 {
   176  		r.mutex.RUnlock()
   177  		return
   178  	}
   179  	var n *node[E] = nil
   180  	n, has = r.get(key)
   181  	if has {
   182  		value = n.value
   183  	}
   184  	r.mutex.RUnlock()
   185  	return
   186  }
   187  
   188  func (r *Ring[E]) get(key string) (value *node[E], has bool) {
   189  	if r.size == 0 {
   190  		return
   191  	}
   192  	head := r.head
   193  	for i := 0; i < r.size; i++ {
   194  		n := r.next()
   195  		if n.value.Key() == key {
   196  			value = n
   197  			has = true
   198  			break
   199  		}
   200  	}
   201  	r.head = head
   202  	return
   203  }
   204  
   205  func (r *Ring[E]) Len() (size int) {
   206  	r.mutex.RLock()
   207  	size = r.size
   208  	r.mutex.RUnlock()
   209  	return
   210  }
   211  
   212  func (r *Ring[E]) String() (value string) {
   213  	r.mutex.RLock()
   214  	p := bytes.NewBufferString("")
   215  	_ = p.WriteByte('[')
   216  	for i := 0; i < r.size; i++ {
   217  		e := r.next()
   218  		if i == 0 {
   219  			_, _ = p.WriteString(e.value.Key())
   220  		} else {
   221  			_, _ = p.WriteString(", ")
   222  			_, _ = p.WriteString(e.value.Key())
   223  		}
   224  	}
   225  	_ = p.WriteByte(']')
   226  	value = p.String()
   227  	r.mutex.RUnlock()
   228  	return
   229  }
   230  
   231  func (r *Ring[E]) next() (node *node[E]) {
   232  	node = r.head
   233  	r.head = r.head.next
   234  	return
   235  }