Author: kahatlen
Date: Thu Jun 7 07:39:04 2007
New Revision: 545197
URL: http://svn.apache.org/viewvc?view=rev&rev=545197
Log:
DERBY-2713: Ensure that a temporary file is not created for a lob
obtained from resultset unless user updates it.
Contributed by Anurag Shekhar.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ClobStreamControl.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ClobStreamControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ClobStreamControl.java?view=diff&rev=545197&r1=545196&r2=545197
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ClobStreamControl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/ClobStreamControl.java Thu
Jun 7 07:39:04 2007
@@ -125,6 +125,22 @@
}
/**
+ * Constructs a <code>ClobStreamControl</code> object and
+ * initializes with a initial String.
+ *
+ * @param dbName name of the database the CLOB value belongs to
+ * @param data initial value in String
+ * @param conChild connection object used to obtain synchronization object
+ */
+ ClobStreamControl (String dbName, String data, ConnectionChild conChild)
+ throws IOException, SQLException, StandardException {
+ if (conChild == null) {
+ throw new NullPointerException("conChild cannot be <null>");
+ }
+ this.conChild = conChild;
+ bytes = new LOBStreamControl(dbName, getByteFromString (data));
+ }
+ /**
* Finds the corresponding byte position for the given UTF-8 character
* position, starting from the byte position <code>startPos</code>.
* See comments in SQLChar.readExternal for more notes on
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java?view=diff&rev=545197&r1=545196&r2=545197
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java Thu Jun 7 07:39:04
2007
@@ -112,8 +112,7 @@
EmbedBlob(byte [] blobBytes,EmbedConnection con) throws SQLException {
super(con);
try {
- control = new LOBStreamControl (con.getDBName());
- control.write (blobBytes, 0, blobBytes.length, 0);
+ control = new LOBStreamControl (con.getDBName(), blobBytes);
materialized = true;
//add entry in connection so it can be cleared
//when transaction is not valid
@@ -149,9 +148,9 @@
if (SanityManager.DEBUG)
SanityManager.ASSERT(dvdBytes != null,"blob has a null value underneath");
- control = new LOBStreamControl (getEmbedConnection().getDBName());
try {
- control.write (dvdBytes, 0, dvdBytes.length, pos);
+ control = new LOBStreamControl (
+ getEmbedConnection().getDBName(), dvdBytes);
}
catch (SQLException e) {
throw StandardException.newException (e.getSQLState());
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java?view=diff&rev=545197&r1=545196&r2=545197
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java Thu Jun 7 07:39:04
2007
@@ -113,9 +113,9 @@
InputStream storeStream = dvd.getStream();
// See if a String or a stream will be the source of the Clob.
if (storeStream == null) {
- this.clob = new ClobStreamControl(con.getDBName(), this);
try {
- this.clob.insertString (dvd.getString(), 1L);
+ clob = new ClobStreamControl(con.getDBName(),
+ dvd.getString(), this);
}
catch (SQLException sqle) {
throw StandardException.newException (sqle.getSQLState(), sqle);
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java?view=diff&rev=545197&r1=545196&r2=545197
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java Thu Jun
7 07:39:04 2007
@@ -45,12 +45,17 @@
/**
* This class acts as a layer of blob/clob repository (in memory or file).
- * The max bytes of data stored in memory is MAX_BUF_SIZE. When write
- * increases the data beyond this value a temporary file is created and data
- * is moved into that. If truncate reduces the size of the file below
- * MAX_BUF_SIZE the data moved into memory.
+ * The max bytes of data stored in memory depends on the way this
+ * class is created. If the class is created with initial data, the buffer
+ * size is set to the size of the byte array supplied. If no initial data
+ * is supplied or if the initial data size is less than DEFAULT_MAX_BUF_SIZE,
+ * The buffer size is set to DEFAULT_MAX_BUF_SIZE.
+ * When write increases the data beyond this value a temporary file is created
+ * and data is moved into that. If truncate reduces the size of the file below
+ * initial buffer size (max of DEFAULT_MAX_BUF_SIZE and initial byte array size)
+ * the data moved into memory.
*
- * This class also creates Input- and OutputStream which can be used to access
+ * This class also creates InputStream and OutputStream which can be used to access
* blob data irrespective of if its in memory or in file.
*/
@@ -59,15 +64,33 @@
private StorageFile lobFile;
private byte [] dataBytes = new byte [0];
private boolean isBytes = true;
- //keeping max 4k bytes in memory
- //randomly selected value
- private final int MAX_BUF_SIZE = 4096;
+ private final int bufferSize;
private String dbName;
private long updateCount;
+ private static final int DEFAULT_MAX_BUF_SIZE = 4096;
- public LOBStreamControl (String dbName) {
+ /**
+ * Creates an empty LOBStreamControl.
+ * @param dbName database name
+ */
+ LOBStreamControl (String dbName) {
+ this.dbName = dbName;
+ updateCount = 0;
+ //default buffer size
+ bufferSize = DEFAULT_MAX_BUF_SIZE;
+ }
+
+ /**
+ * Creates a LOBStreamControl and initializes with a bytes array.
+ * @param dbName database name
+ * @param data initial value
+ */
+ LOBStreamControl (String dbName, byte [] data)
+ throws IOException, SQLException, StandardException {
this.dbName = dbName;
updateCount = 0;
+ bufferSize = Math.max (DEFAULT_MAX_BUF_SIZE, data.length);
+ write (data, 0, data.length, 0);
}
private void init(byte [] b, long len)
@@ -107,6 +130,7 @@
//now this call will write into the file
if (len != 0)
write(b, 0, (int) len, 0);
+ dataBytes = null;
}
private long updateData(byte[] bytes, int offset, int len, long pos)
@@ -186,7 +210,7 @@
isValidPostion(pos);
updateCount++;
if (isBytes) {
- if (pos < MAX_BUF_SIZE) {
+ if (pos < bufferSize) {
byte [] bytes = {(byte) b};
updateData(bytes, 0, 1, pos);
return pos + 1;
@@ -223,7 +247,7 @@
}
updateCount++;
if (isBytes) {
- if (pos + len <= MAX_BUF_SIZE)
+ if (pos + len <= bufferSize)
return updateData(b, off, len, pos);
else {
init(dataBytes, pos);
@@ -331,7 +355,7 @@
System.arraycopy(dataBytes, 0, tmpByte, 0, (int) size);
dataBytes = tmpByte;
} else {
- if (size < MAX_BUF_SIZE) {
+ if (size < bufferSize) {
dataBytes = new byte [(int) size];
read(dataBytes, 0, dataBytes.length, 0);
isBytes = true;
@@ -356,11 +380,10 @@
*/
synchronized void copyData(InputStream inStream,
long length) throws IOException, SQLException, StandardException {
- byte [] data = new byte [MAX_BUF_SIZE];
+ byte [] data = new byte [bufferSize];
long sz = 0;
while (sz < length) {
- int len = (int) (((length - sz) >= MAX_BUF_SIZE) ? MAX_BUF_SIZE
- : length - sz);
+ int len = (int) Math.min (length - sz, bufferSize);
inStream.read(data, 0, len);
write(data, 0, len, sz);
sz += len;
@@ -420,7 +443,7 @@
long length = getLength();
long finalLength = length - endPos + stPos + buf.length;
if (isBytes) {
- if (finalLength > MAX_BUF_SIZE) {
+ if (finalLength > bufferSize) {
init (dataBytes, stPos);
write (buf, 0, buf.length, getLength());
if (endPos < length)
|