gophi/fixedmap.go
kim (grufwub) 43ddf00b36 massively improve code commenting, fix SkipPrefixWriter bug
Signed-off-by: kim (grufwub) <grufwub@gmail.com>
2020-05-08 16:52:17 +01:00

79 lines
1.7 KiB
Go

package main
import (
"container/list"
)
/* TODO: work on efficiency. use our own lower level data structure? */
/* FixedMap:
* A fixed size map that pushes the last
* used value from the stack if size limit
* is reached.
*/
type FixedMap struct {
Map map[string]*MapElement
List *list.List
Size int
}
/* MapElement:
* Simple structure to wrap pointer to list
* element and stored map value together.
*/
type MapElement struct {
Element *list.Element
Value *File
}
func NewFixedMap(size int) *FixedMap {
return &FixedMap{
make(map[string]*MapElement),
list.New(),
size,
}
}
/* Get file in map for key, or nil */
func (fm *FixedMap) Get(key string) *File {
elem, ok := fm.Map[key]
if ok {
/* And that's an LRU implementation folks! */
fm.List.MoveToFront(elem.Element)
return elem.Value
} else {
return nil
}
}
/* Put file in map as key, pushing out last file if size limit reached */
func (fm *FixedMap) Put(key string, value *File) {
element := fm.List.PushFront(key)
fm.Map[key] = &MapElement{ element, value }
if fm.List.Len() > fm.Size {
/* We're at capacity! SIR! */
element = fm.List.Back()
/* We don't check here as we know this is ALWAYS a string */
key, _ := element.Value.(string)
/* Finally delete the map entry and list element! */
delete(fm.Map, key)
fm.List.Remove(element)
}
}
/* Try delete element, else do nothing */
func (fm *FixedMap) Remove(key string) {
elem, ok := fm.Map[key]
if !ok {
/* We don't have this key, return */
return
}
/* Remove the selected element */
delete(fm.Map, key)
fm.List.Remove(elem.Element)
}