all repos — fixyoutube-go @ 636c962ec2a61c90f7451b365aa808a957a9082e

A better way to embed YouTube videos everywhere (inspired by FixTweet).

volatile/volatile.go (view raw)

  1package volatile
  2
  3import (
  4	"fmt"
  5	"time"
  6
  7	"github.com/sirupsen/logrus"
  8)
  9
 10var logger = logrus.New()
 11
 12type Element[K comparable, V any] struct {
 13	key       K
 14	value     V
 15	Timestamp time.Time
 16}
 17
 18type Volatile[K comparable, V any] struct {
 19	data       []Element[K, V]
 20	timeToLive time.Duration
 21}
 22
 23func reverseIntArray(arr []int) {
 24	length := len(arr)
 25	for i := 0; i < length/2; i++ {
 26		arr[i], arr[length-i-1] = arr[length-i-1], arr[i]
 27	}
 28}
 29
 30func NewVolatile[K comparable, V any](timeToLive time.Duration) *Volatile[K, V] {
 31	return &Volatile[K, V]{
 32		data:       nil,
 33		timeToLive: timeToLive,
 34	}
 35}
 36
 37func (v *Volatile[K, V]) removeIndex(index int) error {
 38	if index < 0 || index >= len(v.data) {
 39		return fmt.Errorf("Index out of bounds")
 40	}
 41	v.data = append(v.data[:index], v.data[index+1:]...)
 42	return nil
 43}
 44
 45func (v *Volatile[K, V]) clean() error {
 46	now := time.Now()
 47
 48	for i := len(v.data) - 1; i >= 0; i-- {
 49		if now.Sub(v.data[i].Timestamp) > v.timeToLive {
 50			err := v.removeIndex(i)
 51			if err != nil {
 52				return err
 53			}
 54		}
 55	}
 56	return nil
 57}
 58
 59func (v *Volatile[K, V]) indexOf(key K) int {
 60	for i := range v.data {
 61		e := v.data[i]
 62		if e.key == key {
 63			return i
 64		}
 65	}
 66	return -1
 67}
 68
 69func (v *Volatile[K, V]) Has(key K) bool {
 70	err := v.clean()
 71	if err != nil {
 72		logger.Println(err)
 73		return false
 74	}
 75	return v.indexOf(key) != -1
 76}
 77
 78func (v *Volatile[K, V]) Get(key K) (*V, error) {
 79	err := v.clean()
 80	if err != nil {
 81		logger.Println(err)
 82		return nil, err
 83	}
 84
 85	i := v.indexOf(key)
 86	if i == -1 {
 87		return nil, fmt.Errorf("Not found")
 88	}
 89	return &v.data[i].value, nil
 90}
 91
 92func (v *Volatile[K, V]) Remove(key K) (*V, error) {
 93	err := v.clean()
 94	if err != nil {
 95		logger.Error(err)
 96		return nil, err
 97	}
 98	i := v.indexOf(key)
 99	if i == -1 {
100		logger.Error(err)
101		return nil, err
102	}
103
104	value := &v.data[i].value
105	err = v.removeIndex(i)
106	if err != nil {
107		logger.Error(err)
108		return nil, err
109	}
110	return value, nil
111}
112
113func (v *Volatile[K, V]) Set(key K, value V) error {
114	err := v.clean()
115	if err != nil {
116		logger.Error(err)
117		return err
118	}
119	_, err = v.Remove(key)
120	if err != nil {
121		logger.Error(err)
122		return err
123	}
124	e := Element[K, V]{key: key, value: value, Timestamp: time.Now()}
125	v.data = append(v.data, e)
126	return nil
127}