You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by kr...@apache.org on 2008/10/17 09:51:03 UTC
svn commit: r705502 - in
/db/derby/code/branches/10.4/java/client/org/apache/derby/client:
am/LOBStateTracker.java am/ResultSet.java net/NetCursor.java
Author: kristwaa
Date: Fri Oct 17 00:51:02 2008
New Revision: 705502
URL: http://svn.apache.org/viewvc?rev=705502&view=rev
Log:
DERBY-3601: Optimize LOBStateTracker for non-locator servers.
Merged fixes from trunk; 690133, 691205 and 701156.
Modified:
db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/LOBStateTracker.java
db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java
db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java
Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/LOBStateTracker.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/LOBStateTracker.java?rev=705502&r1=705501&r2=705502&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/LOBStateTracker.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/LOBStateTracker.java Fri Oct 17 00:51:02 2008
@@ -23,16 +23,24 @@
import java.util.Arrays;
/**
- * An object that tracks the state of large objects (LOBs) in a result set.
+ * An object that tracks the state of large objects (LOBs) for the current row
+ * in a result set.
* <p>
- * This object covers two types of functionality regarding LOBs;
+ * A LOB's state is either unpublished or published. When a LOB is published, it
+ * means that the end-user has been given a reference to the LOB object. This
+ * implies that the LOB cannot be automatically freed/released when the
+ * result set position changes (i.e. typically {@code rs.next()}), because the
+ * LOB object must be kept valid/alive until the transaction is ended or the
+ * LOB object is explicitly freed.
+ * <p>
+ * This class covers two types of functionality regarding LOBs;
* <ul>
- * <li>Keep track of whether a LOB column has been accessed.</li>
+ * <li>Keep track of whether a LOB column has been published or not.</li>
* <li>Release LOB locators on the server.</li>
* </ul>
- * The former functionality is always present in a tracker object. The latter
- * functionality may or may not be available. This is decided by whether
- * locators are supported by the server or not.
+ * Both functionalities will be disabled if the server doesn't support locators.
+ * If locators are enabled, they will be freed when {@link #checkCurrentRow} is
+ * called.
* <p>
* The tracker has a notion of current row. The current row is changed by
* calling {@link #checkCurrentRow checkCurrentRow}. The owner of the tracker
@@ -44,21 +52,23 @@
*/
class LOBStateTracker {
- /** Instance to use when there are no LOBs in the result set. */
+ /**
+ * Instance to use when there are no LOBs in the result set, or when the
+ * server doesn't support locators.
+ */
public static final LOBStateTracker NO_OP_TRACKER =
new LOBStateTracker(new int[0], new boolean[0], false);
-
/** 1-based column indexes for the LOBs to track. */
private final int[] columns;
- /** Tells whether a LOB is Blob or a Clob. */
+ /** Tells whether the LOB is Blob or a Clob. */
private final boolean[] isBlob;
- /** Tells whether a LOB colum has been accessed in the current row. */
- private final boolean[] accessed;
+ /** Tells whether the LOB colum has been published for the current row. */
+ private final boolean[] published;
/**
* Tells whether locators shall be released. This will be {@code false} if
* locators are not supported by the server.
*/
- private final boolean release;
+ private final boolean doRelease;
/**
* The last locator values seen when releasing. These values are used to
* detect if {@linkplain #checkCurrentRow} is being executed more than once
@@ -71,15 +81,15 @@
*
* @param lobIndexes the 1-based indexes of the LOB columns
* @param isBlob whether the LOB is a Blob or a Clob
- * @param release whether locators shall be released
+ * @param doRelease whether locators shall be released
* @see #NO_OP_TRACKER
*/
- LOBStateTracker(int[] lobIndexes, boolean[] isBlob, boolean release) {
+ LOBStateTracker(int[] lobIndexes, boolean[] isBlob, boolean doRelease) {
this.columns = lobIndexes;
this.isBlob = isBlob;
- this.accessed = new boolean[columns.length];
- this.release = release;
- // Zero is an invalid locator, so don't fill with different value.
+ this.published = new boolean[columns.length];
+ this.doRelease = doRelease;
+ // Zero is an invalid locator, don't fill with a valid value.
this.lastLocatorSeen = new int[columns.length];
}
@@ -94,12 +104,12 @@
*/
void checkCurrentRow(Cursor cursor)
throws SqlException {
- if (this.release) {
+ if (this.doRelease) {
CallableLocatorProcedures procs = cursor.getLocatorProcedures();
for (int i=0; i < this.columns.length; i++) {
// Note the conversion from 1-based to 0-based index when
// checking if the column has a NULL value.
- if (!this.accessed[i] && !cursor.isNull_[this.columns[i] -1]) {
+ if (!this.published[i] && !cursor.isNull_[this.columns[i] -1]) {
// Fetch the locator so we can free it.
int locator = cursor.locator(this.columns[i]);
if (locator == this.lastLocatorSeen[i]) {
@@ -120,9 +130,9 @@
}
}
}
+ // Reset state for the next row.
+ Arrays.fill(this.published, false);
}
- // Reset state for the next row.
- Arrays.fill(this.accessed, false);
}
/**
@@ -133,24 +143,28 @@
* to release them from the client side in this case.
*/
void discardState() {
- // Force the internal state to accessed for all LOB columns.
- // This will cause checkCurrentRow to ignore all LOBs on the next
- // invocation. The method markAccessed cannot be called before after
- // checkCurrentRow has been called again.
- Arrays.fill(this.accessed, true);
+ if (this.doRelease) {
+ // Force the state to published for all LOB columns.
+ // This will cause checkCurrentRow to ignore all LOBs on the next
+ // invocation. The method markAsPublished cannot be called before
+ // after checkCurrentRow has been called again.
+ Arrays.fill(this.published, true);
+ }
}
/**
- * Marks the specified column of the current row as accessed, which implies
+ * Marks the specified column of the current row as published, which implies
* that the tracker should not release the associated locator.
* <p>
- * Columns must be marked as accessed when a LOB object is created on
+ * Columns must be marked as published when a LOB object is created on
* the client, to avoid releasing the corresponding locator too early.
*
* @param index 1-based column index
*/
- void markAccessed(int index) {
- int internalIndex = Arrays.binarySearch(this.columns, index);
- this.accessed[internalIndex] = true;
+ void markAsPublished(int index) {
+ if (this.doRelease) {
+ int internalIndex = Arrays.binarySearch(this.columns, index);
+ this.published[internalIndex] = true;
+ }
}
}
Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java?rev=705502&r1=705501&r2=705502&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/am/ResultSet.java Fri Oct 17 00:51:02 2008
@@ -6201,29 +6201,33 @@
}
/**
- * Marks the LOB at the specified column as accessed.
+ * Marks the LOB at the specified column as published.
* <p>
- * When a LOB is marked as accessed, the release mechanism will not be
+ * When a LOB is marked as published, the release mechanism will not be
* invoked by the result set. It is expected that the code accessing the
- * LOB releases the locator when it is done with the LOB.
+ * LOB releases the locator when it is done with the LOB, or that the
+ * commit/rollback handles the release.
*
* @param index 1-based column index
*/
- public final void markLOBAsAccessed(int index) {
- this.lobState.markAccessed(index);
+ public final void markLOBAsPublished(int index) {
+ this.lobState.markAsPublished(index);
}
/**
* Initializes the LOB state tracker.
* <p>
- * The state tracker is used to free LOB locators on the server.
+ * The state tracker is used to free LOB locators on the server. If the
+ * server doesn't support locators, or there are no LOBs in the result set,
+ * a no-op tracker will be used.
*/
final void createLOBColumnTracker() {
if (SanityManager.DEBUG) {
SanityManager.ASSERT(this.lobState == null,
"LOB state tracker already initialized.");
}
- if (this.resultSetMetaData_.hasLobColumns()) {
+ if (this.connection_.supportsSessionDataCaching() &&
+ this.resultSetMetaData_.hasLobColumns()) {
final int columnCount = this.resultSetMetaData_.columns_;
int lobCount = 0;
int[] tmpIndexes = new int[columnCount];
@@ -6240,8 +6244,7 @@
boolean[] isBlob = new boolean[lobCount];
System.arraycopy(tmpIndexes, 0, lobIndexes, 0, lobCount);
System.arraycopy(tmpIsBlob, 0, isBlob, 0, lobCount);
- this.lobState = new LOBStateTracker(lobIndexes, isBlob,
- this.connection_.serverSupportsLocators());
+ this.lobState = new LOBStateTracker(lobIndexes, isBlob, true);
} else {
// Use a no-op state tracker to simplify code expecting a tracker.
this.lobState = LOBStateTracker.NO_OP_TRACKER;
Modified: db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java?rev=705502&r1=705501&r2=705502&view=diff
==============================================================================
--- db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java (original)
+++ db/derby/code/branches/10.4/java/client/org/apache/derby/client/net/NetCursor.java Fri Oct 17 00:51:02 2008
@@ -1083,7 +1083,7 @@
throws SqlException {
// Only inform the tracker if the Blob is published to the user.
if (toBePublished) {
- netResultSet_.markLOBAsAccessed(column);
+ netResultSet_.markLOBAsPublished(column);
}
// Check for locator
int locator = locator(column);
@@ -1125,7 +1125,7 @@
throws SqlException {
// Only inform the tracker if the Clob is published to the user.
if (toBePublished) {
- netResultSet_.markLOBAsAccessed(column);
+ netResultSet_.markLOBAsPublished(column);
}
// Check for locator
int locator = locator(column);