cache

first commit. added getter cache, time to live and shutdown

12/11/2018 3:49:49 AM

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();
+    }
+
+}