# ignite-496
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/227220ae Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/227220ae Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/227220ae Branch: refs/heads/ignite-496 Commit: 227220ae68376f08c5eb7ecf668d8d25902f80ba Parents: 987cf05 Author: sboikov <semen.boi...@inria.fr> Authored: Tue Mar 17 23:43:19 2015 +0300 Committer: sboikov <semen.boi...@inria.fr> Committed: Tue Mar 17 23:43:19 2015 +0300 ---------------------------------------------------------------------- .../processors/interop/InteropProcessor.java | 13 +- .../processors/interop/InteropUtils.java | 36 +++ .../ignite-interop-api/ignite-interop-api.cpp | 134 +++++++++- .../ignite-interop-api/ignite-interop-api.h | 258 ++++++++++++++++++- .../ignite-interop-cpp-prototype.cpp | 13 + .../ignite-interop-cpp-prototype.vcxproj | 4 +- .../main/cpp/ignite-interop/ignite-interop.sln | 5 +- 7 files changed, 440 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropProcessor.java index fe2d419b5..d47ad9d 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropProcessor.java @@ -37,7 +37,18 @@ public class InteropProcessor extends GridProcessorAdapter { /** {@inheritDoc} */ public InteropMarshaller marshaller() { - return new TestInteropMarshaller(); + return new InteropMarshaller() { + @Override public void writeObject(Object obj, InteropOutputStream out) { + if (obj == null) + obj = 0; + + out.writeInt((Integer)obj); + } + + @Override public Object readObject(InteropInputStream in) { + return in.readInt(); + } + }; } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropUtils.java new file mode 100644 index 0000000..7323673 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/interop/InteropUtils.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.processors.interop; + +import org.apache.ignite.*; +import org.apache.ignite.internal.*; + +/** + * + */ +public class InteropUtils { + /** + * @param ignite Ignite. + * @return Interop processor. + */ + public static InteropProcessor interop(Ignite ignite) { + GridKernalContext ctx = ((IgniteKernal)ignite).context(); + + return ctx.interop(); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.cpp ---------------------------------------------------------------------- diff --git a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.cpp b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.cpp index 8af5b26..6975ca4 100644 --- a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.cpp +++ b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.cpp @@ -58,6 +58,9 @@ JniMethod M_IGNITION_IGNITE = JniMethod("ignite", "(Ljava/lang/String;)Lorg/apac const char* C_IGNITION_EX = "org/apache/ignite/internal/IgnitionEx"; JniMethod M_IGNITION_EX_START_WITH_CLO = JniMethod("startWithClosure", "(Ljava/lang/String;Ljava/lang/String;Lorg/apache/ignite/lang/IgniteClosure;)Lorg/apache/ignite/Ignite;", true); +const char* C_INTEROP_UTILS = "org/apache/ignite/internal/processors/interop/InteropUtils"; +JniMethod M_INTEROP_UTILS_INTEROP = JniMethod("interop", "(Lorg/apache/ignite/Ignite;)Lorg/apache/ignite/internal/processors/interop/InteropProcessor;", true); + const char* C_INTEROP_PROCESSOR = "org/apache/ignite/internal/processors/interop/InteropProcessor"; JniMethod M_INTEROP_PROCESSOR_CACHE = JniMethod("cache", "(Ljava/lang/String;)Lorg/apache/ignite/internal/processors/interop/InteropTarget;", false); @@ -65,6 +68,7 @@ const char* C_INTEROP_TARGET = "org/apache/ignite/internal/processors/interop/In JniMethod M_INTEROP_TARGET_IN_OP = JniMethod("inOp", "(IJI)I", false); JniMethod M_INTEROP_TARGET_IN_OUT_OP = JniMethod("inOutOp", "(IJI)J", false); +const char* C_INTEROP_CACHE = "org/apache/ignite/internal/processors/interop/InteropCache"; /* Static context instance. */ JniContext* ctx = new JniContext(); @@ -161,11 +165,45 @@ int ContextInit0(JavaVMInitArgs args, JavaVM** retJvm, JNIEnv** retEnv) { if (!ctx->m_IgnitionEx_startWithClo) return JNI_ERR; - ctx->c_IgniteInteropProcessor = FindClass(env, C_INTEROP_PROCESSOR); + ctx->c_InteropProcessor = FindClass(env, C_INTEROP_PROCESSOR); + + if (!ctx->c_InteropProcessor) + return JNI_ERR; + + ctx->m_InteropProcessor_cache = FindMethod(env, ctx->c_InteropProcessor, M_INTEROP_PROCESSOR_CACHE); + + if (!ctx->m_InteropProcessor_cache) + return JNI_ERR; + + ctx->c_InteropUtils = FindClass(env, C_INTEROP_UTILS); + + if (!ctx->c_InteropUtils) + return JNI_ERR; + + ctx->m_InteropUtils_interop = FindMethod(env, ctx->c_InteropUtils, M_INTEROP_UTILS_INTEROP); + + if (!ctx->m_InteropUtils_interop) + return JNI_ERR; + + ctx->c_InteropTarget = FindClass(env, C_INTEROP_TARGET); + + if (!ctx->c_InteropTarget) + return JNI_ERR; + + ctx->m_InteropTarget_inOp = FindMethod(env, ctx->c_InteropTarget, M_INTEROP_TARGET_IN_OP); + + if (!ctx->m_InteropTarget_inOp) + return JNI_ERR; + + ctx->m_InteropTarget_inOutOp = FindMethod(env, ctx->c_InteropTarget, M_INTEROP_TARGET_IN_OUT_OP); - if (!ctx->c_IgniteInteropProcessor) + if (!ctx->m_InteropTarget_inOutOp) return JNI_ERR; + ctx->c_InteropCache = FindClass(env, C_INTEROP_CACHE); + + if (!ctx->c_InteropCache) + return JNI_ERR; // 4. Register natives. @@ -317,10 +355,25 @@ inline JNIEnv* Attach() { return env; } +inline jobject LocalToGlobal(JNIEnv* env, jobject localRef) { + if (localRef) { + jobject globalRef = env->NewGlobalRef(localRef); + + env->DeleteLocalRef(localRef); // Clear local ref irrespective of result. + + if (!globalRef) + printError(env); + + return globalRef; + } + else + return NULL; +} + IgniteInteropNode::~IgniteInteropNode() { JNIEnv* env = Attach(); - env->DeleteGlobalRef(ignite); + env->DeleteGlobalRef(interop); } @@ -331,11 +384,31 @@ IgniteInteropAbstractTarget::~IgniteInteropAbstractTarget() { } jint IgniteInteropAbstractTarget::inOp(jint type, void* ptr, jint len) { - return 0; + JNIEnv* env = Attach(); + + jint res = env->CallNonvirtualIntMethod(this->obj, this->cls, Context()->m_InteropTarget_inOp, type, ptr, len); + + if (env->ExceptionCheck()) { + printError(env); + + return 0; + } + + return res; } void* IgniteInteropAbstractTarget::inOutOp(jint type, void* ptr, jint len) { - return 0; + JNIEnv* env = Attach(); + + jlong res = env->CallNonvirtualLongMethod(this->obj, this->cls, Context()->m_InteropTarget_inOutOp, type, ptr, len); + + if (env->ExceptionCheck()) { + printError(env); + + return NULL; + } + + return (void*)res; } IGNITE_API_IMPORT_EXPORT IgniteInteropNode* StartNode() { @@ -360,14 +433,59 @@ IGNITE_API_IMPORT_EXPORT IgniteInteropNode* StartNode() { if (env->ExceptionCheck() || !ignite) { printError(env); - return 0; + return NULL; } cout << "Started ignite" << endl; - return new IgniteInteropNode(ignite); + jobject interop = env->CallStaticObjectMethod(Context()->c_InteropUtils, + Context()->m_InteropUtils_interop, + ignite); + + env->DeleteLocalRef(ignite); + + if (env->ExceptionCheck() || !interop) { + printError(env); + + return NULL; + } + + return new IgniteInteropNode(LocalToGlobal(env, interop)); } IgniteInteropCache* IgniteInteropNode::getCache(char* cacheName) { - return 0; + JNIEnv* env = Attach(); + + jstring name0 = cacheName ? env->NewStringUTF(cacheName) : NULL; + + if (env->ExceptionCheck()) { + printError(env); + + return NULL; + } + + jobject cache = env->CallObjectMethod(this->interop, Context()->m_InteropProcessor_cache, name0); + + if (name0) + env->DeleteLocalRef(name0); + + if (!cache) { + printError(env); + + return NULL; + } + + return new IgniteInteropCache(LocalToGlobal(env, cache)); +} + +IgniteInteropCache::IgniteInteropCache(jobject obj) : IgniteInteropAbstractTarget(Context()->c_InteropCache, obj) { + // No-op. +} + +void IgniteInteropCache::put(void* ptr, jint len) { + this->inOp(0, ptr, len); +} + +void* IgniteInteropCache::get(void* ptr, jint len) { + return this->inOutOp(0, ptr, len); } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.h ---------------------------------------------------------------------- diff --git a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.h b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.h index 49b8abc..6435200 100644 --- a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.h +++ b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-api/ignite-interop-api.h @@ -28,6 +28,7 @@ #endif #include <jni.h> +#include <assert.h> /* * Unmanaged context. @@ -36,18 +37,255 @@ struct JniContext { JavaVM* jvm; jclass c_Throwable; - jclass c_Class; - - jclass c_Ignition; - jclass c_IgnitionEx; - jclass c_IgniteInteropProcessor; - jclass c_IgniteInteropCache; - jmethodID m_Throwable_toString; jmethodID m_Throwable_getMessage; + + jclass c_Class; jmethodID m_Class_getName; + + jclass c_Ignition; jmethodID m_Ignition_ignite; + + jclass c_IgnitionEx; jmethodID m_IgnitionEx_startWithClo; + + jclass c_InteropUtils; + jmethodID m_InteropUtils_interop; + + jclass c_InteropProcessor; + jmethodID m_InteropProcessor_cache; + + jclass c_InteropTarget; + jmethodID m_InteropTarget_inOp; + jmethodID m_InteropTarget_inOutOp; + + jclass c_InteropCache; +}; + +class InteropByteBuffer { +public: + /** + * @param initialSize Initially allocated size. + */ + InteropByteBuffer(int initialSize) : allocSize(initialSize), pos(0) { + assert(initialSize > 0); + + buffer = reinterpret_cast<char*>(malloc(initialSize)); + } + + /** + * @param byte Value to write. + */ + void writeByte(jbyte byte) { + resizeIfNeeded(1); + + buffer[pos++] = byte; + } + + /** + * @param src Copied memory start. + * @param size Copied memory size. + */ + void insert(const char* src, jint size) { + resizeIfNeeded(size); + + memcpy(buffer + pos, src, size); + + pos += size; + } + + /** + * @param cnt Resize byte count. + */ + void resizeIfNeeded(jint cnt) { + jint newSize = pos + cnt; + + if (newSize > allocSize) { + allocSize *= 2; + + if (newSize > allocSize) + allocSize = newSize; + + buffer = reinterpret_cast<char*>(realloc(buffer, allocSize)); + } + } + + /** + * @return Buffer memory start. + */ + char* data() { + return buffer; + } + + /** + * @return Buffer size. + */ + jint size() { + return pos; + } + + /** + * Sets buffer position to 0. + */ + void reset() { + pos = 0; + } + + /** + * Destructor. + */ + ~InteropByteBuffer() { + free(buffer); + } + +private: + /** */ + char* buffer; + + /** */ + jint allocSize; + + /** */ + jint pos; +}; + +/** +* Little endian primitives output. +*/ +class IGNITE_API_IMPORT_EXPORT InterupOutputStream { +public: + /** + * @param bytes Output vector. + */ + InterupOutputStream(jint cap) : bytes(cap) { + } + + /** + * @param val Value to write. + */ + void writeBool(bool val) { + writeByte(val ? 1 : 0); + } + + /** + * @param val Value to write. + */ + void writeByte(jbyte val) { + bytes.writeByte(val); + } + + /** + * @param val Array to write. + * @param size Array size. + */ + void writeBytes(const void* val, size_t size) { + const char* ptr = reinterpret_cast<const char*>(val); + + bytes.insert(ptr, size); + } + + /** + * @param val Array to write. + * @param size Array size. + */ + void writeBoolArray(const bool* val, jint size) { + for (jint i = 0; i < size; i++) + writeByte(val[i] ? 1 : 0); + } + + /** + * @param val Value to write. + */ + void writeInt16(jshort val) { + char* ptr = reinterpret_cast<char*>(&val); + + bytes.insert(ptr, 2); + } + + /** + * @param val Value to write. + */ + void writeChar(jchar val) { + char* ptr = reinterpret_cast<char*>(&val); + + bytes.insert(ptr, 2); + } + + /** + * @param val Value position. + * @param val Value to write. + */ + void writeInt32To(jint pos, jint val) { + char* ptr = reinterpret_cast<char*>(&val); + + char* dst = reinterpret_cast<char*>(bytes.data()); + + std::copy(ptr, ptr + 4, dst + pos); + } + + /** + * @param val Value position. + * @param val Value to write. + */ + void writeByteTo(jint pos, jbyte val) { + char* dst = reinterpret_cast<char*>(bytes.data()); + + dst[pos] = val; + } + + /** + * @param val Value to write. + */ + void writeInt32(jint val) { + char* ptr = reinterpret_cast<char*>(&val); + + bytes.insert(ptr, 4); + } + + /** + * @param val Value to write. + */ + void writeInt64(jlong val) { + char* ptr = reinterpret_cast<char*>(&val); + + bytes.insert(ptr, 8); + } + + /** + * @param val Value to write. + */ + void writeFloat(float val) { + char* ptr = reinterpret_cast<char*>(&val); + + bytes.insert(ptr, 4); + } + + /** + * @param val Value to write. + */ + void writeDouble(double val) { + char* ptr = reinterpret_cast<char*>(&val); + + bytes.insert(ptr, 8); + } + + /** + * @return Data size. + */ + jint size() { + return bytes.size(); + } + + /** + * @return Data size. + */ + void* data() { + return bytes.data(); + } + +private: + /** */ + InteropByteBuffer bytes; }; class IGNITE_API_IMPORT_EXPORT IgniteInteropAbstractTarget { @@ -60,6 +298,7 @@ protected: public: IgniteInteropAbstractTarget(jclass cls, jobject obj) : cls(cls), obj(obj) { + // No-op. } ~IgniteInteropAbstractTarget(); @@ -80,10 +319,11 @@ public: class IGNITE_API_IMPORT_EXPORT IgniteInteropNode { private: - jobject ignite; + jobject interop; public: - IgniteInteropNode(jobject ignite) : ignite(ignite) { + IgniteInteropNode(jobject interop) : interop(interop) { + // No-op. } ~IgniteInteropNode(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.cpp ---------------------------------------------------------------------- diff --git a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.cpp b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.cpp index 6d905c3..bd4d2b0 100644 --- a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.cpp +++ b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.cpp @@ -33,6 +33,7 @@ private: public: IgniteCache(IgniteInteropCache* interopCache) : interopCache(interopCache) { + // No-op. } ~IgniteCache() { @@ -40,9 +41,21 @@ public: } void put(int key, int val) { + InterupOutputStream out(8); + + out.writeInt32(key); + out.writeInt32(val); + + interopCache->put(out.data(), out.size()); } int get(int key) { + InterupOutputStream out(4); + + out.writeInt32(key); + + interopCache->get(out.data(), out.size()); + return 0; } }; http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.vcxproj ---------------------------------------------------------------------- diff --git a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.vcxproj b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.vcxproj index ba9e1b3..b7d5b0c 100644 --- a/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.vcxproj +++ b/modules/interop/src/main/cpp/ignite-interop/ignite-interop-cpp-prototype/ignite-interop-cpp-prototype.vcxproj @@ -1,5 +1,4 @@ <?xml version="1.0" encoding="utf-8"?> - <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -16,7 +15,6 @@ See the License for the specific language governing permissions and limitations under the License. --> - <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Debug|Win32"> @@ -173,4 +171,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/227220ae/modules/interop/src/main/cpp/ignite-interop/ignite-interop.sln ---------------------------------------------------------------------- diff --git a/modules/interop/src/main/cpp/ignite-interop/ignite-interop.sln b/modules/interop/src/main/cpp/ignite-interop/ignite-interop.sln index 71475cd..3cefee0 100644 --- a/modules/interop/src/main/cpp/ignite-interop/ignite-interop.sln +++ b/modules/interop/src/main/cpp/ignite-interop/ignite-interop.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.30501.0 +VisualStudioVersion = 12.0.21005.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ignite-interop-api", "ignite-interop-api\ignite-interop-api.vcxproj", "{99F02840-F28B-42F3-9530-F8B75F97B682}" EndProject @@ -36,7 +36,8 @@ Global {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Debug|Mixed Platforms.Build.0 = Debug|x64 {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Debug|Win32.ActiveCfg = Debug|Win32 {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Debug|Win32.Build.0 = Debug|Win32 - {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Debug|x64.ActiveCfg = Debug|Win32 + {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Debug|x64.ActiveCfg = Debug|x64 + {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Debug|x64.Build.0 = Debug|x64 {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Release|Mixed Platforms.ActiveCfg = Release|Win32 {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Release|Mixed Platforms.Build.0 = Release|Win32 {15376F49-5837-4FBE-9FE4-636A3A0A686C}.Release|Win32.ActiveCfg = Release|Win32