Package org.apache.ignite
Interface IgniteBinary
-
public interface IgniteBinary
Defines binary objects functionality. With binary objects you are able to:- Seamlessly interoperate between Java, .NET, and C++.
- Make any object binary with zero code change to your existing code.
- Nest binary objects within each other.
- Automatically handle
circular
ornull
references. - Automatically convert collections and maps between Java, .NET, and C++.
-
Optionally avoid deserialization of objects on the server side
(objects are stored in
BinaryObject
format). - Avoid need to have concrete class definitions on the server side.
- Dynamically change structure of the classes without having to restart the cluster.
- Index into binary objects for querying purposes.
Working With Binaries Directly
Once an object is defined as binary, Ignite will always store it in memory in the binary (i.e. binary) format. User can choose to work either with the binary format or with the deserialized form (assuming that class definitions are present in the classpath).To work with the binary format directly, user should create a special cache projection using IgniteCache.withKeepBinary() method and then retrieve individual fields as needed:
IgniteCache<BinaryObject, BinaryObject> prj = cache.withKeepBinary(); // Convert instance of MyKey to binary format. // We could also use BinaryBuilder to create the key in binary format directly. BinaryObject key = grid.binary().toBinary(new MyKey()); BinaryObject val = prj.get(key); String field = val.field("myFieldName");
Alternatively, if we have class definitions in the classpath, we may choose to work with deserialized typed objects at all times.IgniteCache<MyKey.class, MyValue.class> cache = grid.cache(null); MyValue val = cache.get(new MyKey()); // Normal java getter. String fieldVal = val.getMyFieldName();
If we used, for example, one of the automatically handled binary types for a key, like integer, and still wanted to work with binary binary format for values, then we would declare cache projection as follows:IgniteCache<Integer.class, BinaryObject> prj = cache.withKeepBinary();
Automatic Binary Types
Note that only binary classes are converted toBinaryObject
format. Following classes are never converted (e.g.,toBinary(Object)
method will return original object, and instances of these classes will be stored in cache without changes):- All primitives (byte, int, ...) and there boxed versions (Byte, Integer, ...)
- Arrays of primitives (byte[], int[], ...)
String
and array ofString
sUUID
and array ofUUID
sDate
and array ofDate
sTimestamp
and array ofTimestamp
s- Enums and array of enums
- Maps, collections and array of objects (but objects inside them will still be converted if they are binary)
Working With Maps and Collections
All maps and collections in the binary objects are serialized automatically. When working with different platforms, e.g. C++ or .NET, Ignite will automatically pick the most adequate collection or map in either language. For example,ArrayList
in Java will becomeList
in C#,LinkedList
in Java isLinkedList
in C#,HashMap
in Java isDictionary
in C#, andTreeMap
in Java becomesSortedDictionary
in C#, etc.Building Binary Objects
Ignite comes withBinaryObjectBuilder
which allows to build binary objects dynamically:BinaryBuilder builder = Ignition.ignite().binary().builder(); builder.typeId("MyObject"); builder.stringField("fieldA", "A"); build.intField("fieldB", "B"); BinaryObject binaryObj = builder.build();
For the cases when class definition is present in the class path, it is also possible to populate a standard POJO and then convert it to binary format, like so:MyObject obj = new MyObject(); obj.setFieldA("A"); obj.setFieldB(123); BinaryObject binaryObj = Ignition.ignite().binary().toBinary(obj);
NOTE: you don't need to convert typed objects to binary format before storing them in cache, Ignite will do that automatically.Binary Metadata
Even though Ignite binary protocol only works with hash codes for type and field names to achieve better performance, Ignite provides metadata for all binary types which can be queried ar runtime via any of thetype(Class)
methods. Having metadata also allows for proper formatting ofBinaryObject#toString()
method, even when binary objects are kept in binary format only, which may be necessary for audit reasons.Dynamic Structure Changes
Since objects are always cached in the binary binary format, server does not need to be aware of the class definitions. Moreover, if class definitions are not present or not used on the server, then clients can continuously change the structure of the binary objects without having to restart the cluster. For example, if one client stores a certain class with fields A and B, and another client stores the same class with fields B and C, then the server-side binary object will have the fields A, B, and C. As the structure of a binary object changes, the new fields become available for SQL queries automatically.Configuration
By default all your objects are considered as binary and no specific configuration is needed. The only requirement Ignite imposes is that your object has an empty constructor. Note, that since server side does not have to know the class definition, you only need to list binary objects in configuration on the client side. However, if you list them on the server side as well, then you get the ability to deserialize binary objects into concrete types on the server as well as on the client.Here is an example of binary configuration (note that star (*) notation is supported):
... <!-- Explicit binary objects configuration. --> <property name="marshaller"> <bean class="org.apache.ignite.marshaller.binary.BinaryMarshaller"> <property name="classNames"> <list> <value>my.package.for.binary.objects.*</value> <value>org.apache.ignite.examples.client.binary.Employee</value> </list> </property> </bean> </property> ...
or from code:IgniteConfiguration cfg = new IgniteConfiguration(); BinaryMarshaller marsh = new BinaryMarshaller(); marsh.setClassNames(Arrays.asList( Employee.class.getName(), Address.class.getName()) ); cfg.setMarshaller(marsh);
You can also specify class name for a binary object viaBinaryTypeConfiguration
. Do it in case if you need to override other configuration properties on per-type level, like ID-mapper, or serializer.Custom Affinity Keys
Often you need to specify an alternate key (not the cache key) for affinity routing whenever storing objects in cache. For example, if you are cachingEmployee
object withOrganization
, and want to colocate employees with organization they work for, so you can process them together, you need to specify an alternate affinity key. With binary objects you would have to do it as following:<property name="marshaller"> <bean class="org.gridgain.grid.marshaller.binary.BinaryMarshaller"> ... <property name="typeConfigurations"> <list> <bean class="org.apache.ignite.binary.BinaryTypeConfiguration"> <property name="className" value="org.apache.ignite.examples.client.binary.EmployeeKey"/> <property name="affinityKeyFieldName" value="organizationId"/> </bean> </list> </property> ... </bean> </property>
Serialization
Serialization and deserialization works out-of-the-box in Ignite. However, you can provide your own custom serialization logic by optionally implementingBinarylizable
interface, like so:public class Address implements BinaryMarshalAware { private String street; private int zip; // Empty constructor required for binary deserialization. public Address() {} @Override public void writeBinary(BinaryWriter writer) throws BinaryException { writer.writeString("street", street); writer.writeInt("zip", zip); } @Override public void readBinary(BinaryReader reader) throws BinaryException { street = reader.readString("street"); zip = reader.readInt("zip"); } }
Alternatively, if you cannot change class definitions, you can provide custom serialization logic inBinarySerializer
either globally inBinaryConfiguration
or for a specific type viaBinaryTypeConfiguration
instance.Similar to java serialization you can use
writeReplace()
andreadResolve()
methods.-
readResolve
is defined as follows:ANY-ACCESS-MODIFIER Object readResolve()
. It may be used to replace the de-serialized object by another one of your choice. -
writeReplace
is defined as follows:ANY-ACCESS-MODIFIER Object writeReplace()
. This method allows the developer to provide a replacement object that will be serialized instead of the original one.
Custom ID Mappers
Ignite implementation uses name hash codes to generate IDs for class names or field names internally. However, in cases when you want to provide your own ID mapping schema, you can provide your ownBinaryIdMapper
implementation.ID-mapper may be provided either globally in
BinaryConfiguration
, or for a specific type viaBinaryTypeConfiguration
instance.Query Indexing
Binary objects can be indexed for querying by specifying index fields inQueryEntity
inside of specificCacheConfiguration
instance, like so:... <bean class="org.apache.ignite.cache.CacheConfiguration"> ... <property name="queryEntities"> <list> <bean class="QueryEntity"> <property name="type" value="Employee"/> <!-- Fields available from query. --> <property name="fields"> <map> <entry key="name" value="java.lang.String"/> <!-- Nested binary objects can also be indexed. --> <entry key="address.zip" value="java.lang.Integer" /> </map> </property> <!-- Aliases for full property name in dot notation. --> <property name="fields"> <map> <entry key="address.zip" value="zip" /> </map> </property> <!-- Indexes configuration. --> <property name="indexes"> <list> <bean class="org.apache.ignite.cache.QueryIndex"> <property name="fields"> <map> <!-- The boolean value is the acceding flag. --> <entry key="name" value="true"/> </map> </property> </bean> </list> </property> </bean> </list> </property> </bean>
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description BinaryObject
buildEnum(String typeName, int ord)
Create enum object using value.BinaryObject
buildEnum(String typeName, String name)
Create enum object using name.BinaryObjectBuilder
builder(String typeName)
Creates new binary builder.BinaryObjectBuilder
builder(BinaryObject binaryObj)
Creates binary builder initialized by existing binary object.BinaryType
registerClass(Class<?> cls)
Register binary type for specified class.BinaryType
registerEnum(String typeName, Map<String,Integer> vals)
Register enum type.<T> T
toBinary(@Nullable Object obj)
Converts provided object to instance ofBinaryObject
.BinaryType
type(int typeId)
Gets metadata for provided type ID.BinaryType
type(Class<?> cls)
Gets metadata for provided class.BinaryType
type(String typeName)
Gets metadata for provided class name.int
typeId(@NotNull String typeName)
Gets type ID for given type name.Collection<BinaryType>
types()
Gets metadata for all known types.
-
-
-
Method Detail
-
typeId
int typeId(@NotNull @NotNull String typeName)
Gets type ID for given type name. If no user definedBinaryIdMapper
is configured viaBinaryConfiguration
, then system mapper will be used.- Parameters:
typeName
- Type name.- Returns:
- Type ID which a type would have had if it has been registered in Ignite.
-
toBinary
<T> T toBinary(@Nullable @Nullable Object obj) throws BinaryObjectException
Converts provided object to instance ofBinaryObject
.- Type Parameters:
T
- Type of the binary object.- Parameters:
obj
- Object to convert.- Returns:
- Converted object or
null
if obj is null. - Throws:
BinaryObjectException
- In case of error.
-
builder
BinaryObjectBuilder builder(String typeName) throws BinaryObjectException
Creates new binary builder.- Parameters:
typeName
- Type name.- Returns:
- Newly binary builder.
- Throws:
BinaryObjectException
- In case of error.
-
builder
BinaryObjectBuilder builder(BinaryObject binaryObj) throws BinaryObjectException
Creates binary builder initialized by existing binary object.- Parameters:
binaryObj
- Binary object to initialize builder.- Returns:
- Binary builder.
- Throws:
BinaryObjectException
-
type
BinaryType type(Class<?> cls) throws BinaryObjectException
Gets metadata for provided class.- Parameters:
cls
- Class.- Returns:
- Metadata.
- Throws:
BinaryObjectException
- In case of error.
-
type
BinaryType type(String typeName) throws BinaryObjectException
Gets metadata for provided class name.- Parameters:
typeName
- Type name.- Returns:
- Metadata.
- Throws:
BinaryObjectException
- In case of error.
-
type
BinaryType type(int typeId) throws BinaryObjectException
Gets metadata for provided type ID.- Parameters:
typeId
- Type ID.- Returns:
- Metadata.
- Throws:
BinaryObjectException
- In case of error.
-
types
Collection<BinaryType> types() throws BinaryObjectException
Gets metadata for all known types.- Returns:
- Metadata.
- Throws:
BinaryObjectException
- In case of error.
-
buildEnum
BinaryObject buildEnum(String typeName, int ord) throws BinaryObjectException
Create enum object using value.- Parameters:
typeName
- Type name.ord
- Ordinal.- Returns:
- Enum object.
- Throws:
BinaryObjectException
- In case of error.
-
buildEnum
BinaryObject buildEnum(String typeName, String name) throws BinaryObjectException
Create enum object using name.- Parameters:
typeName
- Type name.name
- Name.- Returns:
- Enum object.
- Throws:
BinaryObjectException
- In case of error.
-
registerEnum
BinaryType registerEnum(String typeName, Map<String,Integer> vals) throws BinaryObjectException
Register enum type.- Parameters:
typeName
- Type name.vals
- Mapping of enum constant names to ordinals.- Returns:
- Binary type for registered enum.
- Throws:
BinaryObjectException
- In case of error.
-
registerClass
BinaryType registerClass(Class<?> cls) throws BinaryObjectException
Register binary type for specified class.- Parameters:
cls
- Class.- Returns:
- Metadata.
- Throws:
BinaryObjectException
- In case of error.
-
-