cache
Details
.gitignore 34(+34 -0)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..4a482b8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,34 @@
+# ignore eclipse project files
+.project
+.classpath
+
+# ignore Intellij Idea project files
+.idea
+*.iml
+
+# Netbeans
+/nbproject/
+/nbactions.xml
+
+# Netbeans deploy
+/build/
+
+# Maven deploy
+/target/
+
+# Ant deploy
+/dist/
+
+# Class files
+*.class
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.ear
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
pom.xml 13(+13 -0)
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..2995c37
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>br.ufrgs.inf.prosoft.cache</groupId>
+ <artifactId>Cache</artifactId>
+ <version>1.0</version>
+ <packaging>jar</packaging>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ <maven.compiler.source>1.8</maven.compiler.source>
+ <maven.compiler.target>1.8</maven.compiler.target>
+ </properties>
+</project>
\ No newline at end of file
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/Cache.java b/src/main/java/br/ufrgs/inf/prosoft/cache/Cache.java
new file mode 100644
index 0000000..0ed51a2
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/Cache.java
@@ -0,0 +1,22 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.cache;
+
+/**
+ *
+ * @author romulo
+ */
+public interface Cache {
+
+ public Object put(String key, Object value, long timeToLive);
+
+ public Object put(String key, Object value);
+
+ public Object get(Object key);
+
+ public void invalidate(String key);
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/CachingPerformance.java b/src/main/java/br/ufrgs/inf/prosoft/cache/CachingPerformance.java
new file mode 100644
index 0000000..3f03ba5
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/CachingPerformance.java
@@ -0,0 +1,81 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.cache;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author romulo
+ */
+public class CachingPerformance {
+
+ private int misses;
+ private int hits;
+ private int invalidations;
+ private int maximumSize;
+
+ public CachingPerformance() {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ Logger.getLogger(CachingPerformance.class.getName()).log(Level.INFO, "printing caching metrics");
+ System.out.println(CachingPerformance.this);
+ }
+ });
+ }
+
+ public void reduce(CachingPerformance cachingPerformance) {
+ this.misses += cachingPerformance.misses;
+ this.hits += cachingPerformance.hits;
+ this.invalidations += cachingPerformance.invalidations;
+ this.maximumSize = Math.max(this.maximumSize, cachingPerformance.maximumSize);
+ }
+
+ public void registerHit() {
+ this.hits++;
+ }
+
+ public void registerMiss() {
+ this.misses++;
+ }
+
+ public void registerInvalidation() {
+ this.invalidations++;
+ }
+
+ public void registerEntry() {
+ this.maximumSize++;
+ }
+
+ public void registerSize(int size) {
+ this.maximumSize = Math.max(this.maximumSize, size);
+ }
+
+ public long getRoundedHitRatio() {
+ return Math.round(getHitRatio());
+ }
+
+ public double getHitRatio() {
+ return this.hits * 100.0 / (this.hits + this.misses);
+ }
+
+ public String needInvalidation() {
+ return this.invalidations > 0 ? "yes" : "no";
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("H").append(this.hits);
+ stringBuilder.append(" M").append(this.misses);
+ stringBuilder.append(" I").append(this.invalidations);
+ stringBuilder.append(" S").append(this.maximumSize);
+ return stringBuilder.toString();
+ }
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/GetterCache.java b/src/main/java/br/ufrgs/inf/prosoft/cache/GetterCache.java
new file mode 100644
index 0000000..08a7f82
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/GetterCache.java
@@ -0,0 +1,68 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.cache;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author romulo
+ */
+public class GetterCache {
+
+ private final CachingPerformance cachingPerformance;
+ private Object result;
+ private boolean isFilled;
+
+ public GetterCache() {
+ this.isFilled = false;
+ this.cachingPerformance = new CachingPerformance();
+ }
+
+ public GetterCache(CachingPerformance cachingPerformance) {
+ this.isFilled = false;
+ this.cachingPerformance = cachingPerformance;
+ }
+
+ public Object put(Object value, long timeToLive) {
+ Object put = put(value);
+ Thread thread = new Thread(() -> {
+ try {
+ Thread.sleep(timeToLive);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(SingleCache.class.getName()).log(Level.SEVERE, "interrupted time to live");
+ }
+ this.result = null;
+ this.isFilled = false;
+ });
+ thread.start();
+ return put;
+ }
+
+ public Object put(Object value) {
+ this.result = value;
+ this.isFilled = true;
+ this.cachingPerformance.registerSize(1);
+ return this.result;
+ }
+
+ public Object get() {
+ if (this.isFilled == false) {
+ this.cachingPerformance.registerMiss();
+ return null;
+ }
+ this.cachingPerformance.registerHit();
+ return this.result;
+ }
+
+ public void invalidate() {
+ this.isFilled = false;
+ this.result = null;
+ this.cachingPerformance.registerInvalidation();
+ }
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java b/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java
new file mode 100644
index 0000000..f4084f1
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/MultiCache.java
@@ -0,0 +1,75 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.cache;
+
+import java.util.HashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author romulo
+ */
+public class MultiCache extends HashMap<String, Object> implements Cache {
+
+ private final CachingPerformance cachingPerformance;
+
+ public MultiCache() {
+ this.cachingPerformance = new CachingPerformance();
+ }
+
+ public MultiCache(CachingPerformance cachingPerformance) {
+ this.cachingPerformance = cachingPerformance;
+ }
+
+ public CachingPerformance getCachingPerformance() {
+ return this.cachingPerformance;
+ }
+
+ @Override
+ public Object put(String key, Object value, long timeToLive) {
+ Object put = put(key, value);
+ Thread thread = new Thread(() -> {
+ try {
+ Thread.sleep(timeToLive);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(MultiCache.class.getName()).log(Level.SEVERE, "interrupted time to live");
+ }
+ MultiCache.super.remove(key);
+ });
+ thread.start();
+ return put;
+ }
+
+ @Override
+ public Object put(String key, Object value) {
+ Object oldReference = super.put(key, value);
+ if (oldReference == null) {
+ this.cachingPerformance.registerSize(size());
+ }
+ return oldReference;
+ }
+
+ @Override
+ public Object get(Object key) {
+ Object get = super.get(key);
+ if (get == null) {
+ this.cachingPerformance.registerMiss();
+ } else {
+ this.cachingPerformance.registerHit();
+ }
+ return get;
+ }
+
+ @Override
+ public void invalidate(String key) {
+ Object remove = this.remove(key);
+ if (remove != null) {
+ this.cachingPerformance.registerInvalidation();
+ }
+ }
+
+}
diff --git a/src/main/java/br/ufrgs/inf/prosoft/cache/SingleCache.java b/src/main/java/br/ufrgs/inf/prosoft/cache/SingleCache.java
new file mode 100644
index 0000000..12d6ac1
--- /dev/null
+++ b/src/main/java/br/ufrgs/inf/prosoft/cache/SingleCache.java
@@ -0,0 +1,74 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package br.ufrgs.inf.prosoft.cache;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ *
+ * @author romulo
+ */
+public class SingleCache implements Cache {
+
+ private final CachingPerformance cachingPerformance;
+ private String lastInput;
+ private Object result;
+
+ public SingleCache() {
+ this.cachingPerformance = new CachingPerformance();
+ }
+
+ public SingleCache(CachingPerformance cachingPerformance) {
+ this.cachingPerformance = cachingPerformance;
+ }
+
+ public CachingPerformance getCachingPerformance() {
+ return this.cachingPerformance;
+ }
+
+ @Override
+ public Object put(String key, Object value, long timeToLive) {
+ Object put = put(key, value);
+ Thread thread = new Thread(() -> {
+ try {
+ Thread.sleep(timeToLive);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(SingleCache.class.getName()).log(Level.SEVERE, "interrupted time to live");
+ }
+ this.lastInput = null;
+ this.result = null;
+ });
+ thread.start();
+ return put;
+ }
+
+ @Override
+ public Object put(String key, Object value) {
+ this.lastInput = key;
+ this.result = value;
+ this.cachingPerformance.registerSize(1);
+ return this.result;
+ }
+
+ @Override
+ public Object get(Object key) {
+ if (key.equals(this.lastInput)) {
+ this.cachingPerformance.registerHit();
+ return this.result;
+ }
+ this.cachingPerformance.registerMiss();
+ return null;
+ }
+
+ @Override
+ public void invalidate(String key) {
+ this.lastInput = null;
+ this.result = null;
+ this.cachingPerformance.registerInvalidation();
+ }
+
+}