Archive for November, 2006

A Simple LRU Cache in 5 lines

The applications usually need to cache information in memory. The most often used classes to do this in Java are HashMap and Hashtable. If you need to do any sophisticated caching, then you can use JBoss Cache, OSCache or EHCache. Even if you use an external caching system, you may still want to cache some information locally within an object just to have fast access. The problem with this approach is that, if you are not careful and do not control the size of this in-memory cache, then it may grow too big and affect the performance of your application.

A very simple solution to this problem is to set a maximum size for your in-memory cache and most preferably make it LRU (Least Recently Used). This way you will have a predictable memory utilization and only the items used recently will be kept in the cache.

Starting with JDK 1.4, a new (and very rarely used) collection class was added called LinkedHashMap. There are couple of benefits of using a LinkedHashMap:

  • It is possible to preserve the order of items in the map. So, the order of iteration through the items is same as the order of insertion. A special constructor is provided for this purpose. This is very useful when you already have a sorted collection of data and you want to do some processing on it and return it as a Map. Using a TreeMap (the only other map that allows iteration in a given order) is too expensive for this scenario.
  • It exposes a method removeEldestEntry(Map.Entry) that may be overridden to impose a policy for removing stale mappings automatically when new mappings are added to the map. This is what we are going to use to create a LRU cache.

Check out the following snippet for an example of simple LRU cache.


This code creates a simple LRU cache with maximum 50 entries. The magic happens during the creation of the LinkedHashMap where a boolean flag for access order is set to true and the method removeEldestEntry is overridden. Now, if you run the program, you can see that the cache size is fixed to 50 entries and the least recently used entries are removed from the map. It is possible to create a pruning thread to prune the map so you don’t always necessarily maintain the maximum number of entries.

Share and Enjoy:
  • Digg
  • del.icio.us
  • description
  • Technorati
  • Reddit
  • Facebook
  • blogmarks
  • YahooMyWeb
  • Ma.gnolia

Comments (15)

PMD bug with @SuppressWarnings annotation

PMD is an open source static analysis tool for the Java source code. It has a pretty good set of standard rules and you can add new rules by using XPath or Java code against the AST (Abstract Syntax Tree) it generates from the source code. The code analysis tools help you to keep your code clean and simple and avoid common pitfalls.

I recently found a bug while trying to analyze the code in the JDK 1.5 mode using PMD 3.8 version. The PMD seems to be ignoring all the violations for the class/method if you have a @SuppressWarnings annotation in it. According to the PMD documentation, only if you have @SuppressWarnings("") in your code, it’s supposed to ignore the violations for that class/method. But, the source code for PMD does not implement this logic. It just checks for the presence of @SuppressWarnings annotation and not any values passed to it. The end result is that all the violations are ignored. This can be very annoying as you may miss a significant number of violations.

To fix this issue, I made a couple of changes to the PMD source code. These are listed below with explanations:

  • net.sourceforge.pmd.ast.ASTAnnotation - This is the class where the check for @SuppressWarnings is implemented. I made changes to the suppresses(Rule rule) method of this class to check if any values are passed to this annotation. If any values except "" are passed (e.g. @SuppressWarnings("unchecked")), then all the PMD violations are written to the report. Otherwise if "" is passed, all the PMD violations are suppressed.

    
    

  • net.sourceforge.pmd.renderers.XMLRenderer - You need to change this only if you generate your PMD reports in the XML format. The changes I made here are to improve the information presented for suppressed violations tag (<suppressedviolation>). So, if you decide to use the @SuppressWarnings("") annotation, at the end of reports their will be a section for suppressed violations. Another change I made is to enclose all the <suppressedviolation> tags inside a <file> tag for each file just like regular violations.

    
    

  • net.sourceforge.pmd.util.StringUtil - This was throwing NullPointerException for the suppressed violations while generating the report. I just added a null check here.

You can just replace the whole methods for ASTAnnotation and XMLRenderer classes and add the code snippet for StringUtil class. Once you do that you are ready to do the build. Run following in the bin directory of pmd-3.8 or the directory where you extracted the source code:

ant dist

That should create the pmd-3.8.jar in the lib directory. Now, you can use this jar whether you use the command line, ant or eclipse plugin to run PMD. If you have any questions, please leave me a comment.

Share and Enjoy:
  • Digg
  • del.icio.us
  • description
  • Technorati
  • Reddit
  • Facebook
  • blogmarks
  • YahooMyWeb
  • Ma.gnolia

Comments

Charts in Ruby - Using Gruff

It is very common requirement for any reporting application to be able to draw charts based on some historical and statistical data. The languages with big user community like Java have various libraries available for creating charts. But when it comes to Ruby, there are not as many or as sophisticated choices. I was looking for a library in Ruby to do this sometime back and I found Gruff. It’s a very simple and efficient library.

To install Gruff, all you need to do is:

gem install gruff

You also need to have the RMagick installed that needs the ImageMagick to be installed. You can install ImageMagick using the package manager of your Linux distribution or download it directly from ImageMagick website and install. The RMagick installation can be done by either using gem or using the native OS package manager. On my Mandriva Linux box, the gem installation kept on failing during compilation. So, I just installed it using urpmi and it worked.
I wrote a small module in Ruby to draw the line charts. This module can be included in the scripts where you need to draw the charts. This module is called charts.rb. Here is the source code for it:

The arguments for drawChart function are as follows:

  1. Title of the chart
  2. A Hash of the data (the Caption for data => Array of data)
  3. A Hash of labels for the X axis
  4. Path of the final generated image
  5. The scale of the image from the original chart size of 700px*700px
  6. An array of hex colors if you do not want to use Gruff’s default color scheme

Now, here is how you can use the chart module and the drawChart function:

That’s pretty much all the code. In the end you should have a chart generated like following:
A chart generated by Gruff

Share and Enjoy:
  • Digg
  • del.icio.us
  • description
  • Technorati
  • Reddit
  • Facebook
  • blogmarks
  • YahooMyWeb
  • Ma.gnolia

Comments (6)