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 2010/06/04 13:04:02 UTC
svn commit: r951362 - in /db/derby/code/branches/10.6: ./
java/engine/org/apache/derby/iapi/types/
Author: kristwaa
Date: Fri Jun 4 11:04:02 2010
New Revision: 951362
URL: http://svn.apache.org/viewvc?rev=951362&view=rev
Log:
DERBY-4661: Reduce size of encoding buffer for short character values
Merged fix from trunk (revision 948069).
Modified:
db/derby/code/branches/10.6/ (props changed)
db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/CharStreamHeaderGenerator.java
db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ClobStreamHeaderGenerator.java
db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ReaderToUTF8Stream.java
db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/SQLClob.java
db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/StreamHeaderGenerator.java
Propchange: db/derby/code/branches/10.6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Fri Jun 4 11:04:02 2010
@@ -1 +1 @@
-/db/derby/code/trunk:938547,938796,938959,939231,940462,940469,941627,942031,944152,946794,948045
+/db/derby/code/trunk:938547,938796,938959,939231,940462,940469,941627,942031,944152,946794,948045,948069
Modified: db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/CharStreamHeaderGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/CharStreamHeaderGenerator.java?rev=951362&r1=951361&r2=951362&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/CharStreamHeaderGenerator.java (original)
+++ db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/CharStreamHeaderGenerator.java Fri Jun 4 11:04:02 2010
@@ -134,4 +134,13 @@ public final class CharStreamHeaderGener
return 0;
}
}
+
+ /**
+ * Returns the maximum header length.
+ *
+ * @return Maximum header length in bytes.
+ */
+ public int getMaxHeaderLength() {
+ return 2;
+ }
}
Modified: db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ClobStreamHeaderGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ClobStreamHeaderGenerator.java?rev=951362&r1=951361&r2=951362&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ClobStreamHeaderGenerator.java (original)
+++ db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ClobStreamHeaderGenerator.java Fri Jun 4 11:04:02 2010
@@ -239,6 +239,15 @@ public final class ClobStreamHeaderGener
}
/**
+ * Returns the maximum header length.
+ *
+ * @return Maximum header length in bytes.
+ */
+ public int getMaxHeaderLength() {
+ return 5;
+ }
+
+ /**
* Determines which header format to use.
* <p>
* <em>Implementation note:</em> The header format is determined by
Modified: db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ReaderToUTF8Stream.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ReaderToUTF8Stream.java?rev=951362&r1=951361&r2=951362&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ReaderToUTF8Stream.java (original)
+++ db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/ReaderToUTF8Stream.java Fri Jun 4 11:04:02 2010
@@ -51,6 +51,8 @@ public final class ReaderToUTF8Stream
/** Constant indicating the first iteration of {@code fillBuffer}. */
private final static int FIRST_READ = Integer.MIN_VALUE;
+ /** Buffer space reserved for one 3 byte encoded char and the EOF marker. */
+ private final static int READ_BUFFER_RESERVATION = 6;
/**
* Constant indicating that no mark is set in the stream, or that the read
* ahead limit of the mark has been exceeded.
@@ -58,10 +60,11 @@ public final class ReaderToUTF8Stream
private final static int MARK_UNSET_OR_EXCEEDED = -1;
/**
* Buffer to hold the data read from stream and converted to the modified
- * UTF-8 format. The initial size is 32 KB, but it may grow if the
+ * UTF-8 format. The initial size is dependent on whether the data value
+ * length is known (limited upwards to 32 KB), but it may grow if
* {@linkplain #mark(int)} is invoked.
*/
- private byte[] buffer = new byte[32*1024];
+ private byte[] buffer;
private int boff;
private int blen = -1;
/** Stream mark, set through {@linkplain #mark(int)}. */
@@ -83,7 +86,7 @@ public final class ReaderToUTF8Stream
* Number of characters to truncate from this stream.
* The SQL standard allows for truncation of trailing spaces for CLOB,
* VARCHAR and CHAR. If zero, no characters are truncated, unless the
- * stream length execeeds the maximum length of the column we are inserting
+ * stream length exceeds the maximum length of the column we are inserting
* into.
*/
private final int charsToTruncate;
@@ -124,11 +127,13 @@ public final class ReaderToUTF8Stream
String typeName,
StreamHeaderGenerator headerGenerator) {
this.reader = new LimitReader(appReader);
- reader.setLimit(valueLength);
this.charsToTruncate = numCharsToTruncate;
this.valueLength = valueLength;
this.typeName = typeName;
this.hdrGen = headerGenerator;
+
+ int absValueLength = Math.abs(valueLength);
+ reader.setLimit(absValueLength);
if (SanityManager.DEBUG) {
// Check the type name
// The national types (i.e. NVARCHAR) are not used/supported.
@@ -138,6 +143,17 @@ public final class ReaderToUTF8Stream
typeName.equals(TypeId.CLOB_NAME)) ||
typeName.equals(TypeId.LONGVARCHAR_NAME));
}
+ // Optimization for small values, where we reduce the memory
+ // requirement during encoding/insertion.
+ // Be conservative, assume three bytes per char.
+ int bz = 32*1024; // 32 KB default
+ if (absValueLength < bz / 3) {
+ // Enforce a minimum size of the buffer, otherwise read may loop
+ // indefinitely (must enter for loop in fillBuffer to detect EOF).
+ bz = hdrGen.getMaxHeaderLength() +
+ Math.max(READ_BUFFER_RESERVATION, absValueLength * 3 +3);
+ }
+ buffer = new byte[bz];
}
/**
@@ -167,7 +183,6 @@ public final class ReaderToUTF8Stream
throw new IllegalArgumentException("Maximum length for a capped " +
"stream cannot be negative: " + maximumLength);
}
- reader.setLimit(maximumLength);
}
/**
@@ -325,7 +340,7 @@ public final class ReaderToUTF8Stream
if (mark >= 0) {
// Add 6 bytes reserved for one 3 byte character encoding and the
// 3 byte Derby EOF marker (see encoding loop further down).
- int spaceRequired = readAheadLimit + 6;
+ int spaceRequired = readAheadLimit + READ_BUFFER_RESERVATION;
if (mark + spaceRequired > buffer.length) {
if (blen != -1) {
// Calculate the new offset, as we may have to shift bytes
@@ -347,7 +362,7 @@ public final class ReaderToUTF8Stream
// 6! need to leave room for a three byte UTF8 encoding
// and 3 bytes for our special end of file marker.
- for (; off <= buffer.length - 6; )
+ for (; off <= buffer.length - READ_BUFFER_RESERVATION; )
{
int c = reader.read();
if (c < 0) {
@@ -558,7 +573,7 @@ public final class ReaderToUTF8Stream
*/
public void reset()
throws IOException {
- // Throw execption if the stream has been closed implicitly or
+ // Throw exception if the stream has been closed implicitly or
// explicitly.
if (buffer == null) {
throw new EOFException(MessageService.getTextMessage
Modified: db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/SQLClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/SQLClob.java?rev=951362&r1=951361&r2=951362&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/SQLClob.java (original)
+++ db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/SQLClob.java Fri Jun 4 11:04:02 2010
@@ -57,10 +57,6 @@ import java.util.Calendar;
public class SQLClob
extends SQLVarchar
{
-
- /** The maximum number of bytes used by the stream header. */
- private static final int MAX_STREAM_HEADER_LENGTH = 5;
-
/** The header generator used for 10.4 (or older) databases. */
private static final StreamHeaderGenerator TEN_FOUR_CLOB_HEADER_GENERATOR =
new ClobStreamHeaderGenerator(true);
@@ -70,6 +66,14 @@ public class SQLClob
new ClobStreamHeaderGenerator(false);
/**
+ * The maximum number of bytes used by the stream header.
+ * <p>
+ * Use the length specified by the ten five header generator.
+ */
+ private static final int MAX_STREAM_HEADER_LENGTH =
+ TEN_FIVE_CLOB_HEADER_GENERATOR.getMaxHeaderLength();
+
+ /**
* The descriptor for the stream. If there is no stream this should be
* {@code null}, which is also true if the descriptor hasen't been
* constructed yet.
Modified: db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/StreamHeaderGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/StreamHeaderGenerator.java?rev=951362&r1=951361&r2=951362&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/StreamHeaderGenerator.java (original)
+++ db/derby/code/branches/10.6/java/engine/org/apache/derby/iapi/types/StreamHeaderGenerator.java Fri Jun 4 11:04:02 2010
@@ -86,4 +86,11 @@ public interface StreamHeaderGenerator {
* @throws IOException if writing to the destination stream fails
*/
int writeEOF(ObjectOutput out, long valueLength) throws IOException;
+
+ /**
+ * Returns the maximum length of the header.
+ *
+ * @return Max header length in bytes.
+ */
+ int getMaxHeaderLength();
}