feat: Added a file cache
This commit is contained in:
		
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user