package shared import ( "sync" ) type UniqueFifo struct { keys []string values []interface{} Mu sync.Mutex size int } func NewUniqueFifo(size int) *UniqueFifo { q := UniqueFifo{} q.keys = make([]string, 0) q.values = make([]interface{}, 0) q.size = size return &q } func (q *UniqueFifo) Add(k string, v interface{}) bool { ret := false if len(q.keys) == 0 { q.keys = append(q.keys, k) q.values = append(q.values, v) ret = false } else { i, _ := q.Contains(k) if i != -1 { q.Remove(i) ret = true } else { ret = false } q.keys = append(q.keys, "") q.values = append(q.values, "") copy(q.keys[1:], q.keys) copy(q.values[1:], q.values) q.keys[0] = k q.values[0] = v if len(q.keys) <= q.size { q.keys = q.keys[:len(q.keys)] q.values = q.values[:len(q.values)] } else { q.keys = q.keys[:q.size] q.values = q.values[:q.size] } } return ret } func (q *UniqueFifo) Remove(r int) { f := q.keys[:r] e := q.keys[r+1:] q.keys = f q.keys = append(q.keys, e...) n := q.values[:r] o := q.values[r+1:] q.values = n q.values = append(q.values, o...) } func (q *UniqueFifo) Contains(k string) (int, interface{}) { for i, key := range q.keys { if key == k { return i, q.values[i] } } return -1, nil }