Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

org.josql.utils
Class JoSQLComparator  view JoSQLComparator download JoSQLComparator.java

java.lang.Object
  extended byorg.josql.utils.JoSQLComparator
All Implemented Interfaces:
java.util.Comparator

public class JoSQLComparator
extends java.lang.Object
implements java.util.Comparator

This class allows the ORDER BY clause of a JoSQL SQL clause to be used as a Comparator. It should be noted that is the same as performing: Query.execute(List)>Query.execute(List) 55 but there are times when having a separate comparator is desirable. The EXECUTE ON ALL clause is supported but you must call: doExecuteOn(List) 55 first to ensure that they are executed.

This class is basically just a thin wrapper around using the comparator gained by calling: Query.getOrderByComparator()>Query.getOrderByComparator() 55 .

A note on performance, for small numbers of objects (around 1000) this comparator has (for vanilla accessors, no function calls) pretty comparable performance against a hand-coded Java Comparator that performs the same function. However start to scale the numbers of objects and performance degrades, in testing for ~34000 FileWrapper objects to order by: path DESC, lastModified, name, length took around: 1300ms. The hand-coded Java Comparator took around: 180ms! The upshot is, if you need flexibility and do not need to order large numbers of objects then use this kind of Comparator, if performance and numbers of objects is an issue then hand-rolling your own Comparator is probably best. As a side-note, to perform the following order by: lower(path) DESC, lastModified, name, length using a JoSQLComparator took: about: 1400ms. However modifying the hand-coded Comparator to use: String.compareToIgnoreCase(String)>String.compareToIgnoreCase(String) 55 then took about 860ms! And if you using: String.toLowerCase()>String.toLowerCase() 55 for each string instead, it then takes about: 1800ms! (Meaning that in certain circumstances JoSQL can be faster!)

Caching

It is not uncommon for a Comparator (even using the effecient merge-sort implementation of Collections.sort(List,Comparator)>Collections.sort(List,Comparator) 55 ) to perform thousands (even millions!) of comparisons.

However since JoSQL does not automatically cache the results of calls to functions and results of accessor accesses the performance of this kind of "dynamic" Comparator can quickly degrade. To mitigate this it is possible to turn "caching" on whereby the Comparator will "remember" the results of the functions on a per object basis and use those values instead of calling them again. This is not without it's downside however. Firstly since a reference to the object will be held it is important (if caching is used that you call: clearCache() 55 once the Comparator has been used to free up those references (it was considered using a java.util.WeakHashMap but that doesn't provide exactly what's needed here).

It is recommended that caching is turned on when the Comparator is to be used in a sort operation , i.e. calling: Collections.sort(List,Comparator)>Collections.sort(List,Comparator) 55 or similar (however careful consideration needs to be given to the amount of memory that this may consume, i.e. 4 bytes = 1 object reference, plus 1 List, plus 4 bytes per order by "column" it soon adds up)

If the comparator is to be used in a java.util.TreeMap or java.util.TreeSet then caching should not be used since the values may (and perhaps should) change over time but due to caching the order won't change.

Last Modified By: $Author: barrygently $
Last Modified On: $Date: 2005/01/20 15:27:25 $
Current Revision: $Revision: 1.1 $


Field Summary
private  org.josql.internal.ListExpressionComparator c
           
private  java.lang.Exception exp
           
private  org.josql.Query q
           
 
Constructor Summary
JoSQLComparator(org.josql.Query q)
          Init this file filter with the query already built and parsed.
JoSQLComparator(java.lang.String q)
          Init this filter with the query.
 
Method Summary
 void clearCache()
          Clear the cache, it is VITAL that you call this method before you use the comparator (if it has been used before) otherwise data objects will be "left around" and preventing the GC from cleaning them up.
 int compare(java.lang.Object o1, java.lang.Object o2)
          Compares the objects as according to the ORDER BY clause.
 void doExecuteOn(java.util.List l)
          Execute the EXECUTE ON ALL expressions.
 java.lang.Exception getException()
          The Comparator.compare(Object,Object)>Comparator.compare(Object,Object) 55 method does not allow for any exceptions to be thrown however since the execution of the ORDER BY clause on the objects can cause the throwing of a org.josql.QueryParseException it should be captured.
 org.josql.Query getQuery()
          Get the Query we are using to process objects.
 boolean isCaching()
          Return whether this comparator uses caching to improve performance.
 void setCaching(boolean b)
          Set whether the comparator should use caching to improve performance.
 void setQuery(org.josql.Query q)
          Set a new Query object for use in this filter.
 void setQuery(java.lang.String q)
          Set a new Query (string form) for use in this filter.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 
Methods inherited from interface java.util.Comparator
equals
 

Field Detail

q

private org.josql.Query q

exp

private java.lang.Exception exp

c

private org.josql.internal.ListExpressionComparator c
Constructor Detail

JoSQLComparator

public JoSQLComparator(java.lang.String q)
                throws org.josql.QueryParseException
Init this filter with the query.


JoSQLComparator

public JoSQLComparator(org.josql.Query q)
                throws java.lang.IllegalStateException,
                       org.josql.QueryParseException
Init this file filter with the query already built and parsed.

Method Detail

doExecuteOn

public void doExecuteOn(java.util.List l)
                 throws org.josql.QueryExecutionException
Execute the EXECUTE ON ALL expressions.


clearCache

public void clearCache()
Clear the cache, it is VITAL that you call this method before you use the comparator (if it has been used before) otherwise data objects will be "left around" and preventing the GC from cleaning them up.


isCaching

public boolean isCaching()
                  throws java.lang.IllegalStateException
Return whether this comparator uses caching to improve performance.


setCaching

public void setCaching(boolean b)
                throws java.lang.IllegalStateException
Set whether the comparator should use caching to improve performance.


compare

public int compare(java.lang.Object o1,
                   java.lang.Object o2)
Compares the objects as according to the ORDER BY clause.

Specified by:
compare in interface java.util.Comparator

getException

public java.lang.Exception getException()
The Comparator.compare(Object,Object)>Comparator.compare(Object,Object) 55 method does not allow for any exceptions to be thrown however since the execution of the ORDER BY clause on the objects can cause the throwing of a org.josql.QueryParseException it should be captured. If the exception is thrown then this method will return it.


setQuery

public void setQuery(java.lang.String q)
              throws org.josql.QueryParseException
Set a new Query (string form) for use in this filter.


setQuery

public void setQuery(org.josql.Query q)
              throws java.lang.IllegalStateException,
                     org.josql.QueryParseException
Set a new Query object for use in this filter.


getQuery

public org.josql.Query getQuery()
Get the Query we are using to process objects.