diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/DecisionTree.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/DecisionTree.java index 1e5bf9ea1c..61335e0b9a 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/DecisionTree.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/DecisionTree.java @@ -28,6 +28,8 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; import com.raytheon.uf.common.dataquery.requests.RequestConstraint; import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintType; @@ -43,12 +45,15 @@ import com.raytheon.uf.common.dataquery.requests.RequestConstraint.ConstraintTyp * *
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jul 3, 2007             chammack    Initial Creation.
- * Jan 14, 2013 1442       rferrel     Added method searchTreeUsingContraints.
- *                                     Addition checks on constraints.
- * May 28, 2013 1638       mschenke    Added proper support for {@link ConstraintType#ISNULL}
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- -----------------------------------------
+ * Jul 03, 2007           chammack    Initial Creation.
+ * Jan 14, 2013  1442     rferrel     Added method searchTreeUsingContraints.
+ *                                    Addition checks on constraints.
+ * May 28, 2013  1638     mschenke    Added proper support for
+ *                                    {@link ConstraintType#ISNULL}
+ * Dec 18, 2013  2579     bsteffen    Replace synchronization with a
+ *                                    read/write lock.
  * 
  * 
* @@ -94,9 +99,7 @@ public class DecisionTree { if (lvl == 0) { // heuristic: Always start with pluginName entropyPair = new EntropyPair[1]; - entropyPair[0] = new EntropyPair(); - entropyPair[0].attribute = "pluginName"; - entropyPair[0].entropy = 1.0f; + entropyPair[0] = new EntropyPair("pluginName", 1.0f); } else { for (String attrib : localAttribList) { // For an attribute, pull out the possible values @@ -133,9 +136,8 @@ public class DecisionTree { Iterator attributeListIter = localAttribList.iterator(); for (int i = 0; attributeListIter.hasNext(); i++) { - entropyPair[i] = new EntropyPair(); - entropyPair[i].attribute = attributeListIter.next(); - entropyPair[i].entropy = entropyValues.get(i); + entropyPair[i] = new EntropyPair(attributeListIter.next(), + entropyValues.get(i)); } Arrays.sort(entropyPair); @@ -225,22 +227,25 @@ public class DecisionTree { } protected class DataPair { - public Map metadata; + public final Map metadata; + + public final T data; + + public DataPair(Map metadata, T data) { + this.metadata = metadata; + this.data = data; + } - public T data; } + private final ReadWriteLock lock = new ReentrantReadWriteLock(); + private final List dataPairs; - private final Set attributes; - private Node head; - private int size = 0; - public DecisionTree() { dataPairs = new ArrayList(); - attributes = new HashSet(); } public void insertCriteria(Map searchCriteria, @@ -249,25 +254,22 @@ public class DecisionTree { throw new IllegalArgumentException( "Search criteria must not be null"); - // Check for the case that the item is already listed - DataPair e = new DataPair(); - e.data = item; - e.metadata = searchCriteria; - this.dataPairs.add(e); - size++; + DataPair e = new DataPair(searchCriteria, item); - Set keys = searchCriteria.keySet(); - - this.attributes.addAll(keys); - - if (rebuild) { - // Now, trigger a tree rebuild - rebuildTree(); + lock.writeLock().lock(); + try { + this.dataPairs.add(e); + if (rebuild) { + rebuildTree(); + } + } finally { + lock.writeLock().unlock(); } } public void rebuildTree() { - synchronized (this) { + lock.writeLock().lock(); + try { if (this.dataPairs.size() == 0) { this.head = null; return; @@ -275,6 +277,8 @@ public class DecisionTree { this.head = new Node(); this.head.rebuildTree(dataPairs, new ArrayList(), 0); + } finally { + lock.writeLock().unlock(); } } @@ -318,7 +322,8 @@ public class DecisionTree { */ private List searchTree(Map searchCriteria, boolean evaluateConstraints) { - synchronized (this) { + lock.readLock().lock(); + try { List lst = new ArrayList(); if (head == null) { return lst; @@ -328,6 +333,8 @@ public class DecisionTree { searchTree(curNode, searchCriteria, lst, 0, evaluateConstraints); return lst; + } finally { + lock.readLock().unlock(); } } @@ -391,8 +398,10 @@ public class DecisionTree { * @param item */ public void remove(T item) { - boolean itemRemoved = false; - synchronized (this) { + lock.writeLock().lock(); + try { + boolean itemRemoved = false; + // This could be optimized but removes are a very uncommon operation Iterator exampleIterator = dataPairs.iterator(); while (exampleIterator.hasNext()) { @@ -404,39 +413,26 @@ public class DecisionTree { itemRemoved = true; } } - } - if (itemRemoved) { - rebuildTree(); - } - } - - public void traverse() { - System.out.println("Head:"); - traverse(head); - - } - - public void traverse(Node n) { - if (n == null) - return; - System.out.println(n.type); - if (n.type == NodeType.LEAF) { - System.out.println(n.values); - } else if (n.type == NodeType.DECISION) { - System.out.println(n.decision); - } - System.out.println(n.decisionAttribute); - System.out.println("-------"); - - for (int i = 0; i < n.nodeChildren.size(); i++) { - System.out.println("Child of: " + n.decisionAttribute + " " + i); - Node n2 = n.nodeChildren.get(i); - traverse(n2); + if (itemRemoved) { + rebuildTree(); + } + } finally { + lock.writeLock().unlock(); } } protected List getDataPairs() { - return new ArrayList.DataPair>(dataPairs); + /* + * Copy dataPairs to avoid external iterators getting concurrent + * modification. Must get read lock because copying iterates over + * dataPairs. + */ + lock.readLock().lock(); + try { + return new ArrayList(dataPairs); + } finally { + lock.readLock().unlock(); + } } private static double calcEntropy(int numExamples, Integer[] values) { @@ -451,9 +447,14 @@ public class DecisionTree { } private static class EntropyPair implements Comparable { - public String attribute; + public final String attribute; - public double entropy; + public final double entropy; + + public EntropyPair(String attribute, double entropy) { + this.attribute = attribute; + this.entropy = entropy; + } /* * (non-Javadoc) diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResult.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResult.java index f3316f174d..b491bc7709 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResult.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResult.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; -import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -35,16 +34,18 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * *
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 11/07/08     #1673      bphillip    Initial Creation
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Nov 07, 2008  1673     bphillip    Initial Creation
+ * Dec 18, 2013  2579     bsteffen    Remove ISerializableObject
+ * 
  * 
* * @author bphillip * @version 1.0 */ @DynamicSerialize -public class QueryResult implements ISerializableObject { +public class QueryResult { /** A mapping of the column names to their index in the result */ @DynamicSerializeElement @@ -167,12 +168,10 @@ public class QueryResult implements ISerializableObject { */ public String[] getColumnNameArray() { String[] names = new String[columnNames.size()]; - int i = 0; for (Iterator it = columnNames.keySet().iterator(); it .hasNext();) { String key = it.next(); names[columnNames.get(key)] = key; - i++; } return names; } diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResultRow.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResultRow.java index df3b23c650..dadb348d90 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResultRow.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/db/QueryResultRow.java @@ -22,7 +22,6 @@ package com.raytheon.uf.common.dataquery.db; import java.util.Arrays; -import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -31,16 +30,18 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * *
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * 11/07/08     #1673      bphillip    Initial Creation
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Nov 07, 2008  1673     bphillip    Initial Creation
+ * Dec 18, 2013  2579     bsteffen    Remove ISerializableObject
+ * 
  * 
* * @author bphillip * @version 1.0 */ @DynamicSerialize -public class QueryResultRow implements ISerializableObject { +public class QueryResultRow { /** * The values of the returned columns diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/DbQueryRequestSet.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/DbQueryRequestSet.java index 517d84dda3..d9c50dde79 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/DbQueryRequestSet.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/DbQueryRequestSet.java @@ -24,20 +24,24 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.raytheon.uf.common.serialization.comm.IServerRequest; /** - * TODO Add Description + * Send multiple {@link DbQueryRequestSet}s at once. This can be more efficient + * than sending multiple requests individually because it reduces the network + * overhead. * *
  * 
  * SOFTWARE HISTORY
  * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jun 30, 2011            rjpeter     Initial creation
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Jun 30, 2011           rjpeter     Initial creation
+ * Dec 18, 2013  2579     bsteffen    Class javadoc
  * 
  * 
* * @author rjpeter * @version 1.0 + * @see DbQueryRequest */ @DynamicSerialize public class DbQueryRequestSet implements IServerRequest { diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/QlServerRequest.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/QlServerRequest.java index 701dc92882..464044a9c9 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/QlServerRequest.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/QlServerRequest.java @@ -21,7 +21,6 @@ package com.raytheon.uf.common.dataquery.requests; import java.util.Map; -import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.raytheon.uf.common.serialization.comm.IServerRequest; @@ -32,9 +31,10 @@ import com.raytheon.uf.common.serialization.comm.IServerRequest; *
  * 
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Feb 16, 2011 #8070      ekladstrup  Initial creation
+ * Date          Ticket#    Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Feb 16, 2011  8070     ekladstrup  Initial creation
+ * Dec 18, 2013  2579     bsteffen    Remove ISerializableObject
  * 
  * 
* @@ -42,7 +42,7 @@ import com.raytheon.uf.common.serialization.comm.IServerRequest; * @version 1.0 */ @DynamicSerialize -public class QlServerRequest implements IServerRequest, ISerializableObject { +public class QlServerRequest implements IServerRequest { @DynamicSerializeElement private Map rcMap; diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/RequestConstraint.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/RequestConstraint.java index 76fd4605bd..c1fd146734 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/RequestConstraint.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/RequestConstraint.java @@ -40,29 +40,31 @@ import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; -import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.raytheon.uf.common.time.util.TimeUtil; /** - * RequestConstraint - Constraints on a uEngine request - * - * Allows non-equals style constraints + * Used in requests to limit the type of data returned. Similar to an sql WHERE + * clause, it consists of a type(operator) and a value. When a request is made + * fields will be compared to the constraint value with the specified type to + * determine what data to return. * *
  * 
- *    SOFTWARE HISTORY
+ * SOFTWARE HISTORY
  *   
- *    Date         Ticket#     Engineer    Description
- *    ------------ ----------  ----------- --------------------------
- *    Aug 21, 2007             chammack    Initial Creation.
- *    May 27, 2009 2408        jsanchez    Cast value to String.
- *    Sep 28, 2009 3099        bsteffen    Fixed constraintCompare to convert
- *                                         all non-numeric objects to String
- *    Nov 05, 2009 3553        rjpeter     Added isNull capability.
- *    Jul 09, 2013 1869        bsteffen    Format Calendar when making
- *                                         Constraint Mapping.
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- -----------------------------------------
+ * Aug 21, 2007           chammack    Initial Creation.
+ * May 27, 2009  2408     jsanchez    Cast value to String.
+ * Sep 28, 2009  3099     bsteffen    Fixed constraintCompare to convert all
+ *                                    non-numeric objects to String
+ * Nov 05, 2009  3553     rjpeter     Added isNull capability.
+ * Jul 09, 2013  1869     bsteffen    Format Calendar when making Constraint
+ *                                    Mapping.
+ * Dec 18, 2013  2579     bsteffen    Remove ISerializableObject
+ * 
  * 
  * 
* @@ -73,7 +75,7 @@ import com.raytheon.uf.common.time.util.TimeUtil; @XmlRootElement(name = "requestConstraint") @XmlType(name = "requestConstraint") @DynamicSerialize -public class RequestConstraint implements ISerializableObject, Cloneable { +public class RequestConstraint implements Cloneable { public static final RequestConstraint WILDCARD; static { @@ -114,7 +116,8 @@ public class RequestConstraint implements ISerializableObject, Cloneable { @DynamicSerializeElement protected String constraintValue; - protected transient Map, Object> asMap = new HashMap, Object>(); + protected transient Map, Object> asMap = new HashMap, Object>( + 2); /** * Constructor diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/TimeQueryRequestSet.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/TimeQueryRequestSet.java index f1f3f097b5..49aba3a8be 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/TimeQueryRequestSet.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/requests/TimeQueryRequestSet.java @@ -24,20 +24,25 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; import com.raytheon.uf.common.serialization.comm.IServerRequest; /** - * TODO Add Description + * Send multiple {@link TimeQueryRequest}s at once. This can be more efficient + * than sending multiple requests individually because it reduces the network + * overhead. The response will be a List> where the list contains + * one entry for each request, in the same order as the requests. * *
  * 
  * SOFTWARE HISTORY
  * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jul 1, 2011            rjpeter     Initial creation
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Jul0 1, 2011           rjpeter     Initial creation
+ * Dec 18, 2013  2579     bsteffen    Class javadoc
  * 
  * 
* * @author rjpeter * @version 1.0 + * @see TimeQueryRequest */ @DynamicSerialize public class TimeQueryRequestSet implements IServerRequest { diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java index 8ccf58cdd5..14762e63c2 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponse.java @@ -24,7 +24,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import com.raytheon.uf.common.serialization.ISerializableObject; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; @@ -37,9 +36,10 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; *
  * 
  * SOFTWARE HISTORY
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jan 21, 2010            mschenke     Initial creation
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Jan 21, 2010           mschenke    Initial creation
+ * Dec 18, 2013  2579     bsteffen    Remove ISerializableObject
  * 
  * 
* @@ -47,7 +47,7 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; * @version 1.0 */ @DynamicSerialize -public class DbQueryResponse implements ISerializableObject { +public class DbQueryResponse { public static final String ENTITY_RESULT_KEY = null; diff --git a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponseSet.java b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponseSet.java index 82c1c7bbeb..1e7b421475 100644 --- a/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponseSet.java +++ b/edexOsgi/com.raytheon.uf.common.dataquery/src/com/raytheon/uf/common/dataquery/responses/DbQueryResponseSet.java @@ -19,28 +19,32 @@ **/ package com.raytheon.uf.common.dataquery.responses; -import com.raytheon.uf.common.serialization.ISerializableObject; +import com.raytheon.uf.common.dataquery.requests.DbQueryRequestSet; import com.raytheon.uf.common.serialization.annotations.DynamicSerialize; import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement; /** - * TODO Add Description + * Response to a {@link DbQueryResponseSet}, contains a response to every + * request in the same order. * *
  * 
  * SOFTWARE HISTORY
  * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * Jul 1, 2011            rjpeter     Initial creation
+ * Date          Ticket#  Engineer    Description
+ * ------------- -------- ----------- --------------------------
+ * Jul 01, 2011           rjpeter     Initial creation
+ * Dec 18, 2013  2579     bsteffen    Remove ISerializableObject
  * 
  * 
* * @author rjpeter * @version 1.0 + * @see DbQueryResponse + * @see DbQueryRequestSet */ @DynamicSerialize -public class DbQueryResponseSet implements ISerializableObject { +public class DbQueryResponseSet { @DynamicSerializeElement private DbQueryResponse[] results;