Summary: Using Externalizable to boost remote space performance operations.
OverviewTo solve the performance problems associated with a class serialization, the serialization mechanism allows you to declare that a class is Externalizable. When the ObjectOutputStream writeObject() method is called, it performs the following sequence of actions:
Externalizable is an interface that consists of two methods: public void readExternal(ObjectInput in); public void writeExternal(ObjectOutput out); The Externalization mechanism writes out the identity of the class (which boils down to the name of the class and the appropriate serialVersionUID). It also stores the superclass structure and all the information about the class hierarchy. But instead of visiting each superclass and using it to store some of the state information, it simply calls writeExternal() on the local class definition. When using a POJO class with the space API, you may implement the Externalizable mechanism. This can be done to control serialization and deserialization when the Object is sent to the space (e.g. write, update and execute Operations) and when it is sent back to the client (e.g. read and take operations). This will optimize the remote call when using Remote Space configuration for single, partitioned, and replicated space topologies Space Runtime Modes.
ExampleSpace Domain POJO Message ClassHere is a simple POJO class:
Message
package com.j_spaces.examples.benchmark; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import com.gigaspaces.annotation.pojo.SpaceClass; import com.gigaspaces.annotation.pojo.SpaceId; import com.gigaspaces.annotation.pojo.SpaceProperty; import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType; @SpaceClass public class Message { private static final long serialVersionUID = 1L; private byte[] content; private Long counter; private ArrayList<GregorianCalendar> list; public byte[] getContent() { return content; } public void setContent(byte[] content) { this.content = content; generateData(10); } @SpaceProperty(index=IndexType.BASIC) Long getCounter() { return counter; } public void setCounter(Long counter) { this.counter = counter; } public ArrayList<GregorianCalendar> getList() { return list; } public void setList(ArrayList<GregorianCalendar> list) { this.list = list; } public Message () { } public Message (long initVal, byte[] content) { content = content; counter = initVal; if (content !=null) generateData(10); } public void generateData(int capacity) { if (capacity > 0) { list = new ArrayList<GregorianCalendar>(capacity); for (int i = 0; i < capacity; i++) { int year = (int) (Math.random() * 2000); int month = (int) (Math.random() * 12); int day = (int) (Math.random() * 31); list.add(i, new GregorianCalendar(year, month, day)); } } } @Override public String toString() { return getClass() + "_" + counter + "_" + content; } } Space Domain POJO Message Class Implements ExternalizableHere is the same class with the Externalizable interface implemented.
Message
package com.j_spaces.examples.benchmark; import java.io.Externalizable; import java.io.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import com.gigaspaces.annotation.pojo.SpaceClass; import com.gigaspaces.annotation.pojo.SpaceId; import com.gigaspaces.annotation.pojo.SpaceProperty; import com.gigaspaces.annotation.pojo.SpaceProperty.IndexType; @SpaceClass public class Message implements Externalizable { private static final long serialVersionUID = 1L; private byte[] content; private Long counter; private ArrayList<GregorianCalendar> list; public byte[] getContent() { return content; } public void setContent(byte[] content) { this.content = content; generateData(10); } @SpaceProperty(index=IndexType.BASIC) Long getCounter() { return counter; } public void setCounter(Long counter) { this.counter = counter; } public ArrayList<GregorianCalendar> getList() { return list; } public void setList(ArrayList<GregorianCalendar> list) { this.list = list; } public Message() { } public Message(long initVal, byte[] content) { content = content; counter = initVal; if (content !=null) generateData(10); } public void writeExternal(ObjectOutput out) throws IOException { if (counter == null) out.writeLong(0); else out.writeLong(counter); if (content != null ) { out.writeInt(content.length); out.write(content ,0, content.length); } else { out.writeInt(0); } if (list != null) { out.writeBoolean(true); out.writeInt(list.size()); for (GregorianCalendar date : list) { out.writeInt(date.get(Calendar.YEAR)); out.writeInt(date.get(Calendar.MONTH)); out.writeInt(date.get(Calendar.DAY_OF_MONTH)); } } else { out.writeBoolean(false); } } public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { counter = (Long) in.readLong(); Integer content_length =in.readInt(); if (content_length >0) { content = new byte[content_length.intValue()]; in.read(content, 0 , content_length.intValue()); } boolean islist = in.readBoolean(); if (islist ) { int capacity = (Integer) in.readInt(); list = new ArrayList<GregorianCalendar>(capacity); for (int i = 0; i < capacity; i++) { int year = in.readInt(); int month = in.readInt(); int day = in.readInt(); list.add(i, new GregorianCalendar(year, month, day)); } } } public void generateData(int capacity) { if (capacity > 0) { list = new ArrayList<GregorianCalendar>(capacity); for (int i = 0; i < capacity; i++) { int year = (int) (Math.random() * 2000); int month = (int) (Math.random() * 12); int day = (int) (Math.random() * 31); list.add(i, new GregorianCalendar(year, month, day)); } } } @Override public String toString() { return getClass() + "_" + counter + "_" + content; } } Performance Tests Results |
![]() |
GigaSpaces.com - Legal Notice - 3rd Party Licenses - Site Map - API Docs - Forum - Downloads - Blog - White Papers - Contact Tech Writing - Gen. by Atlassian Confluence |