From 032a7e0c1188d3507b8d9a9571f2446a43cf775b Mon Sep 17 00:00:00 2001 From: msglm Date: Fri, 27 Oct 2023 07:08:25 -0500 Subject: apply https://github.com/42wim/matterbridge/pull/1864 --- vendor/maunium.net/go/mautrix/util/ringbuffer.go | 77 ++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 vendor/maunium.net/go/mautrix/util/ringbuffer.go (limited to 'vendor/maunium.net/go/mautrix/util/ringbuffer.go') diff --git a/vendor/maunium.net/go/mautrix/util/ringbuffer.go b/vendor/maunium.net/go/mautrix/util/ringbuffer.go new file mode 100644 index 00000000..ddb4c79f --- /dev/null +++ b/vendor/maunium.net/go/mautrix/util/ringbuffer.go @@ -0,0 +1,77 @@ +// Copyright (c) 2023 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package util + +import ( + "sync" +) + +type pair[Key comparable, Value any] struct { + Key Key + Value Value +} + +type RingBuffer[Key comparable, Value any] struct { + ptr int + data []pair[Key, Value] + lock sync.RWMutex +} + +func NewRingBuffer[Key comparable, Value any](size int) *RingBuffer[Key, Value] { + return &RingBuffer[Key, Value]{ + data: make([]pair[Key, Value], size), + } +} + +func (rb *RingBuffer[Key, Value]) Contains(val Key) bool { + _, ok := rb.Get(val) + return ok +} + +func (rb *RingBuffer[Key, Value]) Get(key Key) (val Value, found bool) { + rb.lock.RLock() + end := rb.ptr + for i := clamp(end-1, len(rb.data)); i != end; i = clamp(i-1, len(rb.data)) { + if rb.data[i].Key == key { + val = rb.data[i].Value + found = true + break + } + } + rb.lock.RUnlock() + return +} + +func (rb *RingBuffer[Key, Value]) Replace(key Key, val Value) bool { + rb.lock.Lock() + defer rb.lock.Unlock() + end := rb.ptr + for i := clamp(end-1, len(rb.data)); i != end; i = clamp(i-1, len(rb.data)) { + if rb.data[i].Key == key { + rb.data[i].Value = val + return true + } + } + return false +} + +func (rb *RingBuffer[Key, Value]) Push(key Key, val Value) { + rb.lock.Lock() + rb.data[rb.ptr] = pair[Key, Value]{Key: key, Value: val} + rb.ptr = (rb.ptr + 1) % len(rb.data) + rb.lock.Unlock() +} + +func clamp(index, len int) int { + if index < 0 { + return len + index + } else if index >= len { + return len - index + } else { + return index + } +} -- cgit v1.2.3