<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I just checked the following in trunk. <div><br></div><div>Galder, you may want to do something similar for your JBMAR prototype.<div><br></div><div>The changes are around InternalCacheEntry and now InternalCacheValue.</div><div><br></div><div>Previously, the marshaller stored an InternalCacheEntry as [key, value, canExpire, created, lifespan, lastUsed, maxIdle], setting either of the last 4 elements to -1 if they are unused. In a system mainly comprising of mortal values, this is wasteful since each of the last 2 values - which would be unused - are longs and still written to.</div><div><br></div><div>So this change identifies the InternalCacheEntry and writes just what is needed, hence the use of specific magic numbers for each of the InternalCacheEntry implementations. Using a different magic number for each entry type allows me to trim what is written.</div><div><br></div><div>Same approach used for InternalCacheValue. </div><div><br></div><div>Yes, even more ugly switch statements - and this is why we need JBMAR to clean this up - if and when it can match performance and compactness of the resulting byte array. :-)</div><div><br></div><div>Cheers</div><div>Manik</div><div><br></div><div><br></div><div><div><div>Begin forwarded message:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>From: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica"><a href="mailto:infinispan-commits@lists.jboss.org">infinispan-commits@lists.jboss.org</a></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>Date: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica">8 May 2009 12:37:23 BST</font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>To: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica"><a href="mailto:infinispan-commits@lists.jboss.org">infinispan-commits@lists.jboss.org</a></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>Subject: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica"><b>[infinispan-commits] Infinispan SVN: r234 - trunk/core/src/main/java/org/infinispan/marshall.</b></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; "><font face="Helvetica" size="3" color="#000000" style="font: 12.0px Helvetica; color: #000000"><b>Reply-To: </b></font><font face="Helvetica" size="3" style="font: 12.0px Helvetica"><a href="mailto:infinispan-commits@lists.jboss.org">infinispan-commits@lists.jboss.org</a></font></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; min-height: 14px; "><br></div> </div><div>Author: <a href="mailto:manik.surtani@jboss.com">manik.surtani@jboss.com</a><br>Date: 2009-05-08 07:37:23 -0400 (Fri, 08 May 2009)<br>New Revision: 234<br><br>Modified:<br> trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java<br>Log:<br>Improved marshaller<br><br>Modified: trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java<br>===================================================================<br>--- trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java<span class="Apple-tab-span" style="white-space:pre">        </span>2009-05-08 11:36:59 UTC (rev 233)<br>+++ trunk/core/src/main/java/org/infinispan/marshall/MarshallerImpl.java<span class="Apple-tab-span" style="white-space:pre">        </span>2009-05-08 11:37:23 UTC (rev 234)<br>@@ -26,8 +26,13 @@<br> import org.infinispan.commands.RemoteCommandFactory;<br> import org.infinispan.commands.ReplicableCommand;<br> import org.infinispan.commands.write.WriteCommand;<br>+import org.infinispan.container.entries.ImmortalCacheEntry;<br> import org.infinispan.container.entries.InternalCacheEntry;<br>+import org.infinispan.container.entries.InternalCacheValue;<br> import org.infinispan.container.entries.InternalEntryFactory;<br>+import org.infinispan.container.entries.MortalCacheEntry;<br>+import org.infinispan.container.entries.TransientCacheEntry;<br>+import org.infinispan.container.entries.TransientMortalCacheEntry;<br> import org.infinispan.io.ByteBuffer;<br> import org.infinispan.io.ExposedByteArrayOutputStream;<br> import org.infinispan.remoting.responses.ExceptionResponse;<br>@@ -94,14 +99,23 @@<br> protected static final int MAGICNUMBER_SINGLETON_LIST = 23;<br> protected static final int MAGICNUMBER_COMMAND = 24;<br> protected static final int MAGICNUMBER_TRANSACTION_LOG = 25;<br>- protected static final int MAGICNUMBER_INTERNAL_CACHED_ENTRY = 26;<br><br>+ // --- cache entries and values ---<br>+ protected static final int MAGICNUMBER_ICE_IMMORTAL = 26;<br>+ protected static final int MAGICNUMBER_ICE_MORTAL = 27;<br>+ protected static final int MAGICNUMBER_ICE_TRANSIENT = 28;<br>+ protected static final int MAGICNUMBER_ICE_TRANSIENT_MORTAL = 29;<br>+ protected static final int MAGICNUMBER_ICV_IMMORTAL = 30;<br>+ protected static final int MAGICNUMBER_ICV_MORTAL = 31;<br>+ protected static final int MAGICNUMBER_ICV_TRANSIENT = 32;<br>+ protected static final int MAGICNUMBER_ICV_TRANSIENT_MORTAL = 33;<br>+<br> // ---- responses<br>- protected static final int MAGICNUMBER_REQUEST_IGNORED_RESPONSE = 27;<br>- protected static final int MAGICNUMBER_EXTENDED_RESPONSE = 28;<br>- protected static final int MAGICNUMBER_EXCEPTION_RESPONSE = 29;<br>- protected static final int MAGICNUMBER_SUCCESSFUL_RESPONSE = 30;<br>- protected static final int MAGICNUMBER_UNSUCCESSFUL_RESPONSE = 31;<br>+ protected static final int MAGICNUMBER_REQUEST_IGNORED_RESPONSE = 34;<br>+ protected static final int MAGICNUMBER_EXTENDED_RESPONSE = 35;<br>+ protected static final int MAGICNUMBER_EXCEPTION_RESPONSE = 36;<br>+ protected static final int MAGICNUMBER_SUCCESSFUL_RESPONSE = 37;<br>+ protected static final int MAGICNUMBER_UNSUCCESSFUL_RESPONSE = 38;<br><br> protected static final int MAGICNUMBER_NULL = 99;<br> protected static final int MAGICNUMBER_SERIALIZABLE = 100;<br>@@ -173,19 +187,9 @@<br> } else if (o instanceof Response) {<br> marshallResponse((Response) o, out, refMap);<br> } else if (o instanceof InternalCacheEntry) {<br>- out.writeByte(MAGICNUMBER_INTERNAL_CACHED_ENTRY);<br>- InternalCacheEntry ice = (InternalCacheEntry) o;<br>- marshallObject(ice.getKey(), out, refMap);<br>- marshallObject(ice.getValue(), out, refMap);<br>- if (ice.canExpire()) {<br>- out.writeBoolean(true);<br>- writeUnsignedLong(out, ice.getCreated());<br>- out.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs<br>- writeUnsignedLong(out, ice.getLastUsed());<br>- out.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs<br>- } else {<br>- out.writeBoolean(false);<br>- }<br>+ marshallInternalCacheEntry((InternalCacheEntry) o, out, refMap);<br>+ } else if (o instanceof InternalCacheValue) {<br>+ marshallInternalCacheValue((InternalCacheValue) o, out, refMap);<br> } else if (o.getClass().equals(ArrayList.class)) {<br> out.writeByte(MAGICNUMBER_ARRAY_LIST);<br> marshallCollection((Collection) o, out, refMap);<br>@@ -252,7 +256,65 @@<br> }<br> }<br><br>+ private void marshallInternalCacheEntry(InternalCacheEntry ice, ObjectOutput out, Map<Object, Integer> refMap) throws IOException {<br>+ if (ice.getClass().equals(ImmortalCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICE_IMMORTAL);<br>+ marshallObject(ice.getKey(), out, refMap);<br>+ marshallObject(ice.getValue(), out, refMap);<br><br>+ } else if (ice.getClass().equals(MortalCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICE_MORTAL);<br>+ marshallObject(ice.getKey(), out, refMap);<br>+ marshallObject(ice.getValue(), out, refMap);<br>+ writeUnsignedLong(out, ice.getCreated());<br>+ out.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs<br>+<br>+ } else if (ice.getClass().equals(TransientCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICE_TRANSIENT);<br>+ marshallObject(ice.getKey(), out, refMap);<br>+ marshallObject(ice.getValue(), out, refMap);<br>+ writeUnsignedLong(out, ice.getLastUsed());<br>+ out.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs<br>+<br>+ } else if (ice.getClass().equals(TransientMortalCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICE_TRANSIENT_MORTAL);<br>+ marshallObject(ice.getKey(), out, refMap);<br>+ marshallObject(ice.getValue(), out, refMap);<br>+ writeUnsignedLong(out, ice.getCreated());<br>+ out.writeLong(ice.getLifespan()); // could be negative so should not use unsigned longs<br>+ writeUnsignedLong(out, ice.getLastUsed());<br>+ out.writeLong(ice.getMaxIdle()); // could be negative so should not use unsigned longs<br>+ }<br>+ }<br>+<br>+ private void marshallInternalCacheValue(InternalCacheValue icv, ObjectOutput out, Map<Object, Integer> refMap) throws IOException {<br>+ if (icv.getClass().equals(ImmortalCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICV_IMMORTAL);<br>+ marshallObject(icv.getValue(), out, refMap);<br>+<br>+ } else if (icv.getClass().equals(MortalCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICV_MORTAL);<br>+ marshallObject(icv.getValue(), out, refMap);<br>+ writeUnsignedLong(out, icv.getCreated());<br>+ out.writeLong(icv.getLifespan()); // could be negative so should not use unsigned longs<br>+<br>+ } else if (icv.getClass().equals(TransientCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICV_TRANSIENT);<br>+ marshallObject(icv.getValue(), out, refMap);<br>+ writeUnsignedLong(out, icv.getLastUsed());<br>+ out.writeLong(icv.getMaxIdle()); // could be negative so should not use unsigned longs<br>+<br>+ } else if (icv.getClass().equals(TransientMortalCacheEntry.class)) {<br>+ out.writeByte(MAGICNUMBER_ICV_TRANSIENT_MORTAL);<br>+ marshallObject(icv.getValue(), out, refMap);<br>+ writeUnsignedLong(out, icv.getCreated());<br>+ out.writeLong(icv.getLifespan()); // could be negative so should not use unsigned longs<br>+ writeUnsignedLong(out, icv.getLastUsed());<br>+ out.writeLong(icv.getMaxIdle()); // could be negative so should not use unsigned longs<br>+ }<br>+ }<br>+<br>+<br> protected void marshallString(String s, ObjectOutput out) throws IOException {<br> //StringUtil.saveString(out, s);<br> out.writeObject(s);<br>@@ -385,19 +447,16 @@<br> MarshalledValue mv = new MarshalledValue();<br> mv.readExternal(in);<br> return mv;<br>- case MAGICNUMBER_INTERNAL_CACHED_ENTRY:<br>- Object k = unmarshallObject(in, refMap);<br>- Object v = unmarshallObject(in, refMap);<br>- boolean canExpire = in.readBoolean();<br>- if (canExpire) {<br>- long created = readUnsignedLong(in);<br>- long lifespan = in.readLong(); // could be negative so should not use unsigned longs<br>- long lastUsed = readUnsignedLong(in);<br>- long maxIdle = in.readLong(); // could be negative so should not use unsigned longs<br>- return InternalEntryFactory.create(k, v, created, lifespan, lastUsed, maxIdle);<br>- } else {<br>- return InternalEntryFactory.create(k, v);<br>- }<br>+ case MAGICNUMBER_ICE_IMMORTAL:<br>+ case MAGICNUMBER_ICE_MORTAL:<br>+ case MAGICNUMBER_ICE_TRANSIENT:<br>+ case MAGICNUMBER_ICE_TRANSIENT_MORTAL:<br>+ return unmarshallInternalCacheEntry(magicNumber, in, refMap);<br>+ case MAGICNUMBER_ICV_IMMORTAL:<br>+ case MAGICNUMBER_ICV_MORTAL:<br>+ case MAGICNUMBER_ICV_TRANSIENT:<br>+ case MAGICNUMBER_ICV_TRANSIENT_MORTAL:<br>+ return unmarshallInternalCacheValue(magicNumber, in, refMap);<br> case MAGICNUMBER_REQUEST_IGNORED_RESPONSE:<br> case MAGICNUMBER_EXTENDED_RESPONSE:<br> case MAGICNUMBER_EXCEPTION_RESPONSE:<br>@@ -465,6 +524,49 @@<br> throw new IOException("Unknown magic number " + magicNumber);<br> }<br><br>+ private InternalCacheEntry unmarshallInternalCacheEntry(byte magic, ObjectInput in, UnmarshalledReferences refMap) throws IOException, ClassNotFoundException {<br>+ Object k = unmarshallObject(in, refMap);<br>+ Object v = unmarshallObject(in, refMap);<br>+ switch (magic) {<br>+ case MAGICNUMBER_ICE_IMMORTAL:<br>+ return InternalEntryFactory.create(k, v);<br>+ case MAGICNUMBER_ICE_MORTAL:<br>+ return InternalEntryFactory.create(k, v,<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap),<br>+ -1, -1);<br>+ case MAGICNUMBER_ICE_TRANSIENT:<br>+ return InternalEntryFactory.create(k, v,<br>+ -1, -1,<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap));<br>+ case MAGICNUMBER_ICE_TRANSIENT_MORTAL:<br>+ return InternalEntryFactory.create(k, v,<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap),<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap));<br>+ }<br>+ throw new IllegalArgumentException("Unknown magic number " + magic);<br>+ }<br>+<br>+ private InternalCacheValue unmarshallInternalCacheValue(byte magic, ObjectInput in, UnmarshalledReferences refMap) throws IOException, ClassNotFoundException {<br>+ Object v = unmarshallObject(in, refMap);<br>+ switch (magic) {<br>+ case MAGICNUMBER_ICE_IMMORTAL:<br>+ return InternalEntryFactory.createValue(v);<br>+ case MAGICNUMBER_ICE_MORTAL:<br>+ return InternalEntryFactory.createValue(v,<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap),<br>+ -1, -1);<br>+ case MAGICNUMBER_ICE_TRANSIENT:<br>+ return InternalEntryFactory.createValue(v,<br>+ -1, -1,<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap));<br>+ case MAGICNUMBER_ICE_TRANSIENT_MORTAL:<br>+ return InternalEntryFactory.createValue(v,<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap),<br>+ readUnsignedLong(in), (Long) unmarshallObject(in, refMap));<br>+ }<br>+ throw new IllegalArgumentException("Unknown magic number " + magic);<br>+ }<br>+<br> private FastCopyHashMap unmarshallFastCopyHashMap(ObjectInput in, UnmarshalledReferences refMap) throws IOException, ClassNotFoundException {<br> FastCopyHashMap map = new FastCopyHashMap();<br> populateFromStream(in, refMap, map);<br><br>_______________________________________________<br>infinispan-commits mailing list<br><a href="mailto:infinispan-commits@lists.jboss.org">infinispan-commits@lists.jboss.org</a><br>https://lists.jboss.org/mailman/listinfo/infinispan-commits<br></div></blockquote></div><br><div apple-content-edited="true"> <span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>--</div><div>Manik Surtani</div><div><a href="mailto:manik@jboss.org">manik@jboss.org</a></div><div>Lead, Infinispan</div><div>Lead, JBoss Cache</div><div><a href="http://www.infinispan.org">http://www.infinispan.org</a></div><div><a href="http://www.jbosscache.org">http://www.jbosscache.org</a></div><div><br></div></div></span><br class="Apple-interchange-newline"></div></span><br class="Apple-interchange-newline"> </div><br></div></div></body></html>