feat: Added a file cache
This commit is contained in:
parent
0cefb5fd0b
commit
05280d7d9a
62
storage/file_cache.go
Normal file
62
storage/file_cache.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
// A `FileCache` stores open file descriptors for all files that have been
|
||||||
|
// requested, and returns them when requested
|
||||||
|
type FileCache struct {
|
||||||
|
cacheSize int
|
||||||
|
fileNames map[string]int
|
||||||
|
indexesOfFiles map[int]string
|
||||||
|
files []*os.File
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFileCache(cacheSize int) FileCache {
|
||||||
|
var c FileCache
|
||||||
|
|
||||||
|
c.cacheSize = cacheSize
|
||||||
|
c.fileNames = make(map[string]int)
|
||||||
|
c.indexesOfFiles = make(map[int]string)
|
||||||
|
c.files = make([]*os.File, cacheSize)
|
||||||
|
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// `FetchFile` takes in a file's name and returns its file descriptor
|
||||||
|
//
|
||||||
|
// If the file is not found in the cache, the file is added to the cache
|
||||||
|
func (fc *FileCache) FetchFile(fileName string) (*os.File, error) {
|
||||||
|
// The file is already in the cache
|
||||||
|
if index, contains := fc.fileNames[fileName]; contains {
|
||||||
|
return fc.files[index], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The file was not in the cache, try and insert it
|
||||||
|
|
||||||
|
// Random cache eviction
|
||||||
|
indexToRemove := rand.Intn(fc.cacheSize)
|
||||||
|
|
||||||
|
// Remove the old value
|
||||||
|
oldName, present := fc.indexesOfFiles[indexToRemove]
|
||||||
|
|
||||||
|
// If there is already a value, delete its mapping
|
||||||
|
if present {
|
||||||
|
delete(fc.fileNames, oldName)
|
||||||
|
delete(fc.indexesOfFiles, indexToRemove)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert the new value
|
||||||
|
fc.files[indexToRemove] = f
|
||||||
|
fc.fileNames[fileName] = indexToRemove
|
||||||
|
fc.indexesOfFiles[indexToRemove] = fileName
|
||||||
|
|
||||||
|
return f, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user