Skip to content

Commit

Permalink
parameterize max files for camera cache
Browse files Browse the repository at this point in the history
  • Loading branch information
scottfeldman committed Dec 14, 2024
1 parent 5905b73 commit 685fcdb
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 24 deletions.
54 changes: 31 additions & 23 deletions devices/camera/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,39 @@ import (
)

const (
maxMemoryFiles = 100 // Maximum files in memory cache
maxFiles = 2000 // Maximum files in disk cache
maxBuckets = 40 // Number of lock buckets
fileCacheDir = "./camera-images" // Directory where files will be stored
fileCacheDir = "./camera-images" // Directory where files will be stored
)

// Cache struct encapsulates the memory cache, file cache, and index tracking
type Cache struct {
memoryCache map[uint32][]byte // Memory cache (FIFO)
memoryCacheList *list.List // List to track the order of keys in memory cache
memoryCacheLock sync.RWMutex // Lock for memory cache
fileLocks [maxBuckets]*sync.RWMutex // Array of lock buckets
currentIndex uint32 // Tracks the current file index (accessed atomically)
memoryCache map[uint32][]byte // Memory cache (FIFO)
memoryCacheList *list.List // List to track the order of keys in memory cache
memoryCacheLock sync.RWMutex // Lock for memory cache
fileLocks []sync.RWMutex // Array of lock buckets
maxMemoryFiles uint32 // Maximum files in memory cache
maxFiles uint32 // Maximum files in disk cache
maxBuckets uint32 // Number of lock buckets
currentIndex uint32 // Tracks the current file index (accessed atomically)
}

// New creates and initializes a new Cache instance
func New() *Cache {
func New(maxMemoryFiles, maxFiles uint32) *Cache {
var c Cache

c.maxMemoryFiles = maxMemoryFiles
c.maxFiles = maxFiles
c.maxBuckets = (maxFiles / 50) + 1

// Initialize the file lock buckets
for i := 0; i < maxBuckets; i++ {
c.fileLocks[i] = &sync.RWMutex{}
c.fileLocks = make([]sync.RWMutex, c.maxBuckets)
for i := uint32(0); i < c.maxBuckets; i++ {
c.fileLocks[i] = sync.RWMutex{}
}

c.memoryCache = make(map[uint32][]byte)
c.memoryCacheList = list.New()
c.currentIndex = 1

return &c
}

Expand Down Expand Up @@ -94,10 +102,10 @@ func (c *Cache) Preload() error {
atomic.StoreUint32(&c.currentIndex, 1)
}

// Add files to memory cache in the correct order (newest first), but no more than maxMemoryFiles
// Add files to memory cache in the correct order (newest first), but no more than c.maxMemoryFiles
for i, file := range fileData {
if i >= maxMemoryFiles {
break // Stop after adding maxMemoryFiles files to memory cache
if uint32(i) >= c.maxMemoryFiles {
break // Stop after adding c.maxMemoryFiles files to memory cache
}
jpeg, err := os.ReadFile(file.filename)
if err != nil {
Expand Down Expand Up @@ -150,38 +158,38 @@ func (c *Cache) GetJpeg(index uint32) ([]byte, uint32, uint32, error) {
}

func (c *Cache) calculatePreviousIndex(index uint32) uint32 {
// If the index is 1, the previous index is maxFiles (wrap around)
// If the index is 1, the previous index is c.maxFiles (wrap around)
if index == 1 {
return maxFiles
return c.maxFiles
}
// Otherwise, just subtract 1
return index - 1
}

func (c *Cache) calculateNextIndex(index uint32) uint32 {
// If the index is maxFiles, the next index is 1 (wrap around)
if index == maxFiles {
// If the index is c.maxFiles, the next index is 1 (wrap around)
if index == c.maxFiles {
return 1
}
// Otherwise, just add 1
return index + 1
}

func (c *Cache) lockFile(index uint32) {
bucketIndex := index % maxBuckets
bucketIndex := index % c.maxBuckets
c.fileLocks[bucketIndex].Lock()
}

func (c *Cache) unlockFile(index uint32) {
bucketIndex := index % maxBuckets
bucketIndex := index % c.maxBuckets
c.fileLocks[bucketIndex].Unlock()
}

func (c *Cache) addToMemoryCache(index uint32, jpeg []byte) {

c.memoryCacheLock.Lock()

if len(c.memoryCache) >= maxMemoryFiles {
if uint32(len(c.memoryCache)) >= c.maxMemoryFiles {
// Remove the oldest memory cache item if full
oldestElement := c.memoryCacheList.Front()
if oldestElement != nil {
Expand All @@ -202,7 +210,7 @@ func (c *Cache) SaveJpeg(jpeg []byte) error {
current := atomic.LoadUint32(&c.currentIndex)

next := current + 1
if next > maxFiles {
if next > c.maxFiles {
next = 1
}

Expand Down
5 changes: 5 additions & 0 deletions devices/camera/camera-demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ import (
"os/exec"
)

var (
maxMemoryFiles uint32 = 50
maxFiles uint32 = 500
)

func captureJpeg() ([]byte, error) {
index := 0
filename := fmt.Sprintf("images/%d.jpg", index)
Expand Down
5 changes: 5 additions & 0 deletions devices/camera/camera-rpi.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import (
"os/exec"
)

var (
maxMemoryFiles uint32 = 200
maxFiles uint32 = 2000
)

func captureJpeg() ([]byte, error) {

// Create a command for libcamera-still to output to stdout
Expand Down
5 changes: 5 additions & 0 deletions devices/camera/camera-x86-64.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import (
"os/exec"
)

var (
maxMemoryFiles uint32 = 200
maxFiles uint32 = 2000
)

// captureImage captures a jpeg image using ffmpeg
func captureJpeg() ([]byte, error) {

Expand Down
2 changes: 1 addition & 1 deletion devices/camera/camera.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type msgImage struct {
}

func NewModel() device.Devicer {
return &camera{Cache: cache.New()}
return &camera{Cache: cache.New(maxMemoryFiles, maxFiles)}
}

func (c *camera) GetConfig() device.Config {
Expand Down

0 comments on commit 685fcdb

Please sign in to comment.