Author: michiel
Date: 2009-06-03 15:21:47 +0200 (Wed, 03 Jun 2009)
New Revision: 35616
Modified:
mmbase/trunk/src/org/mmbase/module/core/MMObjectBuilder.java
mmbase/trunk/src/org/mmbase/module/core/MMObjectNode.java
Log:
several fixes related to MMB-1810. Avoid storing blobs in memory.
Modified: mmbase/trunk/src/org/mmbase/module/core/MMObjectBuilder.java
===================================================================
--- mmbase/trunk/src/org/mmbase/module/core/MMObjectBuilder.java
2009-06-03 13:20:55 UTC (rev 35615)
+++ mmbase/trunk/src/org/mmbase/module/core/MMObjectBuilder.java
2009-06-03 13:21:47 UTC (rev 35616)
@@ -220,11 +220,11 @@
/** Collections of (GUI) names (singular) for the builder's objects,
divided by language
*/
- protected Map<String,String> singularNames;
+ protected Map<String, String> singularNames;
/** Collections of (GUI) names (plural) for the builder's objects, divided
by language
*/
- protected Map<String,String> pluralNames;
+ protected Map<String, String> pluralNames;
/**
* Full filename (path + buildername + ".xml") where we loaded the builder
from
@@ -2212,7 +2212,7 @@
* @param age the search age as a <code>String</code>
*/
public void setSearchAge(String age) {
- this.searchAge=age;
+ this.searchAge = age;
update();
}
@@ -2334,7 +2334,7 @@
/**
* Sets a list of singular names (language - value pairs)
*/
- public void setSingularNames(Map<String,String> names) {
+ public void setSingularNames(Map<String, String> names) {
singularNames = Collections.unmodifiableMap(names);
update();
}
@@ -2349,7 +2349,7 @@
/**
* Sets a list of plural names (language - value pairs)
*/
- public void setPluralNames(Map<String,String> names) {
+ public void setPluralNames(Map<String, String> names) {
pluralNames = Collections.unmodifiableMap(names);
update();
}
@@ -2387,19 +2387,36 @@
* @param node
* @return an array of <code>byte</code> containing the complete contents
of the field.
* @since MMBase-1.8
+ * @deprecated Use {...@link #getShortedInputStream}
*/
protected byte[] getShortedByte(String fieldName, MMObjectNode node) {
if (node.getNumber() < 0) return null; // capture calls from temporary
nodes
try {
return mmb.getStorageManager().getBinaryValue(node,
getField(fieldName));
} catch (StorageException se) {
- log.error(se.getMessage());
- log.error(Logging.stackTrace(se));
+ log.error(se.getMessage(), se);
return null;
}
}
/**
+ * Get binary data of a blob field. This function is called to 'load' a
field into the node, because
+ * it was not loaded together with the node, because it is supposed to be
too big.
+ * @param fieldName name of the field
+ * @param node
+ * @since MMBase-1.9.1
+ */
+ protected java.io.InputStream getShortedInputStream(String fieldName,
MMObjectNode node) {
+ if (node.getNumber() < 0) return null; // capture calls from temporary
nodes
+ try {
+ return mmb.getStorageManager().getInputStreamValue(node,
getField(fieldName));
+ } catch (StorageException se) {
+ log.error(se.getMessage(), se);
+ return null;
+ }
+ }
+
+ /**
* Sets a key/value pair in the main values of this node.
* Note that if this node is a node in cache, the changes are immediately
visible to
* everyone, even if the changes are not committed.
Modified: mmbase/trunk/src/org/mmbase/module/core/MMObjectNode.java
===================================================================
--- mmbase/trunk/src/org/mmbase/module/core/MMObjectNode.java 2009-06-03
13:20:55 UTC (rev 35615)
+++ mmbase/trunk/src/org/mmbase/module/core/MMObjectNode.java 2009-06-03
13:21:47 UTC (rev 35616)
@@ -631,6 +631,7 @@
setSize(fieldName, fi.getSize());
} else if (fieldValue instanceof SerializableInputStream) {
SerializableInputStream si = (SerializableInputStream) fieldValue;
+ log.info("Setting '" + fieldName + "' to " + si + " " +
si.getSize());
setSize(fieldName, si.getSize());
}
@@ -685,7 +686,9 @@
return 0;
}
// Value is not yet loaded from the database?
- if (VALUE_SHORTED.equals(value)) return -1;
+ if (VALUE_SHORTED.equals(value)) {
+ return -1;
+ }
return SizeOf.getByteSize(value);
}
@@ -728,7 +731,7 @@
/**
* @since MMBase-1.8
*/
- public boolean isNull(String fieldName) {
+ public boolean isNull(final String fieldName) {
if (checkFieldExistance(fieldName)) {
Field field = getBuilder().getField(fieldName);
if (field.isVirtual()) {
@@ -737,12 +740,12 @@
if (field != null && field.getType() == Field.TYPE_NODE) {
return getIntValue(fieldName) <= -1;
}
- Object value = values.get(fieldName);
+ final Object value = values.get(fieldName);
if (VALUE_SHORTED.equals(value)) {
// value is not loaded from the database. We have to check the
database to be sure.
return parent.isNull(fieldName, this);
}
- return values.get(fieldName) == null;
+ return value == null;
} else {
return true;
}
@@ -767,7 +770,11 @@
int type = getDBType(fieldName);
switch (type) {
case Field.TYPE_BINARY:
- value = parent.getShortedByte(fieldName, this);
+ if (getSize(fieldName) < blobs.getMaxEntrySize()) {
+ value = parent.getShortedByte(fieldName, this);
+ } else {
+ value = parent.getShortedInputStream(fieldName, this);
+ }
break;
case Field.TYPE_STRING:
value = parent.getShortedText(fieldName, this);
@@ -886,23 +893,8 @@
return o;
}
- /**
- * If the values map contains an InputStream, care must be taken because
often an InputStream can be used only once.
- * @since MMBase-1.8
- */
- private byte[] useInputStream(String fieldName, InputStream stream) {
// first, convert to byte-array
- byte[] b = SerializableInputStream.toByteArray(stream);
- // check if we can cache it.
- BlobCache blobs = parent.getBlobCache(fieldName);
- String key = blobs.getKey(getNumber(), fieldName);
- if (b.length < blobs.getMaxEntrySize()) {
- blobs.put(key, b);
- }
- setSize(fieldName, b.length);
- values.put(fieldName, b);
- return b;
- }
+
/**
* Get a binary value of a certain field.
* @param fieldName the name of the field who's data to return
@@ -951,13 +943,21 @@
}
}
- if (value instanceof InputStream) {
+ if (value instanceof SerializableInputStream) {
+ SerializableInputStream is = (SerializableInputStream) value;
+ try {
+ is.reset();
+ } catch(IOException ioe) {
+ log.warn(ioe);
+ }
+ return is;
+ } else if (value instanceof InputStream) {
// cannot return it directly, it would kill the inputstream, and
perhaps it cannot be saved in db anymore then.
// Sad, we have a buffer always now.
// XXX think of something that the buffer is only needed if
actually used a second time
// May be we don't have to do this if the
InputStream#markSupported()
// We could #reset() then if needed
- return new ByteArrayInputStream(useInputStream(fieldName,
(InputStream) value));
+ return new SerializableInputStream((InputStream) value,
getSize(fieldName));
}
if (VALUE_SHORTED.equals(value)) {
_______________________________________________
Cvs mailing list
[email protected]
http://lists.mmbase.org/mailman/listinfo/cvs