Last active
January 5, 2016 17:26
-
-
Save frgomes/f027f696299c624666f3 to your computer and use it in GitHub Desktop.
Scala - cache2k with underlying file storage
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import net.jcip.annotations.NotThreadSafe | |
import org.cache2k.impl.ClockProPlusCache | |
type ImageType = Array[Byte] | |
class CacheSource(dir: java.io.File) | |
extends org.cache2k.CacheSource[String, ImageType] { | |
import java.nio.file.Files | |
import javax.imageio.ImageIO | |
override def get(key: String): ImageType = { | |
val path = dir.toPath.resolve(key.concat(".png")) | |
if (Files.exists(path)) { | |
toBytes(ImageIO.read(path.toFile)) | |
} else { | |
throw new RuntimeException(s"Cannot find image identified by ${key}") | |
} | |
} | |
def put(key: String, value: ImageType): Option[ImageType] = | |
if(value!=null){ | |
val file = dir.toPath.resolve(key.concat(".png")).toFile | |
ImageIO.write(Screencaster.toImage(value), "png", file) | |
Some(value) | |
} else { | |
None:Option[ImageType] | |
} | |
private def toBytes(image: BufferedImage): ImageType = { | |
val bo = new ByteArrayOutputStream() | |
ImageIO.write(image, "png", bo) | |
bo.close() | |
bo.toByteArray | |
} | |
} | |
@NotThreadSafe | |
class Cache(val cacheDir: String, val cacheSize: Int) { | |
import java.io.File | |
private val dir: File = open | |
private val source = new CacheSource(dir) | |
private val images = | |
org.cache2k.CacheBuilder | |
.newCache(classOf[String], classOf[ImageType]) | |
.name(dir.getName) | |
.maxSize(cacheSize) | |
.implementation(classOf[ClockProPlusCache[String, ImageType]]) | |
.source(source) | |
.build | |
/** Returns the value associated with `key`, or None if non-existent. */ | |
def get(key: String): Option[ImageType] = { | |
val value = images.get(key) | |
if(value != null) Some(value) else None:Option[ImageType] | |
} | |
/** Inserts or updates Updates the `value` associated to a `key`. */ | |
def put(key: String, value: ImageType) : Option[ImageType] = | |
if(value != null) { | |
val existing = images.peek(key) | |
if(existing != null) Some(existing) else source.put(key, value) | |
} else { | |
images.remove(key) | |
None:Option[ImageType] | |
} | |
/** Creates the cache directory. */ | |
def open(): java.io.File = { | |
val dir = new File(cacheDir.replace("~", System.getProperty("user.home"))) | |
if(dir.isDirectory) dir else { | |
if(dir.mkdirs()) dir else { | |
throw new RuntimeException(s"cannot create cache ${dir.getAbsolutePath}") | |
} | |
} | |
} | |
/** Closes the cache and ensures that all transient data is flushed onto the underlying persistence storage. */ | |
def close(): Unit = images.close() | |
/** Purges the cache. */ | |
def purge(): Unit = images.purge() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment