package org.lodder.subtools.sublibrary.cache; import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DiskCache<K, T> extends InMemoryCache<K, T> { private Connection conn; private static final Logger LOGGER = LoggerFactory.getLogger(DiskCache.class); public DiskCache(long crunchifyTimeToLive, long crunchifyTimerInterval, int maxItems, String username, String password) { super(crunchifyTimeToLive, crunchifyTimerInterval, maxItems); File path = new File(System.getProperty("user.home"), ".MultiSubDownloader"); if (!path.exists()) { if (!path.mkdir()) { throw new RuntimeException("Could not create folder " + path); } } PreparedStatement prep = null; try { Class.forName("org.hsqldb.jdbcDriver"); conn = DriverManager.getConnection("jdbc:hsqldb:file:" + path.toString() + "/diskcache.hsqldb;hsqldb.write_delay=false;shutdown=true", username, password); prep = conn.prepareStatement("create table IF NOT EXISTS cacheobjects (key OTHER, cacheobject OTHER);"); prep.execute(); prep.close(); fillCacheMap(); } catch (ClassNotFoundException e) { throw new RuntimeException("Unable to load jdbcdriver for diskcache"); } catch (SQLException e) { throw new RuntimeException(e); } finally { try { if (prep != null) prep.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } @SuppressWarnings("unchecked") private void fillCacheMap() { try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery("SELECT key, cacheobject FROM cacheobjects"); while (rs.next()) { synchronized (cacheMap) { cacheMap.put(rs.getObject("key"), rs.getObject("cacheobject")); } } rs.close(); } catch (SQLException e) { LOGGER.error("Unable to insert object in disk cache!", e); } finally { } } public void remove(K key) { super.remove(key); try (PreparedStatement prep = conn.prepareCall("delete from cacheobjects where key = ?")) { prep.clearParameters(); prep.setObject(1, key); prep.execute(); } catch (SQLException e) { LOGGER.error("Unable to delete object from disk cache!", e); } } public void put(K key, T value) { super.put(key, value); try (PreparedStatement prep = conn.prepareCall("INSERT INTO cacheobjects (key,cacheobject) VALUES (?,?)")) { prep.clearParameters(); prep.setObject(1, key); synchronized (cacheMap) { CacheObject<?, ?> cacheObject = (CacheObject<?, ?>) cacheMap.get(key); prep.setObject(2, cacheObject); } prep.execute(); } catch (SQLException e) { LOGGER.error("Unable to insert object in disk cache!", e); } } }