ImageCacheImpl

org.mbari.beholder.ImageCacheImpl
class ImageCacheImpl(val root: Path, maxCacheSizeMB: Double, cacheClearPct: Double = ...) extends ImageCache

Disk-backed image frame cache. Frames are indexed by (videoUri, elapsedTime) for O(1) lookups and evicted oldest-first when total on-disk size exceeds maxCacheSizeMB.

Improvements over JpegCache:

  • O(1) lookup via nested ConcurrentHashMap (URI → elapsedMs → Jpeg) instead of O(n) TreeSet.find
  • O(log n) eviction via ConcurrentSkipListSet ordered by creation time; pollFirst() is atomic
  • AtomicLong byte counter avoids floating-point drift from summing MB values
  • AtomicBoolean eviction guard prevents concurrent eviction storms without a global lock
  • scanCache preserves real file creation timestamps for correct age-ordering on restart

Value parameters

cacheClearPct

Fraction of current cache size to free when the limit is exceeded (0 < x <= 1)

maxCacheSizeMB

Maximum allowed on-disk cache size in MB

root

Root directory for cached JPEG files

Attributes

Graph
Supertypes
trait ImageCache
class Object
trait Matchable
class Any

Members list

Value members

Concrete methods

def clearCache(): Unit

Remove all cached JPEGs from disk and clear the in-memory index.

Remove all cached JPEGs from disk and clear the in-memory index.

Attributes

def currentCacheSizeMB: Double
def get(jpeg: CachedImage): Option[CachedImage]

Value parameters

jpeg

The jpeg of interest. This only needs valid url and elapsedTime fields

Attributes

Returns

The jpeg in the cache

def put(cachedImage: CachedImage): CachedImage

Store a image in the cache. Stamps the creation time as now, then triggers eviction if total size exceeds the limit.

Store a image in the cache. Stamps the creation time as now, then triggers eviction if total size exceeds the limit.

Attributes

Returns

The stored Jpeg (with updated creation time)

def remove(cachedImage: CachedImage): Option[CachedImage]

Remove a jpeg from the cache.

Remove a jpeg from the cache.

Value parameters

jpeg

the jpeg to remove

Attributes

def scanCache(): Unit

Scan the cache root directory and rebuild the in-memory index from existing files. Uses each file's filesystem creation timestamp so eviction ordering reflects true file age after a restart (unlike put(), which stamps Instant.now()). Does NOT trigger eviction during the scan.

Scan the cache root directory and rebuild the in-memory index from existing files. Uses each file's filesystem creation timestamp so eviction ordering reflects true file age after a restart (unlike put(), which stamps Instant.now()). Does NOT trigger eviction during the scan.

Attributes

def totalImages: Int

Inherited methods

def get(uri: URI, elapsedTime: Duration, imageType: ImageType, deinterlace: Boolean = ...): Option[CachedImage]

Value parameters

deinterlace

Whether the wanted frame is the deinterlaced variant. Deinterlaced frames are separate cache entries, so this has to match what was stored or the lookup misses.

elapsedTime

The elapsed time into the video

uri

The video URL

Attributes

Inherited from:
ImageCache
def get(uri: URI, elapsedTime: DurationString, imageType: ImageType, deinterlace: Boolean): Option[CachedImage]

Attributes

Inherited from:
ImageCache
def put(uri: URI, elapsedTime: DurationString, path: Path): Option[CachedImage]

Attributes

Inherited from:
ImageCache
def put(uri: URI, elapsedTime: Duration, path: Path): Option[CachedImage]

Store a cachedImage in the cache

Store a cachedImage in the cache

Value parameters

elapsedTime

The elasped time into the video

path

The on disk location of the jpeg. It must be under the cache's root directory

uri

The video URL

Attributes

Inherited from:
ImageCache
def remove(uri: URI, elapsedTime: Duration, imageType: ImageType): Option[CachedImage]

Attributes

Inherited from:
ImageCache

Concrete fields

val root: Path