You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pp...@apache.org on 2012/01/18 00:37:40 UTC
svn commit: r1232650 -
/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
Author: ppoddar
Date: Tue Jan 17 23:37:39 2012
New Revision: 1232650
URL: http://svn.apache.org/viewvc?rev=1232650&view=rev
Log:
OPENJPA-2111: Optimize lookup when possible
Modified:
openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java?rev=1232650&r1=1232649&r2=1232650&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java (original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java Tue Jan 17 23:37:39 2012
@@ -2330,8 +2330,7 @@ public class SelectImpl
extends ResultSetResult
implements PathJoins {
- private SelectImpl _sel = null;
- private Map<Column, Object> _cachedColumnAlias = null;
+ private SelectImpl _sel;
// position in selected columns list where we expect the next load
private int _pos = 0;
@@ -2414,14 +2413,12 @@ public class SelectImpl
protected boolean containsInternal(Object obj, Joins joins) {
// we key directly on objs and join-less cols, or on the alias
// for cols with joins
+ if (_sel._selects.isOptimizable()) {
+ return obj instanceof Column && _sel._selects.getObjectIndex((Column)obj) != null;
+ }
PathJoins pj = getJoins(joins);
if (pj != null && pj.path() != null) {
Object columnAlias = getColumnAlias((Column) obj, pj);
- if (joins == null) {
- if (_cachedColumnAlias == null)
- _cachedColumnAlias = new HashMap<Column, Object>();
- _cachedColumnAlias.put((Column) obj, columnAlias);
- }
return columnAlias != null && _sel._selects.contains(columnAlias);
}
return obj != null && _sel._selects.contains(obj);
@@ -2460,8 +2457,16 @@ public class SelectImpl
return super.nextInternal();
}
+
+ /**
+ * Finds index of the given object with optional join information.
+ * The index refers to the position of the value in the JDBC result set.
+ */
protected int findObject(Object obj, Joins joins)
throws SQLException {
+ if (_sel._selects.isOptimizable()) {
+ return _sel._selects.getObjectIndex((Column)obj);
+ }
if (_pos == _sel._selects.size())
_pos = 0;
@@ -2472,21 +2477,16 @@ public class SelectImpl
if (pj != null && pj.path() != null) {
Column col = (Column) obj;
pk = (col.isPrimaryKey()) ? Boolean.TRUE : Boolean.FALSE;
- if (joins == null && _cachedColumnAlias != null) {
- obj = _cachedColumnAlias.get(col);
- if (obj == null)
- obj = getColumnAlias(col, pj);
- } else {
- obj = getColumnAlias(col, pj);
- }
+ obj = getColumnAlias(col, pj);
if (obj == null)
throw new SQLException(col.getTable() + ": "
+ pj.path() + " (" + _sel._aliases + ")");
}
// we load in the same order we select, more or less...
- if (_sel._selects.get(_pos).equals(obj))
+ if (_sel._selects.get(_pos).equals(obj)) {
return ++_pos;
+ }
// if we're looking for a primary key, try back a couple places,
// since pks might be selected in a slightly different order than
@@ -2496,8 +2496,9 @@ public class SelectImpl
? Boolean.TRUE : Boolean.FALSE;
if (pk.booleanValue()) {
for (int i = _pos - 1; i >= 0 && i >= _pos - 3; i--)
- if (_sel._selects.get(i).equals(obj))
+ if (_sel._selects.get(i).equals(obj)) {
return i + 1;
+ }
}
// search forward on the assumption that we might be skipping
@@ -2515,8 +2516,9 @@ public class SelectImpl
// position marker at its current place cause subsequent loads will
// still probably start from there
for (int i = 0; i < _pos; i++)
- if (_sel._selects.get(i).equals(obj))
+ if (_sel._selects.get(i).equals(obj)) {
return i + 1;
+ }
// somethings's wrong...
throw new SQLException(obj.toString());
@@ -3087,6 +3089,7 @@ public class SelectImpl
protected Map<Object,String> _selectAs = null;
protected DBDictionary _dict = null;
+
/**
* Add all aliases from another instance.
*/
@@ -3266,7 +3269,71 @@ public class SelectImpl
_selectAs = null;
_idents = null;
}
+
+ // Selected column lookup optimization.
+ private Boolean _optimizable;
+ Map<String,Integer> _indices = new HashMap<String, Integer>();
+
+ /**
+ * A set of selected terms become optimized for lookup if all the terms
+ * are columns (may be some with joins) but their names are distinct
+ * In such case, an index lookup is possible only by the name of the column
+ * without any need to recompute alias every time (i.e. for every term for
+ * every row) during lookup.
+ * <br>
+ * This routine computes once and only once per instance to determine
+ * whether such optimization is permissible.
+ * If {@link JDBCConfiguration#getSelectCacheEnabled()} select caching is in effect,
+ * then the same {@link Selects projection term} will be reused and such optimization
+ * may prove useful.
+ */
+ boolean isOptimizable() {
+ if (_optimizable != null) {
+ return _optimizable.booleanValue();
+ }
+ _optimizable = true;
+ int N = size();
+ String columnName = null;
+ for (int i = 0; i < N; i++) {
+ Object key = get(i);
+ if (key instanceof Column) {
+ columnName = ((Column) key).getIdentifier().getName();
+ } else if (key instanceof String) {
+ int dot = ((String)key).lastIndexOf('.');
+ if (dot != -1) {
+ columnName = ((String)key).substring(dot+1);
+ }
+ } else {
+ columnName = null;
+ }
+ if (columnName != null && !_indices.containsKey(columnName)) {
+ _indices.put(columnName, i+1);
+ } else {
+ _indices.clear();
+ _optimizable = false;
+ break;
+ }
+ }
+ return _optimizable;
+ }
+
+ /**
+ * Gets index of the given column assuming that this instance is optimized.
+ * @return JDBC index of the given column
+ * @see #isOptimizable()
+ */
+ Integer getObjectIndex(Column col) {
+ return _indices.get(col.getIdentifier().getName());
+ }
+
+ // for debugging
+ String toString(Object o) {
+ if (o == null) return "null";
+ return o.toString() + '[' + o.getClass().getSimpleName() + '@'
+ + Integer.toHexString(System.identityHashCode(o)) + ']';
+ }
}
+ // ------------- end of SelectImpl$Selects -----------------------------------------
public Joins setCorrelatedVariable(String var) {
if (var == null)