From: <ssk...@vh...> - 2005-12-02 16:10:07
|
Author: sskracic Date: 2005-12-02 17:07:27 +0100 (Fri, 02 Dec 2005) New Revision: 1021 Modified: trunk/ccm-core/application.xml trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig.java trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig_parameter.properties trunk/ccm-core/src/com/redhat/persistence/engine/rdbms/RDBMSEngine.java Log: Adding another configuration parameter: waf.runtime.jdbc_resultset_windowsize. It denotes the width of the in-memory window for the fetched result set. Setting it to 0 means 'unlimited', ie. all rows from the retrieved result set are kept in memory until the result set is closed. This was the default persistence behavior and it's bad bad bad. The default setting is now 1 (a single row), which means keep as little as possible in memory. This alleviates the frequently reported OutOfMemory exception on Postgres. BUT, for this to work, both server and client must be on 8.0 or greater. This patch is not yet fully tested on Oracle, and it's currently unknown whether the memory usage is affected with it. Modified: trunk/ccm-core/application.xml =================================================================== --- trunk/ccm-core/application.xml 2005-11-30 16:28:00 UTC (rev 1020) +++ trunk/ccm-core/application.xml 2005-12-02 16:07:27 UTC (rev 1021) @@ -3,7 +3,7 @@ name="ccm-core" prettyName="Core" version="6.3.0" - release="4" + release="5" webapp="ROOT" buildHooks="build-hooks.xml"> <ccm:dependencies> Modified: trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig.java =================================================================== --- trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig.java 2005-11-30 16:28:00 UTC (rev 1020) +++ trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig.java 2005-12-02 16:07:27 UTC (rev 1021) @@ -61,6 +61,7 @@ private final Parameter m_pingInterval; private final Parameter m_queryCacheSize; private final Parameter m_threadTagging; + private final Parameter m_resultSetWindowSize; /** * Constructs an empty RuntimeConfig object. @@ -81,12 +82,16 @@ ("waf.runtime.thread_tagging", Parameter.REQUIRED, Boolean.TRUE); + m_resultSetWindowSize = new IntegerParameter + ("waf.runtime.jdbc_resultset_windowsize", Parameter.REQUIRED, + new Integer(1)); register(m_url); register(m_poolSize); register(m_pingInterval); register(m_queryCacheSize); register(m_threadTagging); + register(m_resultSetWindowSize); loadInfo(); } @@ -115,6 +120,15 @@ return ((Integer) get(m_pingInterval)).longValue(); } + /** + * Returns the size of in-memory window of a fetched result set. + * + * @return 0 if all fetched rows are kept in memory (beware!) + */ + public final int getResultSetWindowSize() { + return ((Integer) get(m_resultSetWindowSize)).intValue(); + } + public final int getQueryCacheSize() { return ((Integer) get(m_queryCacheSize)).intValue(); } Modified: trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig_parameter.properties =================================================================== --- trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig_parameter.properties 2005-11-30 16:28:00 UTC (rev 1020) +++ trunk/ccm-core/src/com/arsdigita/runtime/RuntimeConfig_parameter.properties 2005-12-02 16:07:27 UTC (rev 1021) @@ -9,4 +9,8 @@ waf.runtime.jdbc_ping_interval.title=JDBC ping interval waf.runtime.jdbc_ping_interval.purpose=Interval used to test for idle connections to be returned to the pool waf.runtime.jdbc_ping_interval.example=30000 -waf.runtime.jdbc_ping_interval.format=[number] \ No newline at end of file +waf.runtime.jdbc_ping_interval.format=[number] +waf.runtime.jdbc_resultset_windowsize.title=ResultSet memory window size +waf.runtime.jdbc_resultset_windowsize.purpose=Number of result set rows kept in memory, 0=keep all rows in memory +waf.runtime.jdbc_resultset_windowsize.example=1 +waf.runtime.jdbc_resultset_windowsize.format=[number] Modified: trunk/ccm-core/src/com/redhat/persistence/engine/rdbms/RDBMSEngine.java =================================================================== --- trunk/ccm-core/src/com/redhat/persistence/engine/rdbms/RDBMSEngine.java 2005-11-30 16:28:00 UTC (rev 1020) +++ trunk/ccm-core/src/com/redhat/persistence/engine/rdbms/RDBMSEngine.java 2005-12-02 16:07:27 UTC (rev 1021) @@ -18,15 +18,18 @@ */ package com.redhat.persistence.engine.rdbms; +import com.arsdigita.runtime.RuntimeConfig; +import com.arsdigita.util.UncheckedWrapperException; +import com.arsdigita.util.WrappedError; import com.redhat.persistence.DataSet; import com.redhat.persistence.Engine; import com.redhat.persistence.Event; import com.redhat.persistence.PropertyMap; import com.redhat.persistence.QuerySource; import com.redhat.persistence.RecordSet; +import com.redhat.persistence.SQLWriterException; import com.redhat.persistence.SetEvent; import com.redhat.persistence.Signature; -import com.redhat.persistence.SQLWriterException; import com.redhat.persistence.common.CompoundKey; import com.redhat.persistence.common.Path; import com.redhat.persistence.metadata.Adapter; @@ -38,8 +41,6 @@ import com.redhat.persistence.oql.Expression; import com.redhat.persistence.oql.Query; import com.redhat.persistence.oql.Size; -import com.arsdigita.util.UncheckedWrapperException; -import com.arsdigita.util.WrappedError; import java.sql.Connection; import java.sql.PreparedStatement; @@ -80,6 +81,9 @@ private ArrayList m_mutations = new ArrayList(); private ArrayList m_mutationTypes = new ArrayList(); + private static int s_windowSize = + RuntimeConfig.getConfig().getResultSetWindowSize(); + private ConnectionSource m_source; private Connection m_conn = null; private int m_connUsers = 0; @@ -109,28 +113,28 @@ if (m_conn == null) { m_conn = m_source.acquire(); } - m_connUsers++; + m_connUsers++; } void release() { - if (m_conn == null) { - return; - } + if (m_conn == null) { + return; + } - m_connUsers--; + m_connUsers--; - if (m_connUsers == 0) { + if (m_connUsers == 0) { m_source.release(m_conn); m_conn = null; } } void releaseAll() { - if (m_conn != null) { - m_source.release(m_conn); - m_conn = null; - m_connUsers = 0; - } + if (m_conn != null) { + m_source.release(m_conn); + m_conn = null; + m_connUsers = 0; + } } void addOperation(Object obj, DML dml) { @@ -138,7 +142,7 @@ if (dml instanceof Delete) { DML prev = (DML) m_operationMap.get(key); if (prev != null) { - removeOperation(obj, prev); + removeOperation(obj, prev); } } m_operationMap.put(key, dml); @@ -147,8 +151,8 @@ void removeOperation(Object obj, DML dml) { Object key = new CompoundKey(obj, dml.getTable()); - m_operationMap.remove(key); - m_operations.remove(dml); + m_operationMap.remove(key); + m_operations.remove(dml); } DML getOperation(Object obj, Table table) { @@ -161,7 +165,7 @@ } void clearUpdates(Object obj) { - m_operationMap.remove(obj); + m_operationMap.remove(obj); } void removeUpdates(Object obj) { @@ -171,31 +175,31 @@ LOG.debug("found: " + ops); for (Iterator it = ops.iterator(); it.hasNext(); ) { Operation op = (Operation) it.next(); - if (op instanceof DML) { - removeOperation(obj, (DML) op); - } else { - m_operations.remove(op); - } + if (op instanceof DML) { + removeOperation(obj, (DML) op); + } else { + m_operations.remove(op); + } it.remove(); } } - clearUpdates(obj); + clearUpdates(obj); } void markUpdate(Object obj) { - if (!hasUpdates(obj)) { - m_operationMap.put(obj, new ArrayList()); - } + if (!hasUpdates(obj)) { + m_operationMap.put(obj, new ArrayList()); + } } void markUpdate(Object obj, Operation op) { - markUpdate(obj); - ArrayList ops = (ArrayList) m_operationMap.get(obj); - ops.add(op); + markUpdate(obj); + ArrayList ops = (ArrayList) m_operationMap.get(obj); + ops.add(op); } boolean hasUpdates(Object obj) { - return m_operationMap.containsKey(obj); + return m_operationMap.containsKey(obj); } void addOperation(Operation op) { @@ -485,6 +489,10 @@ try { if (cycle != null) { cycle.beginExecute(); } + if (s_windowSize > 0) { + ps.setFetchDirection(ResultSet.FETCH_FORWARD); + ps.setFetchSize(s_windowSize); + } if (ps.execute()) { if (cycle != null) { cycle.endExecute(0); } return new ResultCycle(this, ps.getResultSet(), cycle); |