Repository: ignite Updated Branches: refs/heads/ignite-1282 26d9a5383 -> 49c495b9c
IGNITE-1416: Implemneted platform "AtomicLong". Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/49c495b9 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/49c495b9 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/49c495b9 Branch: refs/heads/ignite-1282 Commit: 49c495b9cdf017d91928c7ee5e15387c1e86233e Parents: 26d9a53 Author: Pavel Tupitsyn <[email protected]> Authored: Mon Oct 5 15:51:43 2015 +0300 Committer: vozerov-gridgain <[email protected]> Committed: Mon Oct 5 15:51:43 2015 +0300 ---------------------------------------------------------------------- .../datastructures/GridCacheAtomicLongImpl.java | 26 ++- .../platform/PlatformNoopProcessor.java | 6 + .../processors/platform/PlatformProcessor.java | 11 + .../platform/PlatformProcessorImpl.java | 12 ++ .../datastructures/PlatformAtomicLong.java | 149 ++++++++++++++ .../cpp/common/include/ignite/common/exports.h | 13 ++ .../cpp/common/include/ignite/common/java.h | 27 +++ .../platforms/cpp/common/project/vs/module.def | 14 +- modules/platforms/cpp/common/src/exports.cpp | 48 +++++ modules/platforms/cpp/common/src/java.cpp | 163 +++++++++++++++ modules/platforms/cpp/project/vs/ignite.sln | 7 +- .../Apache.Ignite.Core.Tests.csproj | 2 + .../DataStructures/AtomicLongTest.cs | 138 +++++++++++++ .../Dataload/DataStreamerTest.cs | 2 +- .../Apache.Ignite.Core.Tests/IgniteTestBase.cs | 200 +++++++++++++++++++ .../Apache.Ignite.Core.Tests/TestUtils.cs | 21 +- .../Apache.Ignite.Core.csproj | 2 + .../DataStructures/IAtomicLong.cs | 84 ++++++++ .../dotnet/Apache.Ignite.Core/IIgnite.cs | 16 ++ .../Impl/DataStructures/AtomicLong.cs | 102 ++++++++++ .../dotnet/Apache.Ignite.Core/Impl/Ignite.cs | 15 ++ .../Apache.Ignite.Core/Impl/IgniteProxy.cs | 7 + .../Apache.Ignite.Core/Impl/PlatformTarget.cs | 4 + .../Impl/Portable/PortableWriterImpl.cs | 3 +- .../Impl/Unmanaged/UnmanagedUtils.cs | 104 +++++++++- 25 files changed, 1159 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheAtomicLongImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheAtomicLongImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheAtomicLongImpl.java index 944fc5f..4169e5e 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheAtomicLongImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/datastructures/GridCacheAtomicLongImpl.java @@ -332,7 +332,19 @@ public final class GridCacheAtomicLongImpl implements GridCacheAtomicLongEx, Ext checkRemoved(); try { - return CU.outTx(internalCompareAndSet(expVal, newVal), ctx); + return CU.outTx(internalCompareAndSetAndGet(expVal, newVal) , ctx) == expVal; + } + catch (IgniteCheckedException e) { + throw U.convertException(e); + } + } + + /** {@inheritDoc} */ + public long compareAndSetAndGet(long expVal, long newVal) { + checkRemoved(); + + try { + return CU.outTx(internalCompareAndSetAndGet(expVal, newVal), ctx); } catch (IgniteCheckedException e) { throw U.convertException(e); @@ -509,25 +521,25 @@ public final class GridCacheAtomicLongImpl implements GridCacheAtomicLongEx, Ext } /** - * Method returns callable for execution {@link #compareAndSet(long, long)} + * Method returns callable for execution {@link #compareAndSetAndGet(long, long)} * operation in async and sync mode. * * @param expVal Expected atomic long value. * @param newVal New atomic long value. * @return Callable for execution in async and sync mode. */ - private Callable<Boolean> internalCompareAndSet(final long expVal, final long newVal) { - return new Callable<Boolean>() { - @Override public Boolean call() throws Exception { + private Callable<Long> internalCompareAndSetAndGet(final long expVal, final long newVal) { + return new Callable<Long>() { + @Override public Long call() throws Exception { try (IgniteInternalTx tx = CU.txStartInternal(ctx, atomicView, PESSIMISTIC, REPEATABLE_READ)) { GridCacheAtomicLongValue val = atomicView.get(key); if (val == null) throw new IgniteCheckedException("Failed to find atomic long with given name: " + name); - boolean retVal = val.get() == expVal; + long retVal = val.get(); - if (retVal) { + if (retVal == expVal) { val.set(newVal); atomicView.getAndPut(key, val); http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformNoopProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformNoopProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformNoopProcessor.java index 0f108cf..d49d3e2 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformNoopProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformNoopProcessor.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.platform; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.internal.GridKernalContext; import org.apache.ignite.internal.processors.GridProcessorAdapter; import org.apache.ignite.internal.processors.platform.cache.store.PlatformCacheStore; @@ -122,4 +123,9 @@ public class PlatformNoopProcessor extends GridProcessorAdapter implements Platf throws IgniteCheckedException { // No-op. } + + /** {@inheritDoc} */ + @Override public PlatformTarget atomicLong(String name, long initVal, boolean create) throws IgniteException { + return null; + } } http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java index e1fa891..5c6490f 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessor.java @@ -19,6 +19,7 @@ package org.apache.ignite.internal.processors.platform; import org.apache.ignite.Ignite; import org.apache.ignite.IgniteCheckedException; +import org.apache.ignite.IgniteException; import org.apache.ignite.internal.processors.GridProcessor; import org.apache.ignite.internal.processors.platform.cache.store.PlatformCacheStore; import org.jetbrains.annotations.Nullable; @@ -169,4 +170,14 @@ public interface PlatformProcessor extends GridProcessor { * @throws IgniteCheckedException If failed. */ public void registerStore(PlatformCacheStore store, boolean convertPortable) throws IgniteCheckedException; + + /** + * Get or create AtomicLong. + * @param name Name. + * @param initVal Initial value. + * @param create Create flag. + * @return Platform atomic long. + * @throws IgniteException + */ + public PlatformTarget atomicLong(String name, long initVal, boolean create) throws IgniteException; } http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java index 40b1334..d783928 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/PlatformProcessorImpl.java @@ -30,12 +30,14 @@ import org.apache.ignite.internal.portable.PortableRawWriterEx; import org.apache.ignite.internal.processors.GridProcessorAdapter; import org.apache.ignite.internal.processors.cache.IgniteCacheProxy; import org.apache.ignite.internal.processors.datastreamer.DataStreamerImpl; +import org.apache.ignite.internal.processors.datastructures.GridCacheAtomicLongImpl; import org.apache.ignite.internal.processors.platform.cache.PlatformCache; import org.apache.ignite.internal.processors.platform.cache.affinity.PlatformAffinity; import org.apache.ignite.internal.processors.platform.cache.store.PlatformCacheStore; import org.apache.ignite.internal.processors.platform.cluster.PlatformClusterGroup; import org.apache.ignite.internal.processors.platform.compute.PlatformCompute; import org.apache.ignite.internal.processors.platform.datastreamer.PlatformDataStreamer; +import org.apache.ignite.internal.processors.platform.datastructures.PlatformAtomicLong; import org.apache.ignite.internal.processors.platform.dotnet.PlatformDotNetCacheStore; import org.apache.ignite.internal.processors.platform.events.PlatformEvents; import org.apache.ignite.internal.processors.platform.memory.PlatformMemory; @@ -319,6 +321,16 @@ public class PlatformProcessorImpl extends GridProcessorAdapter implements Platf } } + /** {@inheritDoc} */ + @Override public PlatformTarget atomicLong(String name, long initVal, boolean create) throws IgniteException { + GridCacheAtomicLongImpl atomicLong = (GridCacheAtomicLongImpl)ignite().atomicLong(name, initVal, create); + + if (atomicLong == null) + return null; + + return new PlatformAtomicLong(platformCtx, atomicLong); + } + /** * Internal store initialization routine. * http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastructures/PlatformAtomicLong.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastructures/PlatformAtomicLong.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastructures/PlatformAtomicLong.java new file mode 100644 index 0000000..4a5b2e5 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/platform/datastructures/PlatformAtomicLong.java @@ -0,0 +1,149 @@ +/* + * 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.platform.datastructures; + +import org.apache.ignite.internal.processors.datastructures.GridCacheAtomicLongImpl; +import org.apache.ignite.internal.processors.platform.PlatformAbstractTarget; +import org.apache.ignite.internal.processors.platform.PlatformContext; + +/** + * Platform atomic long wrapper. + */ +public class PlatformAtomicLong extends PlatformAbstractTarget { + /** */ + private final GridCacheAtomicLongImpl atomicLong; + + /** + * Ctor. + * @param ctx Context. + * @param atomicLong AtomicLong to wrap. + */ + public PlatformAtomicLong(PlatformContext ctx, GridCacheAtomicLongImpl atomicLong) { + super(ctx); + + assert atomicLong != null; + + this.atomicLong = atomicLong; + } + + /** + * Reads the value. + * + * @return Current atomic long value. + */ + public long get() { + return atomicLong.get(); + } + + /** + * Increments the value. + * + * @return Current atomic long value. + */ + public long incrementAndGet() { + return atomicLong.incrementAndGet(); + } + + /** + * Increments the value. + * + * @return Original atomic long value. + */ + public long getAndIncrement() { + return atomicLong.getAndIncrement(); + } + + /** + * Adds a value. + * + * @return Current atomic long value. + */ + public long addAndGet(long val) { + return atomicLong.addAndGet(val); + } + + /** + * Adds a value. + * + * @return Original atomic long value. + */ + public long getAndAdd(long val) { + return atomicLong.getAndAdd(val); + } + + /** + * Decrements the value. + * + * @return Current atomic long value. + */ + public long decrementAndGet() { + return atomicLong.decrementAndGet(); + } + + /** + * Decrements the value. + * + * @return Original atomic long value. + */ + public long getAndDecrement() { + return atomicLong.getAndDecrement(); + } + + /** + * Gets current value of atomic long and sets new value + * + * @return Original atomic long value. + */ + public long getAndSet(long val) { + return atomicLong.getAndSet(val); + } + + /** + * Compares two values for equality and, if they are equal, replaces the first value. + * + * @return Original atomic long value. + */ + public long compareAndSetAndGet(long expVal, long newVal) { + return atomicLong.compareAndSetAndGet(expVal, newVal); + } + + /** + * Compares two values for equality and, if they are equal, replaces the first value. + * + * @return Original atomic long value. + */ + public boolean compareAndSet(long cmp, long val) { + return atomicLong.compareAndSet(cmp, val); + } + + /** + * Gets status of atomic. + * + * @return {@code true} if atomic was removed from cache, {@code false} in other case. + */ + public boolean isClosed() { + return atomicLong.removed(); + } + + /** + * Removes this atomic long. + */ + public void close() { + atomicLong.close(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/cpp/common/include/ignite/common/exports.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/include/ignite/common/exports.h b/modules/platforms/cpp/common/include/ignite/common/exports.h index 930fad3..23b9665 100644 --- a/modules/platforms/cpp/common/include/ignite/common/exports.h +++ b/modules/platforms/cpp/common/include/ignite/common/exports.h @@ -44,6 +44,7 @@ extern "C" { void* IGNITE_CALL IgniteProcessorEvents(gcj::JniContext* ctx, void* obj, void* prj); void* IGNITE_CALL IgniteProcessorServices(gcj::JniContext* ctx, void* obj, void* prj); void* IGNITE_CALL IgniteProcessorExtensions(gcj::JniContext* ctx, void* obj); + void* IGNITE_CALL IgniteProcessorAtomicLong(gcj::JniContext* ctx, void* obj, char* name, long long initVal, bool create); long long IGNITE_CALL IgniteTargetInStreamOutLong(gcj::JniContext* ctx, void* obj, int opType, long long memPtr); void IGNITE_CALL IgniteTargetInStreamOutStream(gcj::JniContext* ctx, void* obj, int opType, long long inMemPtr, long long outMemPtr); @@ -140,6 +141,18 @@ extern "C" { void IGNITE_CALL IgniteServicesCancel(gcj::JniContext* ctx, void* obj, char* name); void IGNITE_CALL IgniteServicesCancelAll(gcj::JniContext* ctx, void* obj); void* IGNITE_CALL IgniteServicesGetServiceProxy(gcj::JniContext* ctx, void* obj, char* name, bool sticky); + + long long IGNITE_CALL IgniteAtomicLongGet(gcj::JniContext* ctx, void* obj); + long long IGNITE_CALL IgniteAtomicLongIncrementAndGet(gcj::JniContext* ctx, void* obj); + long long IGNITE_CALL IgniteAtomicLongGetAndIncrement(gcj::JniContext* ctx, void* obj); + long long IGNITE_CALL IgniteAtomicLongAddAndGet(gcj::JniContext* ctx, void* obj, long long value); + long long IGNITE_CALL IgniteAtomicLongGetAndAdd(gcj::JniContext* ctx, void* obj, long long value); + long long IGNITE_CALL IgniteAtomicLongDecrementAndGet(gcj::JniContext* ctx, void* obj); + long long IGNITE_CALL IgniteAtomicLongGetAndDecrement(gcj::JniContext* ctx, void* obj); + long long IGNITE_CALL IgniteAtomicLongGetAndSet(gcj::JniContext* ctx, void* obj, long long value); + long long IGNITE_CALL IgniteAtomicLongCompareAndSetAndGet(gcj::JniContext* ctx, void* obj, long long expVal, long long newVal); + bool IGNITE_CALL IgniteAtomicLongIsClosed(gcj::JniContext* ctx, void* obj); + void IGNITE_CALL IgniteAtomicLongClose(gcj::JniContext* ctx, void* obj); } #endif \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/cpp/common/include/ignite/common/java.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/include/ignite/common/java.h b/modules/platforms/cpp/common/include/ignite/common/java.h index 01ecbe3..2b2abf9 100644 --- a/modules/platforms/cpp/common/include/ignite/common/java.h +++ b/modules/platforms/cpp/common/include/ignite/common/java.h @@ -306,6 +306,7 @@ namespace ignite jmethodID m_PlatformProcessor_events; jmethodID m_PlatformProcessor_services; jmethodID m_PlatformProcessor_extensions; + jmethodID m_PlatformProcessor_atomicLong; jclass c_PlatformTarget; jmethodID m_PlatformTarget_inStreamOutLong; @@ -333,6 +334,19 @@ namespace ignite jmethodID m_PlatformUtils_reallocate; jmethodID m_PlatformUtils_errData; + jclass c_PlatformAtomicLong; + jmethodID m_PlatformAtomicLong_get; + jmethodID m_PlatformAtomicLong_incrementAndGet; + jmethodID m_PlatformAtomicLong_getAndIncrement; + jmethodID m_PlatformAtomicLong_addAndGet; + jmethodID m_PlatformAtomicLong_getAndAdd; + jmethodID m_PlatformAtomicLong_decrementAndGet; + jmethodID m_PlatformAtomicLong_getAndDecrement; + jmethodID m_PlatformAtomicLong_getAndSet; + jmethodID m_PlatformAtomicLong_compareAndSetAndGet; + jmethodID m_PlatformAtomicLong_isClosed; + jmethodID m_PlatformAtomicLong_close; + /** * Constructor. */ @@ -476,6 +490,7 @@ namespace ignite jobject ProcessorEvents(jobject obj, jobject prj); jobject ProcessorServices(jobject obj, jobject prj); jobject ProcessorExtensions(jobject obj); + jobject ProcessorAtomicLong(jobject obj, char* name, long long initVal, bool create); long long TargetInStreamOutLong(jobject obj, int type, long long memPtr, JniErrorInfo* errInfo = NULL); void TargetInStreamOutStream(jobject obj, int opType, long long inMemPtr, long long outMemPtr, JniErrorInfo* errInfo = NULL); @@ -562,6 +577,18 @@ namespace ignite void ServicesCancelAll(jobject obj); void* ServicesGetServiceProxy(jobject obj, char* name, bool sticky); + long long AtomicLongGet(jobject obj); + long long AtomicLongIncrementAndGet(jobject obj); + long long AtomicLongGetAndIncrement(jobject obj); + long long AtomicLongAddAndGet(jobject obj, long long value); + long long AtomicLongGetAndAdd(jobject obj, long long value); + long long AtomicLongDecrementAndGet(jobject obj); + long long AtomicLongGetAndDecrement(jobject obj); + long long AtomicLongGetAndSet(jobject obj, long long value); + long long AtomicLongCompareAndSetAndGet(jobject obj, long long expVal, long long newVal); + bool AtomicLongIsClosed(jobject obj); + void AtomicLongClose(jobject obj); + jobject Acquire(jobject obj); void DestroyJvm(); http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/cpp/common/project/vs/module.def ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/project/vs/module.def b/modules/platforms/cpp/common/project/vs/module.def index d9e8d2b..99cec2d 100644 --- a/modules/platforms/cpp/common/project/vs/module.def +++ b/modules/platforms/cpp/common/project/vs/module.def @@ -96,4 +96,16 @@ IgniteServicesWithServerKeepPortable @93 IgniteServicesCancel @94 IgniteServicesCancelAll @95 IgniteServicesGetServiceProxy @96 -IgniteProcessorExtensions @97 \ No newline at end of file +IgniteProcessorExtensions @97 +IgniteProcessorAtomicLong @98 +IgniteAtomicLongGet @99 +IgniteAtomicLongIncrementAndGet @100 +IgniteAtomicLongGetAndIncrement @101 +IgniteAtomicLongAddAndGet @102 +IgniteAtomicLongGetAndAdd @103 +IgniteAtomicLongDecrementAndGet @104 +IgniteAtomicLongGetAndDecrement @105 +IgniteAtomicLongGetAndSet @106 +IgniteAtomicLongCompareAndSetAndGet @107 +IgniteAtomicLongIsClosed @108 +IgniteAtomicLongClose @109 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/cpp/common/src/exports.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/src/exports.cpp b/modules/platforms/cpp/common/src/exports.cpp index 2ac3340..327719e 100644 --- a/modules/platforms/cpp/common/src/exports.cpp +++ b/modules/platforms/cpp/common/src/exports.cpp @@ -98,6 +98,10 @@ extern "C" { return ctx->ProcessorExtensions(static_cast<jobject>(obj)); } + void* IGNITE_CALL IgniteProcessorAtomicLong(gcj::JniContext* ctx, void* obj, char* name, long long initVal, bool create) { + return ctx->ProcessorAtomicLong(static_cast<jobject>(obj), name, initVal, create); + } + long long IGNITE_CALL IgniteTargetInStreamOutLong(gcj::JniContext* ctx, void* obj, int opType, long long memPtr) { return ctx->TargetInStreamOutLong(static_cast<jobject>(obj), opType, memPtr); } @@ -410,4 +414,48 @@ extern "C" { void* IGNITE_CALL IgniteServicesGetServiceProxy(gcj::JniContext* ctx, void* obj, char* name, bool sticky) { return ctx->ServicesGetServiceProxy(static_cast<jobject>(obj), name, sticky); } + + long long IGNITE_CALL IgniteAtomicLongGet(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongGet(static_cast<jobject>(obj)); + } + + long long IGNITE_CALL IgniteAtomicLongIncrementAndGet(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongIncrementAndGet(static_cast<jobject>(obj)); + } + + long long IGNITE_CALL IgniteAtomicLongGetAndIncrement(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongGetAndIncrement(static_cast<jobject>(obj)); + } + + long long IGNITE_CALL IgniteAtomicLongAddAndGet(gcj::JniContext* ctx, void* obj, long long value) { + return ctx->AtomicLongAddAndGet(static_cast<jobject>(obj), value); + } + + long long IGNITE_CALL IgniteAtomicLongGetAndAdd(gcj::JniContext* ctx, void* obj, long long value) { + return ctx->AtomicLongGetAndAdd(static_cast<jobject>(obj), value); + } + + long long IGNITE_CALL IgniteAtomicLongDecrementAndGet(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongDecrementAndGet(static_cast<jobject>(obj)); + } + + long long IGNITE_CALL IgniteAtomicLongGetAndDecrement(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongGetAndDecrement(static_cast<jobject>(obj)); + } + + long long IGNITE_CALL IgniteAtomicLongGetAndSet(gcj::JniContext* ctx, void* obj, long long value) { + return ctx->AtomicLongGetAndSet(static_cast<jobject>(obj), value); + } + + long long IGNITE_CALL IgniteAtomicLongCompareAndSetAndGet(gcj::JniContext* ctx, void* obj, long long expVal, long long newVal) { + return ctx->AtomicLongCompareAndSetAndGet(static_cast<jobject>(obj), expVal, newVal); + } + + bool IGNITE_CALL IgniteAtomicLongIsClosed(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongIsClosed(static_cast<jobject>(obj)); + } + + void IGNITE_CALL IgniteAtomicLongClose(gcj::JniContext* ctx, void* obj) { + return ctx->AtomicLongClose(static_cast<jobject>(obj)); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/cpp/common/src/java.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/common/src/java.cpp b/modules/platforms/cpp/common/src/java.cpp index 753b785..2c2b38d 100644 --- a/modules/platforms/cpp/common/src/java.cpp +++ b/modules/platforms/cpp/common/src/java.cpp @@ -173,6 +173,7 @@ namespace ignite JniMethod M_PLATFORM_PROCESSOR_EVENTS = JniMethod("events", "(Lorg/apache/ignite/internal/processors/platform/PlatformTarget;)Lorg/apache/ignite/internal/processors/platform/PlatformTarget;", false); JniMethod M_PLATFORM_PROCESSOR_SERVICES = JniMethod("services", "(Lorg/apache/ignite/internal/processors/platform/PlatformTarget;)Lorg/apache/ignite/internal/processors/platform/PlatformTarget;", false); JniMethod M_PLATFORM_PROCESSOR_EXTENSIONS = JniMethod("extensions", "()Lorg/apache/ignite/internal/processors/platform/PlatformTarget;", false); + JniMethod M_PLATFORM_PROCESSOR_ATOMIC_LONG = JniMethod("atomicLong", "(Ljava/lang/String;JZ)Lorg/apache/ignite/internal/processors/platform/PlatformTarget;", false); const char* C_PLATFORM_TARGET = "org/apache/ignite/internal/processors/platform/PlatformTarget"; JniMethod M_PLATFORM_TARGET_IN_STREAM_OUT_LONG = JniMethod("inStreamOutLong", "(IJ)J", false); @@ -350,6 +351,19 @@ namespace ignite JniMethod M_PLATFORM_SERVICES_CANCEL_ALL = JniMethod("cancelAll", "()V", false); JniMethod M_PLATFORM_SERVICES_SERVICE_PROXY = JniMethod("dotNetServiceProxy", "(Ljava/lang/String;Z)Ljava/lang/Object;", false); + const char* C_PLATFORM_ATOMIC_LONG = "org/apache/ignite/internal/processors/platform/datastructures/PlatformAtomicLong"; + JniMethod M_PLATFORM_ATOMIC_LONG_GET = JniMethod("get", "()J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_INCREMENT_AND_GET = JniMethod("incrementAndGet", "()J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_GET_AND_INCREMENT = JniMethod("getAndIncrement", "()J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_ADD_AND_GET = JniMethod("addAndGet", "(J)J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_GET_AND_ADD = JniMethod("getAndAdd", "(J)J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_DECREMENT_AND_GET = JniMethod("decrementAndGet", "()J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_GET_AND_DECREMENT = JniMethod("getAndDecrement", "()J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_GET_AND_SET = JniMethod("getAndSet", "(J)J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_COMPARE_AND_SET_AND_GET = JniMethod("compareAndSetAndGet", "(JJ)J", false); + JniMethod M_PLATFORM_ATOMIC_LONG_IS_CLOSED = JniMethod("isClosed", "()Z", false); + JniMethod M_PLATFORM_ATOMIC_LONG_CLOSE = JniMethod("close", "()V", false); + /* STATIC STATE. */ gcc::CriticalSection JVM_LOCK; JniJvm JVM; @@ -598,6 +612,7 @@ namespace ignite m_PlatformProcessor_events = FindMethod(env, c_PlatformProcessor, M_PLATFORM_PROCESSOR_EVENTS); m_PlatformProcessor_services = FindMethod(env, c_PlatformProcessor, M_PLATFORM_PROCESSOR_SERVICES); m_PlatformProcessor_extensions = FindMethod(env, c_PlatformProcessor, M_PLATFORM_PROCESSOR_EXTENSIONS); + m_PlatformProcessor_atomicLong = FindMethod(env, c_PlatformProcessor, M_PLATFORM_PROCESSOR_ATOMIC_LONG); c_PlatformTarget = FindClass(env, C_PLATFORM_TARGET); m_PlatformTarget_inStreamOutLong = FindMethod(env, c_PlatformTarget, M_PLATFORM_TARGET_IN_STREAM_OUT_LONG); @@ -625,6 +640,19 @@ namespace ignite m_PlatformUtils_reallocate = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_REALLOC); m_PlatformUtils_errData = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_ERR_DATA); + jclass c_PlatformAtomicLong = FindClass(env, C_PLATFORM_ATOMIC_LONG); + m_PlatformAtomicLong_get = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_GET); + m_PlatformAtomicLong_incrementAndGet = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_INCREMENT_AND_GET); + m_PlatformAtomicLong_getAndIncrement = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_GET_AND_INCREMENT); + m_PlatformAtomicLong_addAndGet = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_ADD_AND_GET); + m_PlatformAtomicLong_getAndAdd = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_GET_AND_ADD); + m_PlatformAtomicLong_decrementAndGet = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_DECREMENT_AND_GET); + m_PlatformAtomicLong_getAndDecrement = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_GET_AND_DECREMENT); + m_PlatformAtomicLong_getAndSet = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_GET_AND_SET); + m_PlatformAtomicLong_compareAndSetAndGet = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_COMPARE_AND_SET_AND_GET); + m_PlatformAtomicLong_isClosed = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_IS_CLOSED); + m_PlatformAtomicLong_close = FindMethod(env, c_PlatformAtomicLong, M_PLATFORM_ATOMIC_LONG_CLOSE); + // Find utility classes which are not used from context, but are still required in other places. CheckClass(env, C_PLATFORM_NO_CALLBACK_EXCEPTION); } @@ -1170,6 +1198,22 @@ namespace ignite return LocalToGlobal(env, res); } + jobject JniContext::ProcessorAtomicLong(jobject obj, char* name, long long initVal, bool create) + { + JNIEnv* env = Attach(); + + jstring name0 = name != NULL ? env->NewStringUTF(name) : NULL; + + jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformProcessor_atomicLong, name0, initVal, create); + + if (name0) + env->DeleteLocalRef(name0); + + ExceptionCheck(env); + + return LocalToGlobal(env, res); + } + long long JniContext::TargetInStreamOutLong(jobject obj, int opType, long long memPtr, JniErrorInfo* err) { JNIEnv* env = Attach(); @@ -1848,6 +1892,125 @@ namespace ignite return res; } + long long JniContext::AtomicLongGet(jobject obj) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_get); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongIncrementAndGet(jobject obj) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_incrementAndGet); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongGetAndIncrement(jobject obj) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_getAndIncrement); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongAddAndGet(jobject obj, long long value) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_addAndGet, value); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongGetAndAdd(jobject obj, long long value) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_getAndAdd, value); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongDecrementAndGet(jobject obj) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_decrementAndGet); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongGetAndDecrement(jobject obj) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_getAndDecrement); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongGetAndSet(jobject obj, long long value) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_getAndSet, value); + + ExceptionCheck(env); + + return res; + } + + long long JniContext::AtomicLongCompareAndSetAndGet(jobject obj, long long expVal, long long newVal) + { + JNIEnv* env = Attach(); + + long long res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_compareAndSetAndGet, expVal, newVal); + + ExceptionCheck(env); + + return res; + } + + bool JniContext::AtomicLongIsClosed(jobject obj) + { + JNIEnv* env = Attach(); + + bool res = env->CallBooleanMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_isClosed); + + ExceptionCheck(env); + + return res; + } + + void JniContext::AtomicLongClose(jobject obj) + { + JNIEnv* env = Attach(); + + env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformAtomicLong_close); + + ExceptionCheck(env); + } + jobject JniContext::Acquire(jobject obj) { if (obj) { http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/cpp/project/vs/ignite.sln ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/project/vs/ignite.sln b/modules/platforms/cpp/project/vs/ignite.sln index a96dd02..4a2ec29 100644 --- a/modules/platforms/cpp/project/vs/ignite.sln +++ b/modules/platforms/cpp/project/vs/ignite.sln @@ -1,5 +1,8 @@ -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\common\project\vs\common.vcxproj", "{4F7E4917-4612-4B96-9838-025711ADE391}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "..\..\core\project\vs\core.vcxproj", "{E2DEA693-F2EA-43C2-A813-053378F6E4DB}" http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj index 68bc223..90f3481 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Apache.Ignite.Core.Tests.csproj @@ -95,6 +95,7 @@ <Compile Include="Compute\TaskAdapterTest.cs" /> <Compile Include="Compute\TaskResultTest.cs" /> <Compile Include="Dataload\DataStreamerTest.cs" /> + <Compile Include="DataStructures\AtomicLongTest.cs" /> <Compile Include="EventsTest.cs" /> <Compile Include="Examples\Example.cs" /> <Compile Include="Examples\ExamplesTest.cs" /> @@ -103,6 +104,7 @@ <Compile Include="ExceptionsTest.cs" /> <Compile Include="ExecutableTest.cs" /> <Compile Include="FutureTest.cs" /> + <Compile Include="IgniteTestBase.cs" /> <Compile Include="LifecycleTest.cs" /> <Compile Include="LoadDllTest.cs" /> <Compile Include="IgniteManagerTest.cs" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicLongTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicLongTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicLongTest.cs new file mode 100644 index 0000000..28d0223 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/DataStructures/AtomicLongTest.cs @@ -0,0 +1,138 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Tests.DataStructures +{ + using System.Linq; + using NUnit.Framework; + + /// <summary> + /// Atomic long test. + /// </summary> + public class AtomicLongTest : IgniteTestBase + { + /** */ + private const string AtomicLongName = "testAtomicLong"; + + /// <summary> + /// Initializes a new instance of the <see cref="AtomicLongTest"/> class. + /// </summary> + public AtomicLongTest() : base("config\\compute\\compute-grid1.xml") + { + // No-op. + } + + /** <inheritdoc /> */ + public override void TestSetUp() + { + base.TestSetUp(); + + // Close test atomic if there is any + Grid.GetAtomicLong(AtomicLongName, 0, true).Close(); + } + + /// <summary> + /// Tests lifecycle of the AtomicLong. + /// </summary> + [Test] + public void TestCreateClose() + { + // Nonexistent long returns null + Assert.IsNull(Grid.GetAtomicLong(AtomicLongName, 10, false)); + + // Create new + var al = Grid.GetAtomicLong(AtomicLongName, 10, true); + Assert.AreEqual(AtomicLongName, al.Name); + Assert.AreEqual(10, al.Read()); + Assert.AreEqual(false, al.IsClosed()); + + // Get existing with create flag + var al2 = Grid.GetAtomicLong(AtomicLongName, 5, true); + Assert.AreEqual(AtomicLongName, al2.Name); + Assert.AreEqual(10, al2.Read()); + Assert.AreEqual(false, al2.IsClosed()); + + // Get existing without create flag + var al3 = Grid.GetAtomicLong(AtomicLongName, 5, false); + Assert.AreEqual(AtomicLongName, al3.Name); + Assert.AreEqual(10, al3.Read()); + Assert.AreEqual(false, al3.IsClosed()); + + al.Close(); + + Assert.AreEqual(true, al.IsClosed()); + Assert.AreEqual(true, al2.IsClosed()); + Assert.AreEqual(true, al3.IsClosed()); + + Assert.IsNull(Grid.GetAtomicLong(AtomicLongName, 10, false)); + } + + /// <summary> + /// Tests modification methods. + /// </summary> + [Test] + public void TestModify() + { + var atomics = Enumerable.Range(1, 10) + .Select(x => Grid.GetAtomicLong(AtomicLongName, 5, true)).ToList(); + + atomics.ForEach(x => Assert.AreEqual(5, x.Read())); + + Assert.AreEqual(10, atomics[0].Add(5)); + atomics.ForEach(x => Assert.AreEqual(10, x.Read())); + + Assert.AreEqual(10, atomics[0].CompareExchange(33, 10)); // successful exchange + atomics.ForEach(x => Assert.AreEqual(33, x.Read())); + + Assert.AreEqual(33, atomics[0].CompareExchange(44, 10)); // failed exchange + atomics.ForEach(x => Assert.AreEqual(33, x.Read())); + + Assert.AreEqual(33, atomics[0].Exchange(42)); + atomics.ForEach(x => Assert.AreEqual(42, x.Read())); + + Assert.AreEqual(41, atomics[0].Decrement()); + atomics.ForEach(x => Assert.AreEqual(41, x.Read())); + + Assert.AreEqual(42, atomics[0].Increment()); + atomics.ForEach(x => Assert.AreEqual(42, x.Read())); + } + + /// <summary> + /// Tests multithreaded scenario. + /// </summary> + [Test] + public void TestMultithreaded() + { + const int atomicCnt = 10; + const int threadCnt = 5; + const int iterations = 3000; + + // 10 atomics with same name + var atomics = Enumerable.Range(1, atomicCnt) + .Select(x => Grid.GetAtomicLong(AtomicLongName, 0, true)).ToList(); + + // 5 threads increment 30000 times + TestUtils.RunMultiThreaded(() => + { + for (var i = 0; i < iterations; i++) + atomics.ForEach(x => x.Increment()); + }, threadCnt); + + atomics.ForEach(x => Assert.AreEqual(atomicCnt*threadCnt*iterations, x.Read())); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs index 245ed5f..0195f19 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Dataload/DataStreamerTest.cs @@ -83,7 +83,7 @@ namespace Apache.Ignite.Core.Tests.Dataload [TearDown] public void AfterTest() { - TestUtils.AssertHandleRegistryIsEmpty(_grid, 1000); + TestUtils.AssertHandleRegistryIsEmpty(1000, _grid); } /// <summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteTestBase.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteTestBase.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteTestBase.cs new file mode 100644 index 0000000..a6ffd84 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/IgniteTestBase.cs @@ -0,0 +1,200 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Tests +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Apache.Ignite.Core.Compute; + using Apache.Ignite.Core.Events; + using Apache.Ignite.Core.Messaging; + using NUnit.Framework; + + /// <summary> + /// Base class for all grid tests. + /// </summary> + [Serializable] + public abstract class IgniteTestBase + { + /** Grids. */ + [NonSerialized] + private IIgnite[] _grids; + + /** Config urls. */ + [NonSerialized] + private readonly string[] _springUrls; + + /** Expected entry count by the end of the test. */ + [NonSerialized] + private readonly int _expectedHandleRegistryEntries; + + /// <summary> + /// Initializes a new instance of the <see cref="IgniteTestBase"/> class. + /// </summary> + /// <param name="springUrls">The spring urls.</param> + protected IgniteTestBase(params string[] springUrls) + : this(0, springUrls) + { + // No-op. + } + + /// <summary> + /// Initializes a new instance of the <see cref="IgniteTestBase"/> class. + /// </summary> + /// <param name="springUrls">The spring urls.</param> + /// <param name="expectedHandleRegistryEntries">The expected handle registry entries.</param> + protected IgniteTestBase(int expectedHandleRegistryEntries, params string[] springUrls) + { + _springUrls = springUrls.ToArray(); + + _grids = new IIgnite[_springUrls.Length]; + + Assert.IsTrue(_grids.Length > 0); + + _expectedHandleRegistryEntries = expectedHandleRegistryEntries; + } + + /// <summary> + /// Gets the grid1. + /// </summary> + public IIgnite Grid + { + get { return _grids[0]; } + } + + /// <summary> + /// Gets the grid2. + /// </summary> + public IIgnite Grid2 + { + get { return _grids[1]; } + } + + /// <summary> + /// Gets the grid3. + /// </summary> + public IIgnite Grid3 + { + get { return _grids[2]; } + } + + /// <summary> + /// Gets the events. + /// </summary> + public IEvents Events + { + get { return Grid.GetEvents(); } + } + + /// <summary> + /// Gets the messaging. + /// </summary> + public IMessaging Messaging + { + get { return Grid.GetMessaging(); } + } + + /// <summary> + /// Gets the compute. + /// </summary> + public ICompute Compute + { + get { return Grid.GetCompute(); } + } + + /// <summary> + /// Gets the grids. + /// </summary> + public ICollection<IIgnite> Grids + { + get { return _grids; } + } + + /// <summary> + /// Fixture tear down. + /// </summary> + [TestFixtureTearDown] + public virtual void FixtureTearDown() + { + StopGrids(); + } + + /// <summary> + /// Executes before each test. + /// </summary> + [SetUp] + public virtual void TestSetUp() + { + StartGrids(); + } + + /// <summary> + /// Executes after each test. + /// </summary> + [TearDown] + public virtual void TestTearDown() + { + try + { + TestUtils.AssertHandleRegistryHasItems(1000, _expectedHandleRegistryEntries, _grids); + } + catch (Exception) + { + // Restart grids to cleanup + StopGrids(); + + throw; + } + } + + /// <summary> + /// Starts the grids. + /// </summary> + private void StartGrids() + { + if (Grid != null) + return; + + _grids = _springUrls.Select(x => Ignition.Start(GetConfiguration(x))).ToArray(); + } + + /// <summary> + /// Gets the grid configuration. + /// </summary> + protected virtual IgniteConfiguration GetConfiguration(string springConfigUrl) + { + return new IgniteConfiguration + { + SpringConfigUrl = springConfigUrl, + JvmClasspath = TestUtils.CreateTestClasspath(), + JvmOptions = TestUtils.TestJavaOptions() + }; + } + + /// <summary> + /// Stops the grids. + /// </summary> + private void StopGrids() + { + for (var i = 0; i < _grids.Length; i++) + _grids[i] = null; + + Ignition.StopAll(true); + } + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs index ea0c6ef..f972cf7 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/TestUtils.cs @@ -244,19 +244,32 @@ namespace Apache.Ignite.Core.Tests public static void AssertHandleRegistryIsEmpty(int timeout, params IIgnite[] grids) { foreach (var g in grids) - AssertHandleRegistryIsEmpty(g, timeout); + AssertHandleRegistryHasItems(g, 0, timeout); } /// <summary> - /// Asserts that the handle registry is empty. + /// Asserts that the handle registry has specified number of entries. + /// </summary> + /// <param name="timeout">Timeout, in milliseconds.</param> + /// <param name="expectedCount">Expected item count.</param> + /// <param name="grids">Grids to check.</param> + public static void AssertHandleRegistryHasItems(int timeout, int expectedCount, params IIgnite[] grids) + { + foreach (var g in grids) + AssertHandleRegistryHasItems(g, expectedCount, timeout); + } + + /// <summary> + /// Asserts that the handle registry has specified number of entries. /// </summary> /// <param name="grid">The grid to check.</param> + /// <param name="expectedCount">Expected item count.</param> /// <param name="timeout">Timeout, in milliseconds.</param> - public static void AssertHandleRegistryIsEmpty(IIgnite grid, int timeout) + public static void AssertHandleRegistryHasItems(IIgnite grid, int expectedCount, int timeout) { var handleRegistry = ((Ignite)grid).HandleRegistry; - if (WaitForCondition(() => handleRegistry.Count == 0, timeout)) + if (WaitForCondition(() => handleRegistry.Count == expectedCount, timeout)) return; var items = handleRegistry.GetItems(); http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj index b776c0f..855dda8 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Apache.Ignite.Core.csproj @@ -113,6 +113,7 @@ <Compile Include="Datastream\IStreamReceiver.cs" /> <Compile Include="Datastream\StreamTransformer.cs" /> <Compile Include="Datastream\StreamVisitor.cs" /> + <Compile Include="DataStructures\IAtomicLong.cs" /> <Compile Include="Events\CacheEvent.cs" /> <Compile Include="Events\CacheQueryExecutedEvent.cs" /> <Compile Include="Events\CacheQueryReadEvent.cs" /> @@ -208,6 +209,7 @@ <Compile Include="Impl\Datastream\DataStreamerImpl.cs" /> <Compile Include="Impl\Datastream\DataStreamerRemoveEntry.cs" /> <Compile Include="Impl\Datastream\StreamReceiverHolder.cs" /> + <Compile Include="Impl\DataStructures\AtomicLong.cs" /> <Compile Include="Impl\Events\Events.cs" /> <Compile Include="Impl\Events\EventsAsync.cs" /> <Compile Include="Impl\Events\RemoteListenEventFilter.cs" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/DataStructures/IAtomicLong.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/DataStructures/IAtomicLong.cs b/modules/platforms/dotnet/Apache.Ignite.Core/DataStructures/IAtomicLong.cs new file mode 100644 index 0000000..636bac5 --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/DataStructures/IAtomicLong.cs @@ -0,0 +1,84 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.DataStructures +{ + /// <summary> + /// Represents a distributed atomic long value. + /// </summary> + public interface IAtomicLong + { + /// <summary> + /// Gets the name of this atomic long. + /// </summary> + /// <value> + /// Name of this atomic long. + /// </value> + string Name { get; } + + /// <summary> + /// Returns current value. + /// </summary> + /// <returns>Current value of the atomic long.</returns> + long Read(); + + /// <summary> + /// Increments current value and returns result. + /// </summary> + /// <returns>Current value of the atomic long.</returns> + long Increment(); + + /// <summary> + /// Adds specified value to the current value and returns result. + /// </summary> + /// <param name="value">The value to add.</param> + /// <returns>Current value of the atomic long.</returns> + long Add(long value); + + /// <summary> + /// Decrements current value and returns result. + /// </summary> + /// <returns>Current value of the atomic long.</returns> + long Decrement(); + + /// <summary> + /// Sets current value to a specified value and returns the original value. + /// </summary> + /// <param name="value">The value to set.</param> + /// <returns>Original value of the atomic long.</returns> + long Exchange(long value); + + /// <summary> + /// Compares current value with specified value for equality and, if they are equal, replaces current value. + /// </summary> + /// <param name="value">The value to set.</param> + /// <param name="comparand">The value that is compared to the current value.</param> + /// <returns>Original value of the atomic long.</returns> + long CompareExchange(long value, long comparand); + + /// <summary> + /// Determines whether this instance was removed from cache. + /// </summary> + /// <returns>True if this atomic was removed from cache; otherwise, false.</returns> + bool IsClosed(); + + /// <summary> + /// Closes this instance. + /// </summary> + void Close(); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs index 851f231..c591e2b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/IIgnite.cs @@ -21,8 +21,10 @@ namespace Apache.Ignite.Core using System.Diagnostics.CodeAnalysis; using Apache.Ignite.Core.Cache; using Apache.Ignite.Core.Cluster; + using Apache.Ignite.Core.Common; using Apache.Ignite.Core.Compute; using Apache.Ignite.Core.Datastream; + using Apache.Ignite.Core.DataStructures; using Apache.Ignite.Core.Events; using Apache.Ignite.Core.Messaging; using Apache.Ignite.Core.Portable; @@ -148,5 +150,19 @@ namespace Apache.Ignite.Core /// <returns>Services facade over all cluster nodes.</returns> [SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Semantics.")] IServices GetServices(); + + /// <summary> + /// Gets an atomic long with specified name from cache. + /// Creates new atomic long in cache if it does not exist and <see cref="create"/> is true. + /// </summary> + /// <param name="name">Name of the atomic long.</param> + /// <param name="initialValue"> + /// Initial value for the atomic long. Ignored if <see cref="create"/> is false. + /// </param> + /// <param name="create">Flag indicating whether atomic long should be created if it does not exist.</param> + /// <returns>Atomic long instance with specified name, + /// or null if it does not exist and <see cref="create"/> flag is not set.</returns> + /// <exception cref="IgniteException">If atomic long could not be fetched or created.</exception> + IAtomicLong GetAtomicLong(string name, long initialValue, bool create); } } http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataStructures/AtomicLong.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataStructures/AtomicLong.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataStructures/AtomicLong.cs new file mode 100644 index 0000000..a4785eb --- /dev/null +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/DataStructures/AtomicLong.cs @@ -0,0 +1,102 @@ +/* + * 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. + */ + +namespace Apache.Ignite.Core.Impl.DataStructures +{ + using System.Diagnostics; + using Apache.Ignite.Core.DataStructures; + using Apache.Ignite.Core.Impl.Portable; + using Apache.Ignite.Core.Impl.Unmanaged; + + using UU = Apache.Ignite.Core.Impl.Unmanaged.UnmanagedUtils; + + /// <summary> + /// Atomic long wrapper. + /// </summary> + internal sealed class AtomicLong : PlatformTarget, IAtomicLong + { + /** */ + private readonly string _name; + + /// <summary> + /// Initializes a new instance of the <see cref="AtomicLong"/> class. + /// </summary> + /// <param name="target">The target.</param> + /// <param name="marsh">The marshaller.</param> + /// <param name="name">The name.</param> + public AtomicLong(IUnmanagedTarget target, PortableMarshaller marsh, string name) : base(target, marsh) + { + Debug.Assert(!string.IsNullOrEmpty(name)); + + _name = name; + } + + /** <inheritDoc /> */ + public string Name + { + get { return _name; } + } + + /** <inheritDoc /> */ + public long Read() + { + return UU.AtomicLongGet(Target); + } + + /** <inheritDoc /> */ + public long Increment() + { + return UU.AtomicLongIncrementAndGet(Target); + } + + /** <inheritDoc /> */ + public long Add(long value) + { + return UU.AtomicLongAddAndGet(Target, value); + } + + /** <inheritDoc /> */ + public long Decrement() + { + return UU.AtomicLongDecrementAndGet(Target); + } + + /** <inheritDoc /> */ + public long Exchange(long value) + { + return UU.AtomicLongGetAndSet(Target, value); + } + + /** <inheritDoc /> */ + public long CompareExchange(long value, long comparand) + { + return UU.AtomicLongCompareAndSetAndGet(Target, comparand, value); + } + + /** <inheritDoc /> */ + public void Close() + { + UU.AtomicLongClose(Target); + } + + /** <inheritDoc /> */ + public bool IsClosed() + { + return UU.AtomicLongIsClosed(Target); + } + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs index 39c8a2d..9f3d9b1 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Ignite.cs @@ -27,11 +27,13 @@ namespace Apache.Ignite.Core.Impl using Apache.Ignite.Core.Cluster; using Apache.Ignite.Core.Compute; using Apache.Ignite.Core.Datastream; + using Apache.Ignite.Core.DataStructures; using Apache.Ignite.Core.Events; using Apache.Ignite.Core.Impl.Cache; using Apache.Ignite.Core.Impl.Cluster; using Apache.Ignite.Core.Impl.Common; using Apache.Ignite.Core.Impl.Datastream; + using Apache.Ignite.Core.Impl.DataStructures; using Apache.Ignite.Core.Impl.Handle; using Apache.Ignite.Core.Impl.Portable; using Apache.Ignite.Core.Impl.Transactions; @@ -430,6 +432,19 @@ namespace Apache.Ignite.Core.Impl return _prj.GetServices(); } + /** <inheritdoc /> */ + public IAtomicLong GetAtomicLong(string name, long initialValue, bool create) + { + IgniteArgumentCheck.NotNullOrEmpty(name, "name"); + + var nativeLong = UU.ProcessorAtomicLong(_proc, name, initialValue, create); + + if (nativeLong == null) + return null; + + return new AtomicLong(nativeLong, Marshaller, name); + } + /// <summary> /// Gets internal projection. /// </summary> http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs index 3e26791..4f9e369 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/IgniteProxy.cs @@ -24,6 +24,7 @@ namespace Apache.Ignite.Core.Impl using Apache.Ignite.Core.Cluster; using Apache.Ignite.Core.Compute; using Apache.Ignite.Core.Datastream; + using Apache.Ignite.Core.DataStructures; using Apache.Ignite.Core.Events; using Apache.Ignite.Core.Impl.Cluster; using Apache.Ignite.Core.Impl.Portable; @@ -311,6 +312,12 @@ namespace Apache.Ignite.Core.Impl } /** <inheritdoc /> */ + public IAtomicLong GetAtomicLong(string name, long initialValue, bool create) + { + return _ignite.GetAtomicLong(name, initialValue, create); + } + + /** <inheritdoc /> */ public void WritePortable(IPortableWriter writer) { // No-op. http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformTarget.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformTarget.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformTarget.cs index 6e1c0e4..03ccf8b 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformTarget.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/PlatformTarget.cs @@ -19,6 +19,7 @@ namespace Apache.Ignite.Core.Impl { using System; using System.Collections.Generic; + using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using Apache.Ignite.Core.Common; @@ -73,6 +74,9 @@ namespace Apache.Ignite.Core.Impl /// <param name="marsh">Marshaller.</param> protected PlatformTarget(IUnmanagedTarget target, PortableMarshaller marsh) { + Debug.Assert(target != null); + Debug.Assert(marsh != null); + _target = target; _marsh = marsh; } http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs index e502840..69523c9 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Portable/PortableWriterImpl.cs @@ -1537,7 +1537,8 @@ namespace Apache.Ignite.Core.Impl.Portable { // Merge newly recorded handles with old ones and restore old on the stack. // Otherwise we can use current handles right away. - oldHnds.Merge(_hnds); + if (_hnds != null) + oldHnds.Merge(_hnds); _hnds = oldHnds; } http://git-wip-us.apache.org/repos/asf/ignite/blob/49c495b9/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs ---------------------------------------------------------------------- diff --git a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs index c3a681e..7a19ac4 100644 --- a/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs +++ b/modules/platforms/dotnet/Apache.Ignite.Core/Impl/Unmanaged/UnmanagedUtils.cs @@ -53,6 +53,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private const string ProcProcessorEvents = "IgniteProcessorEvents"; private const string ProcProcessorServices = "IgniteProcessorServices"; private const string ProcProcessorExtensions = "IgniteProcessorExtensions"; + private const string ProcProcessorAtomicLong = "IgniteProcessorAtomicLong"; private const string ProcTargetInStreamOutLong = "IgniteTargetInStreamOutLong"; private const string ProcTargetInStreamOutStream = "IgniteTargetInStreamOutStream"; @@ -150,7 +151,16 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private const string ProcServicesCancel = "IgniteServicesCancel"; private const string ProcServicesCancelAll = "IgniteServicesCancelAll"; private const string ProcServicesGetServiceProxy = "IgniteServicesGetServiceProxy"; - + + private const string ProcAtomicLongGet = "IgniteAtomicLongGet"; + private const string ProcAtomicLongIncrementAndGet = "IgniteAtomicLongIncrementAndGet"; + private const string ProcAtomicLongAddAndGet = "IgniteAtomicLongAddAndGet"; + private const string ProcAtomicLongDecrementAndGet = "IgniteAtomicLongDecrementAndGet"; + private const string ProcAtomicLongGetAndSet = "IgniteAtomicLongGetAndSet"; + private const string ProcAtomicLongCompareAndSetAndGet = "IgniteAtomicLongCompareAndSetAndGet"; + private const string ProcAtomicLongIsClosed = "IgniteAtomicLongIsClosed"; + private const string ProcAtomicLongClose = "IgniteAtomicLongClose"; + #endregion #region DELEGATE DEFINITIONS @@ -174,6 +184,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private delegate void* ProcessorEventsDelegate(void* ctx, void* obj, void* prj); private delegate void* ProcessorServicesDelegate(void* ctx, void* obj, void* prj); private delegate void* ProcessorExtensionsDelegate(void* ctx, void* obj); + private delegate void* ProcessorAtomicLongDelegate(void* ctx, void* obj, sbyte* name, long initVal, bool create); private delegate long TargetInStreamOutLongDelegate(void* ctx, void* target, int opType, long memPtr); private delegate void TargetInStreamOutStreamDelegate(void* ctx, void* target, int opType, long inMemPtr, long outMemPtr); @@ -272,6 +283,15 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private delegate long ServicesCancelAllDelegate(void* ctx, void* target); private delegate void* ServicesGetServiceProxyDelegate(void* ctx, void* target, char* name, bool sticky); + private delegate long AtomicLongGetDelegate(void* ctx, void* target); + private delegate long AtomicLongIncrementAndGetDelegate(void* ctx, void* target); + private delegate long AtomicLongAddAndGetDelegate(void* ctx, void* target, long value); + private delegate long AtomicLongDecrementAndGetDelegate(void* ctx, void* target); + private delegate long AtomicLongGetAndSetDelegate(void* ctx, void* target, long value); + private delegate long AtomicLongCompareAndSetAndGetDelegate(void* ctx, void* target, long expVal, long newVal); + private delegate bool AtomicLongIsClosedDelegate(void* ctx, void* target); + private delegate void AtomicLongCloseDelegate(void* ctx, void* target); + #endregion #region DELEGATE MEMBERS @@ -296,6 +316,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private static readonly ProcessorEventsDelegate PROCESSOR_EVENTS; private static readonly ProcessorServicesDelegate PROCESSOR_SERVICES; private static readonly ProcessorExtensionsDelegate PROCESSOR_EXTENSIONS; + private static readonly ProcessorAtomicLongDelegate PROCESSOR_ATOMIC_LONG; private static readonly TargetInStreamOutLongDelegate TARGET_IN_STREAM_OUT_LONG; private static readonly TargetInStreamOutStreamDelegate TARGET_IN_STREAM_OUT_STREAM; @@ -393,6 +414,16 @@ namespace Apache.Ignite.Core.Impl.Unmanaged private static readonly ServicesCancelDelegate SERVICES_CANCEL; private static readonly ServicesCancelAllDelegate SERVICES_CANCEL_ALL; private static readonly ServicesGetServiceProxyDelegate SERVICES_GET_SERVICE_PROXY; + + private static readonly AtomicLongGetDelegate ATOMIC_LONG_GET; + private static readonly AtomicLongIncrementAndGetDelegate ATOMIC_LONG_INCREMENT_AND_GET; + private static readonly AtomicLongAddAndGetDelegate ATOMIC_LONG_ADD_AND_GET; + private static readonly AtomicLongDecrementAndGetDelegate ATOMIC_LONG_DECREMENT_AND_GET; + private static readonly AtomicLongGetAndSetDelegate ATOMIC_LONG_GET_AND_SET; + private static readonly AtomicLongCompareAndSetAndGetDelegate ATOMIC_LONG_COMPARE_AND_SET_AND_GET; + private static readonly AtomicLongIsClosedDelegate ATOMIC_LONG_IS_CLOSED; + private static readonly AtomicLongCloseDelegate ATOMIC_LONG_CLOSE; + // ReSharper restore InconsistentNaming #endregion @@ -433,6 +464,7 @@ namespace Apache.Ignite.Core.Impl.Unmanaged PROCESSOR_EVENTS = CreateDelegate<ProcessorEventsDelegate>(ProcProcessorEvents); PROCESSOR_SERVICES = CreateDelegate<ProcessorServicesDelegate>(ProcProcessorServices); PROCESSOR_EXTENSIONS = CreateDelegate<ProcessorExtensionsDelegate>(ProcProcessorExtensions); + PROCESSOR_ATOMIC_LONG = CreateDelegate<ProcessorAtomicLongDelegate>(ProcProcessorAtomicLong); TARGET_IN_STREAM_OUT_LONG = CreateDelegate<TargetInStreamOutLongDelegate>(ProcTargetInStreamOutLong); TARGET_IN_STREAM_OUT_STREAM = CreateDelegate<TargetInStreamOutStreamDelegate>(ProcTargetInStreamOutStream); @@ -529,6 +561,15 @@ namespace Apache.Ignite.Core.Impl.Unmanaged SERVICES_CANCEL = CreateDelegate<ServicesCancelDelegate>(ProcServicesCancel); SERVICES_CANCEL_ALL = CreateDelegate<ServicesCancelAllDelegate>(ProcServicesCancelAll); SERVICES_GET_SERVICE_PROXY = CreateDelegate<ServicesGetServiceProxyDelegate>(ProcServicesGetServiceProxy); + + ATOMIC_LONG_GET = CreateDelegate<AtomicLongGetDelegate>(ProcAtomicLongGet); + ATOMIC_LONG_INCREMENT_AND_GET = CreateDelegate<AtomicLongIncrementAndGetDelegate>(ProcAtomicLongIncrementAndGet); + ATOMIC_LONG_ADD_AND_GET = CreateDelegate<AtomicLongAddAndGetDelegate>(ProcAtomicLongAddAndGet); + ATOMIC_LONG_DECREMENT_AND_GET = CreateDelegate<AtomicLongDecrementAndGetDelegate>(ProcAtomicLongDecrementAndGet); + ATOMIC_LONG_GET_AND_SET = CreateDelegate<AtomicLongGetAndSetDelegate>(ProcAtomicLongGetAndSet); + ATOMIC_LONG_COMPARE_AND_SET_AND_GET = CreateDelegate<AtomicLongCompareAndSetAndGetDelegate>(ProcAtomicLongCompareAndSetAndGet); + ATOMIC_LONG_IS_CLOSED = CreateDelegate<AtomicLongIsClosedDelegate>(ProcAtomicLongIsClosed); + ATOMIC_LONG_CLOSE = CreateDelegate<AtomicLongCloseDelegate>(ProcAtomicLongClose); } #region NATIVE METHODS: PROCESSOR @@ -711,6 +752,23 @@ namespace Apache.Ignite.Core.Impl.Unmanaged return target.ChangeTarget(res); } + internal static IUnmanagedTarget ProcessorAtomicLong(IUnmanagedTarget target, string name, long initialValue, + bool create) + { + var name0 = IgniteUtils.StringToUtf8Unmanaged(name); + + try + { + var res = PROCESSOR_ATOMIC_LONG(target.Context, target.Target, name0, initialValue, create); + + return res == null ? null : target.ChangeTarget(res); + } + finally + { + Marshal.FreeHGlobal(new IntPtr(name0)); + } + } + #endregion #region NATIVE METHODS: TARGET @@ -1236,6 +1294,50 @@ namespace Apache.Ignite.Core.Impl.Unmanaged #endregion + #region NATIVE METHODS: DATA STRUCTURES + + internal static long AtomicLongGet(IUnmanagedTarget target) + { + return ATOMIC_LONG_GET(target.Context, target.Target); + } + + internal static long AtomicLongIncrementAndGet(IUnmanagedTarget target) + { + return ATOMIC_LONG_INCREMENT_AND_GET(target.Context, target.Target); + } + + internal static long AtomicLongAddAndGet(IUnmanagedTarget target, long value) + { + return ATOMIC_LONG_ADD_AND_GET(target.Context, target.Target, value); + } + + internal static long AtomicLongDecrementAndGet(IUnmanagedTarget target) + { + return ATOMIC_LONG_DECREMENT_AND_GET(target.Context, target.Target); + } + + internal static long AtomicLongGetAndSet(IUnmanagedTarget target, long value) + { + return ATOMIC_LONG_GET_AND_SET(target.Context, target.Target, value); + } + + internal static long AtomicLongCompareAndSetAndGet(IUnmanagedTarget target, long expVal, long newVal) + { + return ATOMIC_LONG_COMPARE_AND_SET_AND_GET(target.Context, target.Target, expVal, newVal); + } + + internal static bool AtomicLongIsClosed(IUnmanagedTarget target) + { + return ATOMIC_LONG_IS_CLOSED(target.Context, target.Target); + } + + internal static void AtomicLongClose(IUnmanagedTarget target) + { + ATOMIC_LONG_CLOSE(target.Context, target.Target); + } + + #endregion + /// <summary> /// No-op initializer used to force type loading and static constructor call. /// </summary>
