///|
let default_image_cache_max_bytes : Int = 8 * 1024 * 1024
///|
pub struct ImageCache {
data : Map[String, String]
order : Array[String]
mut total_bytes : Int
mut max_bytes : Int
}
///|
pub fn ImageCache::new(
max_bytes? : Int = default_image_cache_max_bytes,
) -> ImageCache {
{ data: {}, order: [], total_bytes: 0, max_bytes: max_bytes.max(0) }
}
///|
fn remove_order_key(order : Array[String], src : String) -> Unit {
let mut found_idx : Int? = None
for i, key in order {
if key == src {
found_idx = Some(i)
break
}
}
match found_idx {
Some(idx) => {
let _ = order.remove(idx)
}
None => ()
}
}
///|
fn ImageCache::evict_if_needed(self : ImageCache) -> Unit {
while self.total_bytes > self.max_bytes && !self.order.is_empty() {
let evicted_src = self.order.remove(0)
match self.data.get(evicted_src) {
Some(cached_data) => {
self.data.remove(evicted_src)
self.total_bytes = (self.total_bytes - cached_data.length()).max(0)
}
None => ()
}
}
}
///|
pub fn ImageCache::set_max_bytes(self : ImageCache, max_bytes : Int) -> Unit {
self.max_bytes = max_bytes.max(0)
self.evict_if_needed()
}
///|
pub fn ImageCache::put(self : ImageCache, src : String, data : String) -> Unit {
if self.data.contains(src) {
match self.data.get(src) {
Some(existing) =>
self.total_bytes = (self.total_bytes - existing.length()).max(0)
None => ()
}
self.data.remove(src)
remove_order_key(self.order, src)
}
self.data.set(src, data)
self.order.push(src)
self.total_bytes += data.length()
self.evict_if_needed()
}
///|
pub fn ImageCache::get(self : ImageCache, src : String) -> String? {
self.data.get(src)
}
///|
pub fn ImageCache::contains(self : ImageCache, src : String) -> Bool {
self.data.contains(src)
}
///|
pub fn ImageCache::is_empty(self : ImageCache) -> Bool {
self.data.is_empty()
}
///|
pub fn ImageCache::total_bytes(self : ImageCache) -> Int {
self.total_bytes
}
///|
pub fn ImageCache::max_bytes(self : ImageCache) -> Int {
self.max_bytes
}