|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.josql.utils.JoSQLComparator
public class JoSQLComparator
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)
but there are times when having a separate comparator is desirable.
The EXECUTE ON ALL clause is supported but you must call: doExecuteOn(List)
first to ensure that they are executed.
This class is basically just a thin wrapper around using the comparator gained by
calling: Query.getOrderByComparator()
.
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)
then took about 860ms! And if you using:
String.toLowerCase()
for each string instead, it then takes about: 1800ms!
(Meaning that in certain circumstances JoSQL can be faster!)
It is not uncommon for a Comparator (even using the effecient merge-sort implementation of
Collections.sort(List,Comparator)
) 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()
once the Comparator has been used to free up those
references (it was considered using a 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)
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 TreeMap
or 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.
Constructor Summary | |
---|---|
JoSQLComparator(Query q)
Init this file filter with the query already built and parsed. |
|
JoSQLComparator(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(Object o1,
Object o2)
Compares the objects as according to the ORDER BY clause. |
void |
doExecuteOn(List l)
Execute the EXECUTE ON ALL expressions. |
Exception |
getException()
The Comparator.compare(Object,Object) 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 QueryParseException it should
be captured. |
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(Query q)
Set a new Query object for use in this filter. |
void |
setQuery(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 |
Constructor Detail |
---|
public JoSQLComparator(String q) throws QueryParseException
q
- The query.
QueryParseException
- If there is an issue with the parsing of the query.public JoSQLComparator(Query q) throws IllegalStateException, QueryParseException
q
- The query.
IllegalStateException
- If the Query object has not been parsed.
QueryParseException
- If the FROM class is not as expected.Method Detail |
---|
public void doExecuteOn(List l) throws QueryExecutionException
l
- The list to execute the expressions on.
QueryExecutionException
public void clearCache()
public boolean isCaching() throws IllegalStateException
true
if caching is on.
IllegalStateException
- If the query has not yet been parsed or set.public void setCaching(boolean b) throws IllegalStateException
b
- Set to true
to turn caching on.
IllegalStateException
- If the query has not yet been parsed or set.public int compare(Object o1, Object o2)
compare
in interface Comparator
o1
- The first object.o2
- The second object.public Exception getException()
Comparator.compare(Object,Object)
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 QueryParseException
it should
be captured. If the exception is thrown then this method will return it.
compare(Object,Object)
or by sub-class/interface specific methods, this may be null if no exception was thrown.public void setQuery(String q) throws QueryParseException
q
- The Query to use.
QueryParseException
- If there is an issue with the parsing of the query,
or if the FROM class is not as expected.public void setQuery(Query q) throws IllegalStateException, QueryParseException
q
- The Query to use.
IllegalStateException
- If the Query object has not been parsed.
QueryParseException
- If the FROM class is not as expected.public Query getQuery()
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |