Browse Source

Added the first round of caching, added some compile time settings, modified the start scripts.

master
Drew Short 11 years ago
parent
commit
f22be07b80
  1. 16
      pom.xml
  2. 2
      src/includes/startCLI.sh
  3. 4
      src/includes/startGUI.sh
  4. 176
      src/main/java/com/sothr/imagetools/AppConfig.java
  5. 8
      src/main/resources/ehcache.xml
  6. 2
      src/main/scala/com/sothr/imagetools/dto/ImageHashDTO.scala
  7. 8
      src/test/resources/ehcache.xml
  8. 44
      src/test/scala/com/sothr/imagetools/hash/HashServiceTest.scala

16
pom.xml

@ -98,6 +98,16 @@
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>
<version>1.9</version> <version>1.9</version>
</dependency> </dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -237,6 +247,12 @@
</goals> </goals>
</execution> </execution>
</executions> </executions>
<configuration>
<jvmArgs>
<jvmArg>-Xms64m</jvmArg>
<jvmArg>-Xmx1024m</jvmArg>
</jvmArgs>
</configuration>
</plugin> </plugin>
<plugin> <plugin>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>

2
src/includes/startCLI.sh

@ -4,7 +4,7 @@ command=""
correct=false correct=false
while true; do while true; do
read -p "Please enter and commandline arguments you would like to include: " args read -p "Please enter and commandline arguments you would like to include: " args
command="-cp ${project.name}-${project.version}-jfx.jar:lib/* com.sothr.imagetools.AppCLI $args"
command="-Xmx1.5G -cp ${project.name}-${project.version}-jfx.jar:lib/* com.sothr.imagetools.AppCLI $args"
echo "Is \"$command\" accurate? (yes/no)" echo "Is \"$command\" accurate? (yes/no)"
select yn in "Yes" "No"; do select yn in "Yes" "No"; do
case $yn in case $yn in

4
src/includes/startGUI.sh

@ -0,0 +1,4 @@
#!/bin/bash
echo "Welcome to Image Tools version: ${project.version}"
command="-Xmx1.5G -jar ${project.name}-${project.version}-jfx.jar"
java $command

176
src/main/java/com/sothr/imagetools/AppConfig.java

@ -2,6 +2,7 @@ package com.sothr.imagetools;
import com.sothr.imagetools.util.PropertiesService; import com.sothr.imagetools.util.PropertiesService;
import com.sothr.imagetools.util.PropertiesEnum; import com.sothr.imagetools.util.PropertiesEnum;
import net.sf.ehcache.CacheManager;
import org.apache.log4j.PropertyConfigurator; import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.BasicConfigurator; import org.apache.log4j.BasicConfigurator;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -10,9 +11,10 @@ import org.slf4j.LoggerFactory;
import java.io.File; import java.io.File;
import java.util.Properties; import java.util.Properties;
class AppConfig {
public class AppConfig {
private static Logger logger; private static Logger logger;
public static CacheManager cacheManager;
//Logging defaults //Logging defaults
private static final String LOGSETTINGSFILE = "./log4j.properties"; private static final String LOGSETTINGSFILE = "./log4j.properties";
@ -23,99 +25,107 @@ class AppConfig {
private static final String USERPROPERTIESFILE = "./config.xml"; private static final String USERPROPERTIESFILE = "./config.xml";
private static Boolean loadedProperties = false; private static Boolean loadedProperties = false;
//Cache defaults
private static Boolean configuredCache = false;
public static void configureApp() { public static void configureApp() {
//configSimpleLogging();
if (!configuredLogging) {
BasicConfigurator.configure();
loadProperties();
BasicConfigurator.resetConfiguration();
} else {
loadProperties();
}
configLogging();
logger.info("Detected Version: %s of Image Tools".format(PropertiesService.getVersion().toString()));
//configSimpleLogging();
if (!configuredLogging) {
BasicConfigurator.configure();
loadProperties();
BasicConfigurator.resetConfiguration();
} else {
loadProperties();
}
configLogging();
configCache();
} }
public static void configSimpleLogging() {
BasicConfigurator.configure();
public static void configCache() {
if (!configuredCache) {
cacheManager = CacheManager.newInstance();
configuredCache = true;
logger.info("Configured EHCache");
}
} }
public static void configLogging(String location) { public static void configLogging(String location) {
//Logging Config
//remove previous configuration if it exists
//BasicConfigurator.resetConfiguration();
File file = new File(location);
Boolean fromFile = false;
if (file.exists()) {
fromFile = true;
PropertyConfigurator.configure(location);
} else {
//Simple error logging configuration
Properties defaultProps = new Properties();
String rootLogger = "DEBUG";
if (Boolean.valueOf(PropertiesService.get(PropertiesEnum.LogDebug().toString()))) {
//Rolling Debug logger
rootLogger += ", DL";
defaultProps.setProperty("log4j.appender.DL","org.apache.log4j.RollingFileAppender");
defaultProps.setProperty("log4j.appender.DL.Threshold","DEBUG");
defaultProps.setProperty("log4j.appender.DL.File","Image-Tools.debug");
defaultProps.setProperty("log4j.appender.DL.MaxFileSize","500KB");
defaultProps.setProperty("log4j.appender.DL.MaxBackupIndex","1");
defaultProps.setProperty("log4j.appender.DL.layout","org.apache.log4j.EnhancedPatternLayout");
defaultProps.setProperty("log4j.appender.DL.layout.ConversionPattern","%d{yy-MM-dd HH:mm:ss} %-5p [%c{3.}] - %m%n");
}
if (Boolean.valueOf(PropertiesService.get(PropertiesEnum.LogInfo().toString()))) {
//Rolling Info logger
rootLogger += ", IL";
defaultProps.setProperty("log4j.appender.IL","org.apache.log4j.RollingFileAppender");
defaultProps.setProperty("log4j.appender.IL.Threshold","INFO");
defaultProps.setProperty("log4j.appender.IL.File","Image-Tools.info");
defaultProps.setProperty("log4j.appender.IL.MaxFileSize","100KB");
defaultProps.setProperty("log4j.appender.IL.MaxBackupIndex","1");
defaultProps.setProperty("log4j.appender.IL.layout","org.apache.log4j.EnhancedPatternLayout");
defaultProps.setProperty("log4j.appender.IL.layout.ConversionPattern","%d{yy-MM-dd HH:mm:ss} %-5p [%c{3.}] - %m%n");
}
if (Boolean.valueOf(PropertiesService.get(PropertiesEnum.LogError().toString()))) {
//Rolling Error logger
rootLogger += ", EL";
defaultProps.setProperty("log4j.appender.EL","org.apache.log4j.RollingFileAppender");
defaultProps.setProperty("log4j.appender.EL.Threshold","ERROR");
defaultProps.setProperty("log4j.appender.EL.File","Image-Tools.err");
defaultProps.setProperty("log4j.appender.EL.MaxFileSize","100KB");
defaultProps.setProperty("log4j.appender.EL.MaxBackupIndex","1");
defaultProps.setProperty("log4j.appender.EL.layout","org.apache.log4j.EnhancedPatternLayout");
defaultProps.setProperty("log4j.appender.EL.layout.ConversionPattern","%d{yy-MM-dd HH:mm:ss} %-5p [%c{3.}] - %m%n");
}
defaultProps.setProperty("log4j.rootLogger",rootLogger);
PropertyConfigurator.configure(defaultProps);
}
logger = LoggerFactory.getLogger(AppConfig.class);
String message = fromFile ? "From File" : "From Defaults";
logger.info(String.format("Configured Logger %s", message));
//Logging Config
//remove previous configuration if it exists
//BasicConfigurator.resetConfiguration();
File file = new File(location);
Boolean fromFile = false;
if (file.exists()) {
fromFile = true;
PropertyConfigurator.configure(location);
} else {
//Simple error logging configuration
Properties defaultProps = new Properties();
String rootLogger = "DEBUG";
if (Boolean.valueOf(PropertiesService.get(PropertiesEnum.LogDebug().toString()))) {
//Rolling Debug logger
rootLogger += ", DL";
defaultProps.setProperty("log4j.appender.DL","org.apache.log4j.RollingFileAppender");
defaultProps.setProperty("log4j.appender.DL.Threshold","DEBUG");
defaultProps.setProperty("log4j.appender.DL.File","Image-Tools.debug");
defaultProps.setProperty("log4j.appender.DL.MaxFileSize","500KB");
defaultProps.setProperty("log4j.appender.DL.MaxBackupIndex","1");
defaultProps.setProperty("log4j.appender.DL.layout","org.apache.log4j.EnhancedPatternLayout");
defaultProps.setProperty("log4j.appender.DL.layout.ConversionPattern","%d{yy-MM-dd HH:mm:ss} %-5p [%c{3.}] - %m%n");
}
if (Boolean.valueOf(PropertiesService.get(PropertiesEnum.LogInfo().toString()))) {
//Rolling Info logger
rootLogger += ", IL";
defaultProps.setProperty("log4j.appender.IL","org.apache.log4j.RollingFileAppender");
defaultProps.setProperty("log4j.appender.IL.Threshold","INFO");
defaultProps.setProperty("log4j.appender.IL.File","Image-Tools.info");
defaultProps.setProperty("log4j.appender.IL.MaxFileSize","100KB");
defaultProps.setProperty("log4j.appender.IL.MaxBackupIndex","1");
defaultProps.setProperty("log4j.appender.IL.layout","org.apache.log4j.EnhancedPatternLayout");
defaultProps.setProperty("log4j.appender.IL.layout.ConversionPattern","%d{yy-MM-dd HH:mm:ss} %-5p [%c{3.}] - %m%n");
}
if (Boolean.valueOf(PropertiesService.get(PropertiesEnum.LogError().toString()))) {
//Rolling Error logger
rootLogger += ", EL";
defaultProps.setProperty("log4j.appender.EL","org.apache.log4j.RollingFileAppender");
defaultProps.setProperty("log4j.appender.EL.Threshold","ERROR");
defaultProps.setProperty("log4j.appender.EL.File","Image-Tools.err");
defaultProps.setProperty("log4j.appender.EL.MaxFileSize","100KB");
defaultProps.setProperty("log4j.appender.EL.MaxBackupIndex","1");
defaultProps.setProperty("log4j.appender.EL.layout","org.apache.log4j.EnhancedPatternLayout");
defaultProps.setProperty("log4j.appender.EL.layout.ConversionPattern","%d{yy-MM-dd HH:mm:ss} %-5p [%c{3.}] - %m%n");
}
defaultProps.setProperty("log4j.rootLogger",rootLogger);
PropertyConfigurator.configure(defaultProps);
} }
logger = LoggerFactory.getLogger(AppConfig.class);
String message = fromFile ? "From File" : "From Defaults";
logger.info(String.format("Configured Logger %s", message));
logger.info("Detected Version: %s of Image Tools".format(PropertiesService.getVersion().toString()));
}
//Only configure logging from the default file once
public static void configLogging() {
if (!configuredLogging) {
configLogging(LOGSETTINGSFILE);
configuredLogging = true;
}
//Only configure logging from the default file once
public static void configLogging() {
if (!configuredLogging) {
configLogging(LOGSETTINGSFILE);
configuredLogging = true;
} }
}
public static void loadProperties() {
if (!loadedProperties) {
File file = new File(USERPROPERTIESFILE);
if (file.exists()) {
PropertiesService.loadProperties(DEFAULTPROPERTIESFILE, USERPROPERTIESFILE);
} else {
PropertiesService.loadProperties(DEFAULTPROPERTIESFILE, null);
}
loadedProperties = true;
}
public static void loadProperties() {
if (!loadedProperties) {
File file = new File(USERPROPERTIESFILE);
if (file.exists()) {
PropertiesService.loadProperties(DEFAULTPROPERTIESFILE, USERPROPERTIESFILE);
} else {
PropertiesService.loadProperties(DEFAULTPROPERTIESFILE, null);
}
loadedProperties = true;
} }
}
public static void saveProperties() {
PropertiesService.saveXMLProperties(USERPROPERTIESFILE);
}
public static void saveProperties() {
PropertiesService.saveXMLProperties(USERPROPERTIESFILE);
}
} }

8
src/main/resources/ehcache.xml

@ -0,0 +1,8 @@
<ehcache maxBytesLocalHeap="512M" maxBytesLocalDisk="5g" >
<cache name="images"
timeToLiveSeconds="100">
</cache>
<cache name="thumbnails"
timeToLiveSeconds="100">
</cache>
</ehcache>

2
src/main/scala/com/sothr/imagetools/dto/ImageHashDTO.scala

@ -2,7 +2,7 @@ package com.sothr.imagetools.dto
import grizzled.slf4j.Logging import grizzled.slf4j.Logging
class ImageHashDTO(val ahash:Long, val dhash:Long, val phash:Long, val md5:String) extends Logging {
class ImageHashDTO(val ahash:Long, val dhash:Long, val phash:Long, val md5:String) extends Serializable with Logging{
override def hashCode():Int = { override def hashCode():Int = {
var result = 365 var result = 365

8
src/test/resources/ehcache.xml

@ -0,0 +1,8 @@
<ehcache maxBytesLocalHeap="512M" maxBytesLocalDisk="5g" >
<cache name="images"
timeToLiveSeconds="100">
</cache>
<cache name="thumbnails"
timeToLiveSeconds="100">
</cache>
</ehcache>

44
src/test/scala/com/sothr/imagetools/hash/HashServiceTest.scala

@ -1,9 +1,10 @@
package com.sothr.imagetools.hash package com.sothr.imagetools.hash
import com.sothr.imagetools.{BaseTest, TestParams}
import com.sothr.imagetools.{AppConfig, BaseTest, TestParams}
import javax.imageio.ImageIO import javax.imageio.ImageIO
import java.io.File import java.io.File
import com.sothr.imagetools.dto.ImageHashDTO import com.sothr.imagetools.dto.ImageHashDTO
import net.sf.ehcache.{Cache, Element}
/** /**
* Created by dev on 1/23/14. * Created by dev on 1/23/14.
@ -310,10 +311,51 @@ class HashServiceTest extends BaseTest {
assert(hash == "b137131bd55896c747286e4d247b845e") assert(hash == "b137131bd55896c747286e4d247b845e")
} }
def imageHashTestWithCacheCase(filePath:String):ImageHashDTO = {
val cache = AppConfig.cacheManager.getCache("images")
var result:ImageHashDTO = null
if (cache.get(filePath) != null) {
result = cache.get(filePath).getObjectValue.asInstanceOf[ImageHashDTO]
} else {
result = imageHashTestCase(filePath)
cache.put(new Element(filePath,result))
}
result
}
def imageHashTestCase(filePath:String):ImageHashDTO = { def imageHashTestCase(filePath:String):ImageHashDTO = {
HashService.getImageHashes(filePath) HashService.getImageHashes(filePath)
} }
test("Benchmark getImageHashes with cache") {
info("Benchmarking getImageHashes with cache")
info("getImageHashes Large Image 3684x2736")
val largeTime1 = getTime { imageHashTestWithCacheCase(TestParams.LargeSampleImage1) }
val largeTime2 = getTime { imageHashTestWithCacheCase(TestParams.LargeSampleImage1) }
val largeTime3 = getTime { imageHashTestWithCacheCase(TestParams.LargeSampleImage1) }
val largeTime4 = getTime { imageHashTestWithCacheCase(TestParams.LargeSampleImage1) }
val largeTime5 = getTime { imageHashTestWithCacheCase(TestParams.LargeSampleImage1) }
val largeMean = getMean(largeTime1, largeTime2, largeTime3, largeTime4, largeTime5)
info(s"The mean time of 5 tests for large was: $largeMean ms")
info("getImageHashes Medium Image 1824x1368")
val mediumTime1 = getTime { imageHashTestWithCacheCase(TestParams.MediumSampleImage1) }
val mediumTime2 = getTime { imageHashTestWithCacheCase(TestParams.MediumSampleImage1) }
val mediumTime3 = getTime { imageHashTestWithCacheCase(TestParams.MediumSampleImage1) }
val mediumTime4 = getTime { imageHashTestWithCacheCase(TestParams.MediumSampleImage1) }
val mediumTime5 = getTime { imageHashTestWithCacheCase(TestParams.MediumSampleImage1) }
val mediumMean = getMean(mediumTime1, mediumTime2, mediumTime3, mediumTime4, mediumTime5)
info(s"The mean time of 5 tests for medium was: $mediumMean ms")
info("getImageHashes Small Image 912x684")
val smallTime1 = getTime { imageHashTestWithCacheCase(TestParams.SmallSampleImage1) }
val smallTime2 = getTime { imageHashTestWithCacheCase(TestParams.SmallSampleImage1) }
val smallTime3 = getTime { imageHashTestWithCacheCase(TestParams.SmallSampleImage1) }
val smallTime4 = getTime { imageHashTestWithCacheCase(TestParams.SmallSampleImage1) }
val smallTime5 = getTime { imageHashTestWithCacheCase(TestParams.SmallSampleImage1) }
val smallMean = getMean(smallTime1, smallTime2, smallTime3, smallTime4, smallTime5)
info(s"The mean time of 5 tests for small was: $smallMean ms")
assert(true)
}
test("Benchmark getImageHashes") { test("Benchmark getImageHashes") {
info("Benchmarking getImageHashes") info("Benchmarking getImageHashes")
info("getImageHashes Large Image 3684x2736") info("getImageHashes Large Image 3684x2736")

Loading…
Cancel
Save