Skip to content

Instantly share code, notes, and snippets.

@mantyr
Created June 1, 2016 17:36
Show Gist options
  • Save mantyr/d0e8434c132a111ade377a9859636f64 to your computer and use it in GitHub Desktop.
Save mantyr/d0e8434c132a111ade377a9859636f64 to your computer and use it in GitHub Desktop.
Удаляем старые элементы в map, при этом следим что бы элементов было не больше N штук
// https://play.golang.org/p/sopEgcwRZC
package main
import (
"fmt"
"sync"
)
type Map struct {
sync.RWMutex
ch chan string
d map[string]string
}
func NewMap() (m *Map) {
m = new(Map)
m.ch = make(chan string, 10000)
m.d = make(map[string]string)
return
}
func (m *Map) Add(key, value string) {
m.Lock()
defer m.Unlock()
m.check(50, true)
m.d[key] = value
m.ch <- key
}
func (m *Map) Get(key string) string {
m.RLock()
defer m.RUnlock()
if v, ok := m.d[key]; ok {
return v
}
return ""
}
func (m *Map) Check() {
m.check(50, false)
}
// храним не более len_max элементов+1 в map, при этом удаляем сначала самые старые в порядке их добавления
// есть проблема - если ключ был добавлен несколько раз то программа не видит что элемент обновился и всё равно его удалит как старый
// что бы этого не происходило нужно добавлять дату к в ключь и проверять, если ключ имеет другую дату (или вместо даты инкрементный счётчик) то такой элемент пропускается
func (m *Map) check(len_max int, is_lock bool) {
ch_len := len(m.ch)
if ch_len > len_max {
if !is_lock {
m.Lock()
defer m.Unlock()
}
ch_len = len(m.ch)
for i := 0; i < ch_len - len_max; i++ {
delete(m.d, <- m.ch)
}
}
}
func (m *Map) Len() int {
return len(m.ch)
}
func main() {
fmt.Println("Hello, playground")
m := NewMap()
for i := 0; i < 1000; i++ {
m.Add(fmt.Sprintf("key_%s", i), fmt.Sprintf("value_%s", i))
}
fmt.Println(m.Len())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment