apache-ignite

Форк
0
/
cpp-platform-interoperability.adoc 
249 строк · 7.6 Кб
1
// Licensed to the Apache Software Foundation (ASF) under one or more
2
// contributor license agreements.  See the NOTICE file distributed with
3
// this work for additional information regarding copyright ownership.
4
// The ASF licenses this file to You under the Apache License, Version 2.0
5
// (the "License"); you may not use this file except in compliance with
6
// the License.  You may obtain a copy of the License at
7
//
8
// http://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
= Ignite.C++ and Platform Interoperability
16

17
== Overview
18

19
When using Apache Ignite C++, it is quite common to have several C++ and Java nodes running in a single cluster. To seamlessly
20
interoperate between C++ and Java nodes, you need to take several aspects into consideration. Let's review them.
21

22
== Binary Marshaller Configuration
23

24
Ignite uses its binary marshaller for data, logic, messages serialization and deserialization. Due to architectural specificities,
25
Java and C++ nodes are started with different default settings of the binary marshaller that can lead to exceptions like
26
 the one below during a node startup if you try to set up a heterogeneous cluster:
27

28
[tabs]
29
--
30
tab:Java[]
31
[source,java]
32
----
33
class org.apache.ignite.spi.IgniteSpiException: Local node's
34
binary configuration is not equal to remote node's binary configuration
35
[locNodeId=b3f0367d-3c2b-47b4-865f-a62c656b5d3f,
36
rmtNodeId=556a3f41-eab1-4d9f-b67c-d94d77ddd89d,
37
locBinaryCfg={globIdMapper=org.apache.ignite.binary.BinaryBasicIdMapper,
38
compactFooter=false, globSerializer=null}, rmtBinaryCfg=null]
39
----
40
--
41

42
To avoid the exception and to make sure Java and C++ nodes can co-exist in a single cluster, add the following binary
43
marshaller's settings to the Java configuration:
44

45
[tabs]
46
--
47
tab:XML[]
48
[source,xml]
49
----
50
<?xml version="1.0" encoding="UTF-8"?>
51

52
<beans xmlns="http://www.springframework.org/schema/beans"
53
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
54
       xsi:schemaLocation="http://www.springframework.org/schema/beans
55
        http://www.springframework.org/schema/beans/spring-beans.xsd">
56

57
    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
58
        ...
59
        <property name="binaryConfiguration">
60
            <bean class="org.apache.ignite.configuration.BinaryConfiguration">
61
                <property name="compactFooter" value="false"/>
62

63
                <property name="idMapper">
64
                    <bean class="org.apache.ignite.binary.BinaryBasicIdMapper">
65
                        <property name="lowerCase" value="true"/>
66
                    </bean>
67
                </property>
68
            </bean>
69
        </property>
70
        ...
71
    </bean>
72
</beans>
73
----
74
--
75

76
== Basic Types Compatibility
77

78
Your C++ application can put a value into the cluster and another Java application can read it back. The table below
79
shows how the types are matched between Java and C++:
80

81
[opts="header"]
82
|===
83
|Java Type | C++ Type
84

85
| `boolean`, `java.lang.Boolean`| `bool`
86
| `byte`, `java.lang.Byte`| `int8_t`
87
| `short`, `java.lang.Short`| `int16_t`
88
| `int`, `java.lang.Integer`| `int32_t`
89
| `long`, `java.lang.Long`| `int64_t`
90
| `float`, `java.lang.Float`| `float`
91
| `double`, `java.lang.Double`| `double`
92
| `char`, `java.lang.Character`| `uint16_t`
93
| `java.lang.String`| `std::string`, `char[]`
94
| `java.util.Date`| `ignite::Date`
95
| `java.sql.Time`| `ignite::Time`
96
| `java.sql.Timestamp`| `ignite::Timestamp`
97
| `java.util.UUID`| `ignite::Guid`
98
|===
99

100
== Custom Types Compatibility
101

102
To get access to the same application-specific object on both Java and C++ nodes, you need to describe it similarly in
103
both the languages. This includes the same type name, type id, fields id, hash code algorithm, as well as read/write functions
104
for the type.
105

106
To do this on the C++ end, you need to use the `ignite::binary::BinaryType` class template.
107

108
Let's consider the following example that defines a Java class that will be later read by a C++ application:
109

110
[tabs]
111
--
112
tab:Java[]
113
[source,java]
114
----
115
package org.apache.ignite.examples;
116

117
public class CrossClass implements Binarylizable {
118
    private long id;
119

120
    private int idPart;
121

122
    public void readBinary(BinaryReader reader) throws BinaryObjectException {
123
        id = reader.readLong("id");
124
        idPart = reader.readInt("idPart");
125
    }
126

127
    public void writeBinary(BinaryWriter writer) throws BinaryObjectException {
128
        writer.writeLong("id", id);
129
        writer.writeInt("idPart", idPart);
130
    }
131
}
132
----
133
--
134

135
Next, you create a counter-part on the C++ end:
136

137
[tabs]
138
--
139
tab:C++[]
140
[source,cpp]
141
----
142
namespace ignite
143
{
144
  namespace binary
145
  {
146
    template<>
147
    struct BinaryType<CrossClass>
148
    {
149
      static int32_t GetTypeId()
150
      {
151
        return GetBinaryStringHashCode("CrossClass");
152
      }
153

154
      static void GetTypeName(std::string& name)
155
      {
156
        name = "CrossClass";
157
      }
158

159
      static int32_t GetFieldId(const char* name)
160
      {
161
        return GetBinaryStringHashCode(name);
162
      }
163

164
      static bool IsNull(const CrossClass& obj)
165
      {
166
        return false;
167
      }
168

169
      static void GetNull(CrossClass& dst)
170
      {
171
        dst = CrossClass();
172
      }
173

174
      static void Read(BinaryReader& reader, CrossClass& dst)
175
      {
176
        dst.id = reader.ReadInt64("id");
177
        dst.idPart = reader.ReadInt32("idPart");
178
      }
179

180
      static void Write(BinaryWriter& writer, const CrossClass& obj)
181
      {
182
        writer.WriteInt64("id", obj.id);
183
        writer.WriteInt32("idPart", obj.idPart);
184
      }
185
    };
186
  }
187
}
188
----
189
--
190

191
Finally, you need to use the following `BinaryConfiguration` for **both** Java and C++ nodes:
192

193
[tabs]
194
--
195
tab:XML[]
196
[source,xml]
197
----
198
<?xml version="1.0" encoding="UTF-8"?>
199

200
<beans xmlns="http://www.springframework.org/schema/beans"
201
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
202
       xsi:schemaLocation="http://www.springframework.org/schema/beans
203
        http://www.springframework.org/schema/beans/spring-beans.xsd">
204

205
    <bean id="ignite.cfg" class="org.apache.ignite.configuration.IgniteConfiguration">
206
        ...
207
        <property name="binaryConfiguration">
208
            <bean class="org.apache.ignite.configuration.BinaryConfiguration">
209
                <property name="compactFooter" value="false"/>
210

211
                <property name="idMapper">
212
                    <bean class="org.apache.ignite.binary.BinaryBasicIdMapper">
213
                        <property name="lowerCase" value="true"/>
214
                    </bean>
215
                </property>
216

217
                <property name="nameMapper">
218
                    <bean class="org.apache.ignite.binary.BinaryBasicNameMapper">
219
                        <property name="simpleName" value="true"/>
220
                    </bean>
221
                </property>
222

223
                <property name="classNames">
224
                    <list>
225
                        <value>org.apache.ignite.examples.CrossClass</value>
226
                    </list>
227
                </property>
228
            </bean>
229
        </property>
230
        ...
231
    </bean>
232
</beans>
233
----
234
--
235

236
[CAUTION]
237
====
238
[discrete]
239
It is especially important to implement `GetTypeName()` and `GetTypeId()` methods in the right manner for the types that
240
are used for the keys.
241
====
242

243
[CAUTION]
244
====
245
[discrete]
246
C++ function `GetBinaryStringHashCode()` always calculates hash as `BinaryBasicIdMapper` when its property `lowerCase` is set
247
to `true`. So make sure you have the correct configuration for the `BinaryBasicIdMapper` if you are going to use this
248
function to calculate the type id in C++.
249
====
250

251

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.