diff --git a/.travis.yml b/.travis.yml index 85c5521..1d7df3c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,10 +7,10 @@ android: # - tools # The BuildTools version used by your project - - build-tools-21.1.2 + - build-tools-25.0.1 # The SDK version used to compile your project - - android-23 + - android-25 # Additional components - extra-google-m2repository @@ -19,7 +19,7 @@ android: # Specify at least one system image, # if you need to run emulator(s) during your tests - - sys-img-armeabi-v7a-android-21 + - sys-img-armeabi-v7a-android-25 before_script: # Create and start emulator @@ -30,5 +30,5 @@ before_script: script: - ./gradlew clean - - ./gradlew dualcache-library:connectedAndroidTest -Ptravis --stacktrace - #- ./gradlew dualcache:check -Ptravis --stacktrace + #- ./gradlew dualcache-library:connectedAndroidTest -Ptravis --stacktrace + - ./gradlew dualcache:check -Ptravis --stacktrace diff --git a/build.gradle b/build.gradle index 731ab7a..1288679 100644 --- a/build.gradle +++ b/build.gradle @@ -2,9 +2,10 @@ buildscript { repositories { mavenCentral() + jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0' + classpath 'com.android.tools.build:gradle:2.2.3' } } @@ -21,3 +22,5 @@ allprojects { mavenCentral() } } + +apply from: 'dependencies.gradle' diff --git a/config/quality.gradle b/config/quality.gradle index ff8218d..1bf7408 100644 --- a/config/quality.gradle +++ b/config/quality.gradle @@ -16,7 +16,7 @@ task checkstyle(type: Checkstyle) { } -task findbugs(type: FindBugs, dependsOn: assembleDebug) { +task findbugs(type: FindBugs, dependsOn: "assembleDebug") { ignoreFailures = false effort = "max" reportLevel = "high" diff --git a/dependencies.gradle b/dependencies.gradle new file mode 100644 index 0000000..e23701c --- /dev/null +++ b/dependencies.gradle @@ -0,0 +1,13 @@ +ext { + compileSdkVersion = 25 + buildToolsVersion = '25.0.1' + minSdkVersion = 12 + targetSdkVersion = 25 + + javaVersion = 1.7 + + diskLruVersion = '2.0.2' + jacksonDatabindVersion = '2.4.2' + + androidSupportTestRunner = '0.5' +} diff --git a/dualcache-demoapp/build.gradle b/dualcache-demoapp/build.gradle index 29f426b..8db92ea 100644 --- a/dualcache-demoapp/build.gradle +++ b/dualcache-demoapp/build.gradle @@ -2,14 +2,14 @@ apply plugin: 'com.android.application' apply from: '../config/quality.gradle' android { - compileSdkVersion 21 - buildToolsVersion '21.1.2' + compileSdkVersion project.compileSdkVersion + buildToolsVersion project.buildToolsVersion defaultConfig { - minSdkVersion 9 - targetSdkVersion 21 - versionCode 1 - versionName "1.0" + minSdkVersion project.minSdkVersion + targetSdkVersion project.targetSdkVersion + versionCode Integer.parseInt(project.VERSION_CODE) + versionName project.VERSION_NAME } buildTypes { release { diff --git a/dualcache-jsonserializer/build.gradle b/dualcache-jsonserializer/build.gradle index 0d50e25..55fb2f3 100644 --- a/dualcache-jsonserializer/build.gradle +++ b/dualcache-jsonserializer/build.gradle @@ -2,9 +2,9 @@ apply plugin: 'java' apply from: '../maven_push_java.gradle' dependencies { - compile 'com.fasterxml.jackson.core:jackson-databind:2.4.2' + compile "com.fasterxml.jackson.core:jackson-databind:${jacksonDatabindVersion}" compile project(path: ':dualcache-serializerinterface') - sourceCompatibility = 1.7 - targetCompatibility = 1.7 + sourceCompatibility = project.javaVersion + targetCompatibility = project.javaVersion } diff --git a/dualcache-library/build.gradle b/dualcache-library/build.gradle index 0a79a7f..5db874b 100644 --- a/dualcache-library/build.gradle +++ b/dualcache-library/build.gradle @@ -1,16 +1,17 @@ +import com.android.builder.core.BuilderConstants + apply plugin: 'com.android.library' apply from: '../config/quality.gradle' apply from: '../maven_push.gradle' android { - - compileSdkVersion 23 - buildToolsVersion '21.1.2' + compileSdkVersion project.compileSdkVersion + buildToolsVersion project.buildToolsVersion defaultConfig { - minSdkVersion 9 - targetSdkVersion 23 - versionCode 1 + minSdkVersion project.minSdkVersion + targetSdkVersion project.targetSdkVersion + versionCode Integer.parseInt(project.VERSION_CODE) versionName project.VERSION_NAME testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } @@ -26,15 +27,15 @@ android { dependencies { compile project (':dualcache-serializerinterface') - compile 'com.jakewharton:disklrucache:2.0.2' + compile "com.jakewharton:disklrucache:${project.diskLruVersion}" - androidTestCompile 'com.android.support.test:runner:0.3' + androidTestCompile "com.android.support.test:runner:${project.androidSupportTestRunner}" androidTestCompile project (':dualcache-jsonserializer') } android.libraryVariants.all { variant -> def name = variant.buildType.name - if (name.equals(com.android.builder.core.BuilderConstants.DEBUG)) { + if (name.equals(BuilderConstants.DEBUG)) { return; // Skip debug builds. } def task = project.tasks.create "jar${name.capitalize()}", Jar diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/DualCacheTest.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/DualCacheTest.java index 1f4aaac..7b3fb2b 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/DualCacheTest.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/DualCacheTest.java @@ -1,14 +1,16 @@ package com.vincentbrison.openlibraries.android.dualcache.lib; +import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; -import android.test.AndroidTestCase; import android.util.Log; +import com.vincentbrison.openlibraries.android.dualcache.CacheSerializer; import com.vincentbrison.openlibraries.android.dualcache.DualCache; +import com.vincentbrison.openlibraries.android.dualcache.DualCacheDiskMode; +import com.vincentbrison.openlibraries.android.dualcache.DualCacheRamMode; import com.vincentbrison.openlibraries.android.dualcache.JsonSerializer; import com.vincentbrison.openlibraries.android.dualcache.SizeOf; -import com.vincentbrison.openlibraries.android.dualcache.CacheSerializer; import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.AbstractVehicule; import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.CoolBike; import com.vincentbrison.openlibraries.android.dualcache.lib.testobjects.CoolCar; @@ -21,129 +23,161 @@ import java.util.ArrayList; import java.util.List; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; + @RunWith(AndroidJUnit4.class) -public abstract class DualCacheTest extends AndroidTestCase { +public abstract class DualCacheTest { protected static final int RAM_MAX_SIZE = 1000; protected static final int DISK_MAX_SIZE = 20 * RAM_MAX_SIZE; protected static final String CACHE_NAME = "test"; protected static final int TEST_APP_VERSION = 0; - protected DualCache mCache; + protected DualCache cache; protected CacheSerializer defaultCacheSerializer; + private Context context; + + protected Context getContext() { + return context; + } @Before - @Override public void setUp() throws Exception { - super.setUp(); defaultCacheSerializer = new JsonSerializer<>(AbstractVehicule.class); - setContext(InstrumentationRegistry.getTargetContext()); + context = InstrumentationRegistry.getTargetContext(); } @After - @Override public void tearDown() throws Exception { - mCache.invalidate(); - super.tearDown(); + cache.invalidate(); } @Test public void testBasicOperations() throws Exception { CoolCar car = new CoolCar(); - mCache.put("key", car); - if (mCache.getRAMMode().equals(DualCache.DualCacheRamMode.DISABLE) && - mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertNull(mCache.get("key")); + String keyCar = "car"; + cache.put(keyCar, car); + if (cache.getRAMMode().equals(DualCacheRamMode.DISABLE) && + cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); } else { - assertEquals(car, mCache.get("key")); + assertEquals(car, cache.get(keyCar)); + assertEquals(true, cache.contains(keyCar)); } - mCache.invalidateRAM(); - if (mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertNull(mCache.get("key")); + cache.invalidateRAM(); + if (cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); } else { - assertEquals(car, mCache.get("key")); + assertEquals(car, cache.get(keyCar)); + assertEquals(true, cache.contains(keyCar)); } - mCache.put("key", car); - if (mCache.getRAMMode().equals(DualCache.DualCacheRamMode.DISABLE) && - mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertNull(mCache.get("key")); + cache.put(keyCar, car); + if (cache.getRAMMode().equals(DualCacheRamMode.DISABLE) && + cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); } else { - assertEquals(car, mCache.get("key")); + assertEquals(car, cache.get(keyCar)); + assertEquals(true, cache.contains(keyCar)); } - mCache.invalidate(); - assertNull(mCache.get("key")); + cache.invalidate(); + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); CoolBike bike = new CoolBike(); - mCache.put("car", car); - mCache.put("bike", bike); - if (mCache.getRAMMode().equals(DualCache.DualCacheRamMode.DISABLE) && - mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertNull(mCache.get("car")); - assertNull(mCache.get("bike")); + cache.put(keyCar, car); + String keyBike = "bike"; + cache.put(keyBike, bike); + if (cache.getRAMMode().equals(DualCacheRamMode.DISABLE) && + cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); + assertNull(cache.get(keyBike)); + assertEquals(false, cache.contains(keyBike)); } else { - assertEquals(mCache.get("car"), car); - assertEquals(mCache.get("bike"), bike); + assertEquals(cache.get(keyCar), car); + assertEquals(true, cache.contains(keyCar)); + assertEquals(cache.get(keyBike), bike); + assertEquals(true, cache.contains(keyBike)); } } @Test public void testBasicOperations2() throws Exception { CoolCar car = new CoolCar(); - mCache.put("key", car); - mCache.invalidateRAM(); - if (mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertNull(mCache.get("key")); + String keyCar = "car"; + cache.put(keyCar, car); + cache.invalidateRAM(); + if (cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); } else { - assertEquals(car, mCache.get("key")); - mCache.invalidateRAM(); + assertEquals(car, cache.get(keyCar)); + assertEquals(true, cache.contains(keyCar)); + cache.invalidateRAM(); } - mCache.invalidateDisk(); - assertNull(mCache.get("key")); + cache.invalidateDisk(); + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); - mCache.put("key", car); - mCache.invalidateRAM(); - if (mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertNull(mCache.get("key")); + cache.put(keyCar, car); + cache.invalidateRAM(); + if (cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); } else { - assertEquals(car, mCache.get("key")); + assertEquals(car, cache.get(keyCar)); + assertEquals(true, cache.contains(keyCar)); } - mCache.invalidate(); - assertNull(mCache.get("key")); + cache.invalidate(); + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); CoolBike bike = new CoolBike(); - mCache.put("car", car); - mCache.put("bike", bike); - mCache.delete("car"); - mCache.delete("bike"); - assertNull(mCache.get("car")); - assertNull(mCache.get("bike")); + String keyBike = "bike"; + cache.put(keyCar, car); + cache.put(keyBike, bike); + cache.delete(keyCar); + cache.delete(keyBike); + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); + assertNull(cache.get(keyBike)); + assertEquals(false, cache.contains(keyBike)); } @Test public void testLRUPolicy() { - mCache.invalidate(); + cache.invalidate(); CoolCar carToEvict = new CoolCar(); - mCache.put("car", carToEvict); - long size = mCache.getRamSize(); + String keyCar = "car"; + cache.put(keyCar, carToEvict); + long size = cache.getRamUsedInBytes(); int numberOfItemsToAddForRAMEviction = (int) (RAM_MAX_SIZE / size); for (int i = 0; i < numberOfItemsToAddForRAMEviction; i++) { - mCache.put("car" + i, new CoolCar()); + cache.put(keyCar + i, new CoolCar()); } - mCache.invalidateDisk(); - assertNull(mCache.get("car")); + cache.invalidateDisk(); + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); - mCache.put("car", carToEvict); + cache.put(keyCar, carToEvict); for (int i = 0; i < numberOfItemsToAddForRAMEviction; i++) { - mCache.put("car" + i, new CoolCar()); + cache.put(keyCar + i, new CoolCar()); } - if (!mCache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE)) { - assertEquals(carToEvict, mCache.get("car")); + if (!cache.getDiskMode().equals(DualCacheDiskMode.DISABLE)) { + assertEquals(carToEvict, cache.get(keyCar)); + assertEquals(true, cache.contains(keyCar)); } else { - assertNull(mCache.get("car")); + assertNull(cache.get(keyCar)); + assertEquals(false, cache.contains(keyCar)); } } @@ -151,7 +185,7 @@ public void testLRUPolicy() { public void testConcurrentAccess() { List threads = new ArrayList<>(); for (int i = 0; i < 10; i++) { - threads.add(createWrokerThread(mCache)); + threads.add(createWrokerThread(cache)); } Log.d("dualcachedebuglogti", "start worker threads"); for (Thread thread : threads) { @@ -175,17 +209,20 @@ private Thread createWrokerThread(final DualCache cache) { int sMaxNumberOfRun = 1000; @Override public void run() { + String key = "key"; try { int numberOfRun = 0; while (numberOfRun++ < sMaxNumberOfRun) { Thread.sleep((long) (Math.random() * 2)); double choice = Math.random(); if (choice < 0.4) { - cache.put("key", new CoolCar()); + cache.put(key, new CoolCar()); } else if (choice < 0.5) { - cache.delete("key"); + cache.delete(key); } else if (choice < 0.8) { - cache.get("key"); + cache.get(key); + } else if (choice < 0.9) { + cache.contains(key); } else if (choice < 1) { cache.invalidate(); } else { diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/TestIssue11.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/TestIssue11.java index b1051b3..69d7c5d 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/TestIssue11.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/TestIssue11.java @@ -1,25 +1,30 @@ package com.vincentbrison.openlibraries.android.dualcache.lib; +import android.content.Context; import android.support.test.InstrumentationRegistry; -import android.test.AndroidTestCase; +import android.support.test.runner.AndroidJUnit4; +import com.vincentbrison.openlibraries.android.dualcache.Builder; import com.vincentbrison.openlibraries.android.dualcache.CacheSerializer; import com.vincentbrison.openlibraries.android.dualcache.DualCache; -import com.vincentbrison.openlibraries.android.dualcache.Builder; import com.vincentbrison.openlibraries.android.dualcache.JsonSerializer; import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import java.io.File; import java.util.ArrayList; import java.util.List; +import static org.junit.Assert.assertFalse; + /** * Test issue 11. */ -public class TestIssue11 extends AndroidTestCase { +@RunWith(AndroidJUnit4.class) +public class TestIssue11 { private static final int CACHE_SIZE = 10 * 1024 * 1024; // 10 MB private static final int CACHE_RAM_ENTRIES = 25; protected static final String CACHE_NAME = "test"; @@ -27,13 +32,11 @@ public class TestIssue11 extends AndroidTestCase { protected DualCache mCache; @Before - @Override public void setUp() throws Exception { - super.setUp(); - setContext(InstrumentationRegistry.getTargetContext()); - File cacheDir = new File(mContext.getCacheDir(), CACHE_NAME); + Context context = InstrumentationRegistry.getTargetContext(); + File cacheDir = new File(context.getCacheDir(), CACHE_NAME); CacheSerializer jsonSerializer = new JsonSerializer<>(String.class); - mCache = new Builder<>(CACHE_NAME, 0, String.class) + mCache = new Builder(CACHE_NAME, 0) .enableLog() .useSerializerInRam(CACHE_RAM_ENTRIES, jsonSerializer) .useSerializerInDisk(CACHE_SIZE, cacheDir, jsonSerializer) @@ -41,10 +44,8 @@ public void setUp() throws Exception { } @After - @Override public void tearDown() throws Exception { mCache.invalidate(); - super.tearDown(); } @Test diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskCustomSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskCustomSerializer.java index 76881fb..5b6c576 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskCustomSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskCustomSerializer.java @@ -9,10 +9,14 @@ public class NoRamDiskCustomSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .noRam() - .useSerializerInDisk(DISK_MAX_SIZE, true, new DualCacheTest.SerializerForTesting(), getContext()) + .useSerializerInDisk( + DISK_MAX_SIZE, + true, + new DualCacheTest.SerializerForTesting(), + getContext()) .build(); } } diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskDefaultSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskDefaultSerializer.java index e5efcc0..e2a024a 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskDefaultSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/NoRamDiskDefaultSerializer.java @@ -9,7 +9,7 @@ public class NoRamDiskDefaultSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .noRam() .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskCustomSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskCustomSerializer.java index c8ca9a3..a903d1c 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskCustomSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskCustomSerializer.java @@ -9,7 +9,7 @@ public class RamCustomSerializerDiskCustomSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useSerializerInRam(RAM_MAX_SIZE, new SerializerForTesting()) .useSerializerInDisk(DISK_MAX_SIZE, true, new SerializerForTesting(), getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskDefaultSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskDefaultSerializer.java index 1399a8e..8cb9e0f 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskDefaultSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerDiskDefaultSerializer.java @@ -9,7 +9,7 @@ public class RamCustomSerializerDiskDefaultSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useSerializerInRam(RAM_MAX_SIZE, new SerializerForTesting()) .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerNoDisk.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerNoDisk.java index cb7f933..2700a9a 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerNoDisk.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamCustomSerializerNoDisk.java @@ -9,7 +9,7 @@ public class RamCustomSerializerNoDisk extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useSerializerInRam(RAM_MAX_SIZE, new SerializerForTesting()) .noDisk() diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskCustomSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskCustomSerializer.java index 0c04919..1e3b808 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskCustomSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskCustomSerializer.java @@ -9,7 +9,7 @@ public class RamDefaultSerializerDiskCustomSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useSerializerInRam(RAM_MAX_SIZE, defaultCacheSerializer) .useSerializerInDisk(DISK_MAX_SIZE, true, new SerializerForTesting(), getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskDefaultSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskDefaultSerializer.java index 173a1e1..6e700be 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskDefaultSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerDiskDefaultSerializer.java @@ -9,7 +9,7 @@ public class RamDefaultSerializerDiskDefaultSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useSerializerInRam(RAM_MAX_SIZE, defaultCacheSerializer) .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerNoDisk.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerNoDisk.java index 3c823d9..e636a1e 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerNoDisk.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamDefaultSerializerNoDisk.java @@ -9,7 +9,7 @@ public class RamDefaultSerializerNoDisk extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useSerializerInRam(RAM_MAX_SIZE, defaultCacheSerializer) .noDisk() diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskCustomSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskCustomSerializer.java index 53ebb0c..8659c1f 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskCustomSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskCustomSerializer.java @@ -9,7 +9,7 @@ public class RamReferenceDiskCustomSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()) .useSerializerInDisk(DISK_MAX_SIZE, true, new DualCacheTest.SerializerForTesting(), getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskDefaultSerializer.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskDefaultSerializer.java index c5ade2e..2c59274 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskDefaultSerializer.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceDiskDefaultSerializer.java @@ -9,7 +9,7 @@ public class RamReferenceDiskDefaultSerializer extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()) .useSerializerInDisk(DISK_MAX_SIZE, true, defaultCacheSerializer, getContext()) diff --git a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceNoDisk.java b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceNoDisk.java index 629e18e..cf75c45 100644 --- a/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceNoDisk.java +++ b/dualcache-library/src/androidTest/java/com/vincentbrison/openlibraries/android/dualcache/lib/configurationsToTest/RamReferenceNoDisk.java @@ -9,7 +9,7 @@ public class RamReferenceNoDisk extends DualCacheTest { @Override public void setUp() throws Exception { super.setUp(); - mCache = new Builder<>(CACHE_NAME, TEST_APP_VERSION, AbstractVehicule.class) + cache = new Builder(CACHE_NAME, TEST_APP_VERSION) .enableLog() .useReferenceInRam(RAM_MAX_SIZE, new SizeOfVehiculeForTesting()) .noDisk() diff --git a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/Builder.java b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/Builder.java index bbf7b2c..952bafc 100644 --- a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/Builder.java +++ b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/Builder.java @@ -2,43 +2,43 @@ import android.content.Context; -import com.jakewharton.disklrucache.DiskLruCache; - import java.io.File; -import java.io.IOException; /** * Class used to build a cache. + * * @param is the class of object to store in cache. */ public class Builder { - private static final int VALUES_PER_CACHE_ENTRY = 1; + /** + * Defined the sub folder from {@link android.content.Context#getCacheDir()} used to store all + * the data generated from the use of this library. + */ + private static final String CACHE_FILE_PREFIX = "dualcache"; private String id; private int appVersion; - private Class clazz; private boolean logEnabled; private int maxRamSizeBytes; - private DualCache.DualCacheRamMode ramMode; + private DualCacheRamMode ramMode; private CacheSerializer ramSerializer; private SizeOf sizeOf; private int maxDiskSizeBytes; - private DualCache.DualCacheDiskMode diskMode; + private DualCacheDiskMode diskMode; private CacheSerializer diskSerializer; private File diskFolder; /** * Start the building of the cache. - * @param id is the id of the cache (should be unique). + * + * @param id is the id of the cache (should be unique). * @param appVersion is the app version of the app. If data are already stored in disk cache - * with previous app version, it will be invalidate. - * @param clazz is the class of object to store in cache. + * with previous app version, it will be invalidate. */ - public Builder(String id, int appVersion, Class clazz) { + public Builder(String id, int appVersion) { this.id = id; this.appVersion = appVersion; - this.clazz = clazz; this.ramMode = null; this.diskMode = null; this.logEnabled = false; @@ -46,6 +46,7 @@ public Builder(String id, int appVersion, Class clazz) { /** * Enabling log from the cache. By default disable. + * * @return the builder. */ public Builder enableLog() { @@ -55,6 +56,7 @@ public Builder enableLog() { /** * Builder the cache. Exception will be thrown if it can not be created. + * * @return the cache instance. */ public DualCache build() { @@ -66,45 +68,26 @@ public DualCache build() { } DualCache cache = - new DualCache<>(id, appVersion, clazz, new Logger(logEnabled)); - - cache.setRamMode(ramMode); - switch (ramMode) { - case ENABLE_WITH_SPECIFIC_SERIALIZER: - cache.setRAMSerializer(ramSerializer); - cache.setRamCacheLru(new StringLruCache(maxRamSizeBytes)); - break; - case ENABLE_WITH_REFERENCE: - cache.setRamCacheLru(new ReferenceLruCache<>(maxRamSizeBytes, sizeOf)); - break; - } - - cache.setDiskMode(diskMode); - switch (diskMode) { - case ENABLE_WITH_SPECIFIC_SERIALIZER: - cache.setDiskSerializer(this.diskSerializer); - cache.setDiskCacheSizeInBytes(this.maxDiskSizeBytes); - try { - DiskLruCache diskLruCache = DiskLruCache.open( - this.diskFolder, - this.appVersion, - VALUES_PER_CACHE_ENTRY, - this.maxDiskSizeBytes - ); - cache.setDiskLruCache(diskLruCache); - cache.setDiskCacheFolder(this.diskFolder); - } catch (IOException e) { - e.printStackTrace(); - } - break; - } + new DualCache<>( + appVersion, + new Logger(logEnabled), + ramMode, + ramSerializer, + maxRamSizeBytes, + sizeOf, + diskMode, + diskSerializer, + maxDiskSizeBytes, + diskFolder + ); - boolean isRamDisable = cache.getRAMMode().equals(DualCache.DualCacheRamMode.DISABLE); - boolean isDiskDisable = cache.getDiskMode().equals(DualCache.DualCacheDiskMode.DISABLE); + boolean isRamDisable = cache.getRAMMode().equals(DualCacheRamMode.DISABLE); + boolean isDiskDisable = cache.getDiskMode().equals(DualCacheDiskMode.DISABLE); if (isRamDisable && isDiskDisable) { throw new IllegalStateException("The ram cache layer and the disk cache layer are " + - "disable. You have to use at least one of those layers."); + "disable. You have to use at least one of those " + + "layers."); } return cache; @@ -112,15 +95,17 @@ public DualCache build() { /** * Use Json serialization/deserialization to store and retrieve object from ram cache. + * * @param maxRamSizeBytes is the max amount of ram in bytes which can be used by the ram cache. - * @param serializer is the cache interface which provide serialization/deserialization methods - * for the ram cache layer. + * @param serializer is the cache interface which provide serialization/deserialization + * methods + * for the ram cache layer. * @return the builder. */ public Builder useSerializerInRam( int maxRamSizeBytes, CacheSerializer serializer ) { - this.ramMode = DualCache.DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER; + this.ramMode = DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER; this.maxRamSizeBytes = maxRamSizeBytes; this.ramSerializer = serializer; return this; @@ -130,14 +115,15 @@ public Builder useSerializerInRam( * Store directly objects in ram (without serialization/deserialization). * You have to provide a way to compute the size of an object in * ram to be able to used the LRU capacity of the ram cache. + * * @param maxRamSizeBytes is the max amount of ram which can be used by the ram cache. - * @param handlerSizeOf computes the size of object stored in ram. + * @param handlerSizeOf computes the size of object stored in ram. * @return the builder. */ public Builder useReferenceInRam( int maxRamSizeBytes, SizeOf handlerSizeOf ) { - this.ramMode = DualCache.DualCacheRamMode.ENABLE_WITH_REFERENCE; + this.ramMode = DualCacheRamMode.ENABLE_WITH_REFERENCE; this.maxRamSizeBytes = maxRamSizeBytes; this.sizeOf = handlerSizeOf; return this; @@ -145,25 +131,31 @@ public Builder useReferenceInRam( /** * The ram cache will not be used, meaning that only the disk cache will be used. + * * @return the builder for the disk cache layer. */ public Builder noRam() { - this.ramMode = DualCache.DualCacheRamMode.DISABLE; + this.ramMode = DualCacheRamMode.DISABLE; return this; } /** * Use custom serialization/deserialization to store and retrieve objects from disk cache. + * * @param maxDiskSizeBytes is the max size of disk in bytes which an be used by the disk cache * layer. - * @param usePrivateFiles is true if you want to use {@link Context#MODE_PRIVATE} with the - * default disk cache folder. - * @param serializer provides serialization/deserialization methods for the disk cache layer. - * @param context is used to access file system. + * @param usePrivateFiles is true if you want to use {@link Context#MODE_PRIVATE} with the + * default disk cache folder. + * @param serializer provides serialization/deserialization methods for the disk cache + * layer. + * @param context is used to access file system. * @return the builder. */ public Builder useSerializerInDisk( - int maxDiskSizeBytes, boolean usePrivateFiles, CacheSerializer serializer, Context context + int maxDiskSizeBytes, + boolean usePrivateFiles, + CacheSerializer serializer, + Context context ) { File folder = getDefaultDiskCacheFolder(usePrivateFiles, context); return useSerializerInDisk(maxDiskSizeBytes, folder, serializer); @@ -171,17 +163,19 @@ public Builder useSerializerInDisk( /** * Use custom serialization/deserialization to store and retrieve object from disk cache. + * * @param maxDiskSizeBytes is the max size of disk in bytes which an be used by the disk cache * layer. - * @param diskCacheFolder is the folder where the disk cache will be stored. - * @param serializer provides serialization/deserialization methods for the disk cache layer. + * @param diskCacheFolder is the folder where the disk cache will be stored. + * @param serializer provides serialization/deserialization methods for the disk cache + * layer. * @return the builder. */ public Builder useSerializerInDisk( int maxDiskSizeBytes, File diskCacheFolder, CacheSerializer serializer ) { this.diskFolder = diskCacheFolder; - this.diskMode = DualCache.DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER; + this.diskMode = DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER; this.maxDiskSizeBytes = maxDiskSizeBytes; this.diskSerializer = serializer; return this; @@ -191,13 +185,13 @@ private File getDefaultDiskCacheFolder(boolean usePrivateFiles, Context context) File folder; if (usePrivateFiles) { folder = context.getDir( - DualCache.CACHE_FILE_PREFIX + this.id, + CACHE_FILE_PREFIX + this.id, Context.MODE_PRIVATE ); } else { folder = new File(context.getCacheDir().getPath() - + "/" + DualCache.CACHE_FILE_PREFIX - + "/" + this.id + + "/" + CACHE_FILE_PREFIX + + "/" + this.id ); } return folder; @@ -206,10 +200,11 @@ private File getDefaultDiskCacheFolder(boolean usePrivateFiles, Context context) /** * Use this if you do not want use the disk cache layer, meaning that only the ram cache layer * will be used. + * * @return the builder. */ public Builder noDisk() { - this.diskMode = DualCache.DualCacheDiskMode.DISABLE; + this.diskMode = DualCacheDiskMode.DISABLE; return this; } } diff --git a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCache.java b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCache.java index aaa5f74..076fb7f 100755 --- a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCache.java +++ b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCache.java @@ -20,12 +20,6 @@ import java.io.File; import java.io.IOException; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReadWriteLock; -import java.util.concurrent.locks.ReentrantLock; -import java.util.concurrent.locks.ReentrantReadWriteLock; /** * This class intent to provide a very easy to use, reliable, highly configurable caching library @@ -35,173 +29,89 @@ */ public class DualCache { - /** - * Define the behaviour of the RAM layer. - */ - public enum DualCacheRamMode { - /** - * Means that object will be serialized with a specific serializer in RAM. - */ - ENABLE_WITH_SPECIFIC_SERIALIZER, - - /** - * Means that only references to objects will be stored in the RAM layer. - */ - ENABLE_WITH_REFERENCE, - - /** - * The RAM layer is not used. - */ - DISABLE - } - - /** - * Define the behaviour of the disk layer. - */ - public enum DualCacheDiskMode { - /** - * Means that object will be serialized with a specific serializer in disk. - */ - ENABLE_WITH_SPECIFIC_SERIALIZER, - - /** - * The disk layer is not used. - */ - DISABLE - } - - /** - * Defined the sub folder from {@link android.content.Context#getCacheDir()} used to store all - * the data generated from the use of this library. - */ - protected static final String CACHE_FILE_PREFIX = "dualcache"; - - private static final String LOG_PREFIX = "Entry for "; - - /** - * Unique ID which define a cache. - */ - private String mId; - - /** - * RAM cache. - */ - private RamLruCache mRamCacheLru; - - /** - * Disk cache. - */ - private DiskLruCache mDiskLruCache; - - /** - * Define the class store in this cache. - */ - private Class mClazz; - - /** - * Hold the max size in bytes of the disk cache. - */ - private int mDiskCacheSizeInBytes; - - /** - * Define the folder in which the disk cache will save its files. - */ - private File mDiskCacheFolder; - - /** - * Define the app version of the application (allow you to automatically invalidate data - * from different app version on disk). - */ - private int mAppVersion; - - /** - * By default the RAM layer use JSON serialization to store cached object. - */ - private DualCacheRamMode mRamMode; - - /** - * By default the disk layer use JSON serialization to store cached object. - */ - private DualCacheDiskMode mDiskMode; - - /** - * The handler used when the ram cache is enable with - * {@link DualCache - * .DualCacheRAMMode#ENABLE_WITH_REFERENCE} - */ - private SizeOf mHandlerSizeOf; - - private CacheSerializer mDiskSerializer; - - private CacheSerializer mRamSerializer; - - private final ConcurrentMap mEditionLocks = new ConcurrentHashMap<>(); - private ReadWriteLock mInvalidationReadWriteLock = new ReentrantReadWriteLock(); + private static final int VALUES_PER_CACHE_ENTRY = 1; + + private final RamLruCache ramCacheLru; + private DiskLruCache diskLruCache; + private final int maxDiskSizeBytes; + private final File diskCacheFolder; + private final int appVersion; + private final DualCacheRamMode ramMode; + private final DualCacheDiskMode diskMode; + private final CacheSerializer diskSerializer; + private final CacheSerializer ramSerializer; + private final DualCacheLock dualCacheLock = new DualCacheLock(); private final Logger logger; - - /** - * Constructor which only set global parameter of the cache. - * - * @param id is the id of the cache. - * @param appVersion is the app version of the app. (Data in disk cache will be invalidate if - * their app version is inferior than this app version. - * @param clazz is the Class of object to store in cache. - * @param logger - */ - DualCache(String id, int appVersion, Class clazz, Logger logger) { - mId = id; - mAppVersion = appVersion; - mClazz = clazz; + private final LoggerHelper loggerHelper; + + DualCache( + int appVersion, + Logger logger, + DualCacheRamMode ramMode, + CacheSerializer ramSerializer, + int maxRamSizeBytes, + SizeOf sizeOf, + DualCacheDiskMode diskMode, + CacheSerializer diskSerializer, + int maxDiskSizeBytes, + File diskFolder + ) { + this.appVersion = appVersion; + this.ramMode = ramMode; + this.ramSerializer = ramSerializer; + this.diskMode = diskMode; + this.diskSerializer = diskSerializer; + this.diskCacheFolder = diskFolder; this.logger = logger; - } - - protected int getAppVersion() { - return mAppVersion; - } - - protected String getCacheId() { - return mId; - } - - protected void setDiskLruCache(DiskLruCache diskLruCache) { - mDiskLruCache = diskLruCache; - } - - protected void setRAMSerializer(CacheSerializer ramSerializer) { - mRamSerializer = ramSerializer; - } + this.loggerHelper = new LoggerHelper(logger); + + switch (ramMode) { + case ENABLE_WITH_SPECIFIC_SERIALIZER: + this.ramCacheLru = new StringLruCache(maxRamSizeBytes); + break; + case ENABLE_WITH_REFERENCE: + this.ramCacheLru = new ReferenceLruCache<>(maxRamSizeBytes, sizeOf); + break; + default: + this.ramCacheLru = null; + } - protected void setDiskSerializer(CacheSerializer diskSerializer) { - mDiskSerializer = diskSerializer; + switch (diskMode) { + case ENABLE_WITH_SPECIFIC_SERIALIZER: + this.maxDiskSizeBytes = maxDiskSizeBytes; + try { + openDiskLruCache(diskFolder); + } catch (IOException e) { + logger.logError(e); + } + break; + default: + this.maxDiskSizeBytes = 0; + } } - protected void setRamCacheLru(RamLruCache ramLruCache) { - mRamCacheLru = ramLruCache; + private void openDiskLruCache(File diskFolder) throws IOException { + this.diskLruCache = DiskLruCache.open( + diskFolder, + this.appVersion, + VALUES_PER_CACHE_ENTRY, + this.maxDiskSizeBytes + ); } - /** - * Return the size used in bytes of the RAM cache. - * - * @return the size used in bytes of the RAM cache. - */ - public long getRamSize() { - if (mRamCacheLru == null) { + public long getRamUsedInBytes() { + if (ramCacheLru == null) { return -1; } else { - return mRamCacheLru.size(); + return ramCacheLru.size(); } } - /** - * Return the size used in bytes of the disk cache. - * - * @return the size used in bytes of the disk cache. - */ - public long getDiskSize() { - if (mDiskLruCache == null) { + public long getDiskUsedInBytes() { + if (diskLruCache == null) { return -1; } else { - return mDiskLruCache.size(); + return diskLruCache.size(); } } @@ -212,28 +122,7 @@ public long getDiskSize() { * @return the way objects are cached in RAM layer. */ public DualCacheRamMode getRAMMode() { - return mRamMode; - } - - /** - * Set the way objects are stored in the RAM layer. - * - * @param ramMode is the value to set. - */ - protected void setRamMode(DualCacheRamMode ramMode) { - this.mRamMode = ramMode; - } - - protected void setDiskCacheSizeInBytes(int diskCacheSizeInBytes) { - mDiskCacheSizeInBytes = diskCacheSizeInBytes; - } - - public File getDiskCacheFolder() { - return mDiskCacheFolder; - } - - public void setDiskCacheFolder(File folder) { - mDiskCacheFolder = folder; + return ramMode; } /** @@ -242,7 +131,7 @@ public void setDiskCacheFolder(File folder) { * @return the way objects are cached in disk layer. */ public DualCacheDiskMode getDiskMode() { - return mDiskMode; + return diskMode; } /** @@ -254,33 +143,31 @@ public DualCacheDiskMode getDiskMode() { public void put(String key, T object) { // Synchronize put on each entry. Gives concurrent editions on different entries, and atomic // modification on the same entry. - if (mRamMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE)) { - mRamCacheLru.put(key, object); + if (ramMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE)) { + ramCacheLru.put(key, object); } String ramSerialized = null; - if (mRamMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { - ramSerialized = mRamSerializer.toString(object); - mRamCacheLru.put(key, ramSerialized); + if (ramMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { + ramSerialized = ramSerializer.toString(object); + ramCacheLru.put(key, ramSerialized); } - if (mDiskMode.equals(DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { + if (diskMode.equals(DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { try { - mInvalidationReadWriteLock.readLock().lock(); - getLockForGivenEntry(key).lock(); - DiskLruCache.Editor editor = mDiskLruCache.edit(key); - if (mRamSerializer == mDiskSerializer) { + dualCacheLock.lockDiskEntryWrite(key); + DiskLruCache.Editor editor = diskLruCache.edit(key); + if (ramSerializer == diskSerializer) { // Optimization if using same serializer - editor.set(0, new String(ramSerialized)); + editor.set(0, ramSerialized); } else { - editor.set(0, new String(mDiskSerializer.toString(object))); + editor.set(0, diskSerializer.toString(object)); } editor.commit(); } catch (IOException e) { logger.logError(e); } finally { - getLockForGivenEntry(key).unlock(); - mInvalidationReadWriteLock.readLock().unlock(); + dualCacheLock.unLockDiskEntryWrite(key); } } } @@ -300,36 +187,34 @@ public T get(String key) { DiskLruCache.Snapshot snapshotObject = null; // Try to get the object from RAM. - boolean isRamSerialized = mRamMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER); - boolean isRamReferenced = mRamMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE); + boolean isRamSerialized = ramMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER); + boolean isRamReferenced = ramMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE); if (isRamSerialized || isRamReferenced) { - ramResult = mRamCacheLru.get(key); + ramResult = ramCacheLru.get(key); } if (ramResult == null) { // Try to get the cached object from disk. - logEntryForKeyIsNotInRam(key); - if (mDiskMode.equals(DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { + loggerHelper.logEntryForKeyIsNotInRam(key); + if (diskMode.equals(DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { try { - mInvalidationReadWriteLock.readLock().lock(); - getLockForGivenEntry(key).lock(); - snapshotObject = mDiskLruCache.get(key); + dualCacheLock.lockDiskEntryWrite(key); + snapshotObject = diskLruCache.get(key); } catch (IOException e) { logger.logError(e); } finally { - getLockForGivenEntry(key).unlock(); - mInvalidationReadWriteLock.readLock().unlock(); + dualCacheLock.unLockDiskEntryWrite(key); } if (snapshotObject != null) { - logEntryForKeyIsOnDisk(key); + loggerHelper.logEntryForKeyIsOnDisk(key); try { diskResult = snapshotObject.getString(0); } catch (IOException e) { logger.logError(e); } } else { - logEntryForKeyIsNotOnDisk(key); + loggerHelper.logEntryForKeyIsNotOnDisk(key); } } @@ -337,30 +222,28 @@ public T get(String key) { if (diskResult != null) { // Load object, no need to check disk configuration since diskresult != null. - if (objectFromStringDisk == null) { - objectFromStringDisk = mDiskSerializer.fromString(diskResult); - } + objectFromStringDisk = diskSerializer.fromString(diskResult); // Refresh object in ram. - if (mRamMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE)) { - if (mDiskMode.equals(DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { - mRamCacheLru.put(key, objectFromStringDisk); + if (ramMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE)) { + if (diskMode.equals(DualCacheDiskMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { + ramCacheLru.put(key, objectFromStringDisk); } - } else if (mRamMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { - if (mDiskSerializer == mRamSerializer) { - mRamCacheLru.put(key, diskResult); + } else if (ramMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { + if (diskSerializer == ramSerializer) { + ramCacheLru.put(key, diskResult); } else { - mRamCacheLru.put(key, mRamSerializer.toString(objectFromStringDisk)); + ramCacheLru.put(key, ramSerializer.toString(objectFromStringDisk)); } } return objectFromStringDisk; } } else { - logEntryForKeyIsInRam(key); - if (mRamMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE)) { + loggerHelper.logEntryForKeyIsInRam(key); + if (ramMode.equals(DualCacheRamMode.ENABLE_WITH_REFERENCE)) { return (T) ramResult; - } else if (mRamMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { - return mRamSerializer.fromString((String) ramResult); + } else if (ramMode.equals(DualCacheRamMode.ENABLE_WITH_SPECIFIC_SERIALIZER)) { + return ramSerializer.fromString((String) ramResult); } } @@ -368,33 +251,23 @@ public T get(String key) { return null; } - // Let concurrent modification on different keys. - private Lock getLockForGivenEntry(String key) { - if (!mEditionLocks.containsKey(key)) { - mEditionLocks.putIfAbsent(key, new ReentrantLock()); - } - return mEditionLocks.get(key); - } - /** * Delete the corresponding object in cache. * * @param key is the key of the object. */ public void delete(String key) { - if (!mRamMode.equals(DualCacheRamMode.DISABLE)) { - mRamCacheLru.remove(key); + if (!ramMode.equals(DualCacheRamMode.DISABLE)) { + ramCacheLru.remove(key); } - if (!mDiskMode.equals(DualCacheDiskMode.DISABLE)) { + if (!diskMode.equals(DualCacheDiskMode.DISABLE)) { try { - mInvalidationReadWriteLock.readLock().lock(); - getLockForGivenEntry(key).lock(); - mDiskLruCache.remove(key); + dualCacheLock.lockDiskEntryWrite(key); + diskLruCache.remove(key); } catch (IOException e) { logger.logError(e); } finally { - getLockForGivenEntry(key).unlock(); - mInvalidationReadWriteLock.readLock().unlock(); + dualCacheLock.unLockDiskEntryWrite(key); } } } @@ -411,8 +284,8 @@ public void invalidate() { * Remove all objects from RAM. */ public void invalidateRAM() { - if (!mRamMode.equals(DualCacheRamMode.DISABLE)) { - mRamCacheLru.evictAll(); + if (!ramMode.equals(DualCacheRamMode.DISABLE)) { + ramCacheLru.evictAll(); } } @@ -420,47 +293,38 @@ public void invalidateRAM() { * Remove all objects from Disk. */ public void invalidateDisk() { - if (!mDiskMode.equals(DualCacheDiskMode.DISABLE)) { + if (!diskMode.equals(DualCacheDiskMode.DISABLE)) { try { - mInvalidationReadWriteLock.writeLock().lock(); - mDiskLruCache.delete(); - mDiskLruCache = - DiskLruCache.open(mDiskCacheFolder, mAppVersion, 1, mDiskCacheSizeInBytes); + dualCacheLock.lockFullDiskWrite(); + diskLruCache.delete(); + openDiskLruCache(diskCacheFolder); } catch (IOException e) { logger.logError(e); } finally { - mInvalidationReadWriteLock.writeLock().unlock(); + dualCacheLock.unLockFullDiskWrite(); } } } /** - * Set the way objects are stored in the disk layer. - * - * @param diskMode is the value to set. + * Test if an object is present in cache. + * @param key is the key of the object. + * @return true if the object is present in cache, false otherwise. */ - public void setDiskMode(DualCacheDiskMode diskMode) { - this.mDiskMode = diskMode; - } - - // Logging helpers - private void logEntrySavedForKey(String key) { - logger.logInfo(LOG_PREFIX + key + " is saved in cache."); - } - - private void logEntryForKeyIsInRam(String key) { - logger.logInfo(LOG_PREFIX + key + " is in RAM."); - } - - private void logEntryForKeyIsNotInRam(String key) { - logger.logInfo(LOG_PREFIX + key + " is not in RAM."); - } - - private void logEntryForKeyIsOnDisk(String key) { - logger.logInfo(LOG_PREFIX + key + " is on disk."); - } - - private void logEntryForKeyIsNotOnDisk(String key) { - logger.logInfo(LOG_PREFIX + key + " is not on disk."); + public boolean contains(String key) { + if (!ramMode.equals(DualCacheRamMode.DISABLE) && ramCacheLru.snapshot().containsKey(key)) { + return true; + } + try { + dualCacheLock.lockDiskEntryWrite(key); + if (!diskMode.equals(DualCacheDiskMode.DISABLE) && diskLruCache.get(key) != null) { + return true; + } + } catch (IOException e) { + logger.logError(e); + } finally { + dualCacheLock.unLockDiskEntryWrite(key); + } + return false; } } diff --git a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheDiskMode.java b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheDiskMode.java new file mode 100644 index 0000000..344b944 --- /dev/null +++ b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheDiskMode.java @@ -0,0 +1,16 @@ +package com.vincentbrison.openlibraries.android.dualcache; + +/** + * Define the behaviour of the disk layer. + */ +public enum DualCacheDiskMode { + /** + * Means that object will be serialized with a specific serializer in disk. + */ + ENABLE_WITH_SPECIFIC_SERIALIZER, + + /** + * The disk layer is not used. + */ + DISABLE +} diff --git a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheLock.java b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheLock.java new file mode 100644 index 0000000..d397419 --- /dev/null +++ b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheLock.java @@ -0,0 +1,39 @@ +package com.vincentbrison.openlibraries.android.dualcache; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +class DualCacheLock { + + private final ConcurrentMap editionLocks = new ConcurrentHashMap<>(); + private final ReadWriteLock invalidationReadWriteLock = new ReentrantReadWriteLock(); + + void lockDiskEntryWrite(String key) { + invalidationReadWriteLock.readLock().lock(); + getLockForGivenDiskEntry(key).lock(); + } + + void unLockDiskEntryWrite(String key) { + getLockForGivenDiskEntry(key).unlock(); + invalidationReadWriteLock.readLock().unlock(); + } + + void lockFullDiskWrite() { + invalidationReadWriteLock.writeLock().lock(); + } + + void unLockFullDiskWrite() { + invalidationReadWriteLock.writeLock().unlock(); + } + + private Lock getLockForGivenDiskEntry(String key) { + if (!editionLocks.containsKey(key)) { + editionLocks.putIfAbsent(key, new ReentrantLock()); + } + return editionLocks.get(key); + } +} diff --git a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheRamMode.java b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheRamMode.java new file mode 100644 index 0000000..d04064a --- /dev/null +++ b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/DualCacheRamMode.java @@ -0,0 +1,21 @@ +package com.vincentbrison.openlibraries.android.dualcache; + +/** + * Define the behaviour of the RAM layer. + */ +public enum DualCacheRamMode { + /** + * Means that object will be serialized with a specific serializer in RAM. + */ + ENABLE_WITH_SPECIFIC_SERIALIZER, + + /** + * Means that only references to objects will be stored in the RAM layer. + */ + ENABLE_WITH_REFERENCE, + + /** + * The RAM layer is not used. + */ + DISABLE +} diff --git a/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/LoggerHelper.java b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/LoggerHelper.java new file mode 100644 index 0000000..874542d --- /dev/null +++ b/dualcache-library/src/main/java/com/vincentbrison/openlibraries/android/dualcache/LoggerHelper.java @@ -0,0 +1,32 @@ +package com.vincentbrison.openlibraries.android.dualcache; + +class LoggerHelper { + + private static final String LOG_PREFIX = "Entry for "; + + private final Logger logger; + + LoggerHelper(Logger logger) { + this.logger = logger; + } + + void logEntrySavedForKey(String key) { + logger.logInfo(LOG_PREFIX + key + " is saved in cache."); + } + + void logEntryForKeyIsInRam(String key) { + logger.logInfo(LOG_PREFIX + key + " is in RAM."); + } + + void logEntryForKeyIsNotInRam(String key) { + logger.logInfo(LOG_PREFIX + key + " is not in RAM."); + } + + void logEntryForKeyIsOnDisk(String key) { + logger.logInfo(LOG_PREFIX + key + " is on disk."); + } + + void logEntryForKeyIsNotOnDisk(String key) { + logger.logInfo(LOG_PREFIX + key + " is not on disk."); + } +} diff --git a/dualcache-serializerinterface/build.gradle b/dualcache-serializerinterface/build.gradle index 31d8fd8..59ed753 100644 --- a/dualcache-serializerinterface/build.gradle +++ b/dualcache-serializerinterface/build.gradle @@ -2,6 +2,6 @@ apply plugin: 'java' apply from: '../maven_push_java.gradle' dependencies { - sourceCompatibility = 1.7 - targetCompatibility = 1.7 + sourceCompatibility = project.javaVersion + targetCompatibility = project.javaVersion } diff --git a/gradle.properties b/gradle.properties index 2c6a2b6..9e358d9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,5 @@ -VERSION_NAME=3.0.0 +VERSION_NAME=3.1.0 +VERSION_CODE=1 GROUP=com.vincentbrison.openlibraries.android + +org.gradle.jvmargs=-Xmx1536M diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0f6475c..d8d2694 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sat May 28 13:43:26 CEST 2016 +#Sat Nov 26 21:25:44 CET 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip