You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by sb...@apache.org on 2015/11/17 17:38:28 UTC
[1/4] ignite git commit: 'Single' operations optimizations for tx
cache.
Repository: ignite
Updated Branches:
refs/heads/ignite-1.5 38e66d93f -> 3ff71fd74
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java
new file mode 100644
index 0000000..22f04a8
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteSingleStateImpl.java
@@ -0,0 +1,108 @@
+/*
+ * 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.cache.transactions;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class IgniteTxRemoteSingleStateImpl extends IgniteTxRemoteStateAdapter {
+ /** */
+ private IgniteTxEntry entry;
+
+ /** {@inheritDoc} */
+ @Override public void addWriteEntry(IgniteTxKey key, IgniteTxEntry e) {
+ this.entry = e;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void clearEntry(IgniteTxKey key) {
+ if (entry != null && entry.txKey().equals(key))
+ entry = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ if (entry != null && entry.txKey().equals(key))
+ return entry;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return entry != null && entry.txKey().equals(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return Collections.emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return entry != null ? Collections.singleton(entry.txKey()) : Collections.<IgniteTxKey>emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return Collections.emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return entry != null ? Collections.singletonMap(entry.txKey(), entry) :
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return Collections.emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return entry == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public IgniteTxEntry singleWrite() {
+ return entry;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxRemoteSingleStateImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java
new file mode 100644
index 0000000..b8290a1
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteState.java
@@ -0,0 +1,34 @@
+/*
+ * 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.cache.transactions;
+
+/**
+ *
+ */
+public interface IgniteTxRemoteState extends IgniteTxState {
+ /**
+ * @param key Key.
+ * @param e Entry.
+ */
+ public void addWriteEntry(IgniteTxKey key, IgniteTxEntry e);
+
+ /**
+ * @param key Entry key.
+ */
+ public void clearEntry(IgniteTxKey key);
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
new file mode 100644
index 0000000..e7c4c96
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateAdapter.java
@@ -0,0 +1,110 @@
+/*
+ * 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.cache.transactions;
+
+import java.util.Collection;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public abstract class IgniteTxRemoteStateAdapter implements IgniteTxRemoteState {
+ /** {@inheritDoc} */
+ @Override public boolean implicitSingle() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public Integer firstCacheId() {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void awaitLastFut(GridCacheSharedContext cctx) {
+ assert false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException validateTopology(GridCacheSharedContext cctx, GridDhtTopologyFuture topFut) {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sync(GridCacheSharedContext cctx) {
+ assert false;
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNearCache(GridCacheSharedContext cctx) {
+ assert false;
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addActiveCache(GridCacheContext cacheCtx, IgniteTxLocalAdapter tx)
+ throws IgniteCheckedException {
+ assert false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
+ assert false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean storeUsed(GridCacheSharedContext cctx) {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
+ assert false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java
new file mode 100644
index 0000000..32bc646
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteStateImpl.java
@@ -0,0 +1,124 @@
+/*
+ * 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.cache.transactions;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+
+/**
+ *
+ */
+public class IgniteTxRemoteStateImpl extends IgniteTxRemoteStateAdapter {
+ /** Read set. */
+ @GridToStringInclude
+ protected Map<IgniteTxKey, IgniteTxEntry> readMap;
+
+ /** Write map. */
+ @GridToStringInclude
+ protected Map<IgniteTxKey, IgniteTxEntry> writeMap;
+
+ /**
+ * @param readMap Read map.
+ * @param writeMap Write map.
+ */
+ public IgniteTxRemoteStateImpl(Map<IgniteTxKey, IgniteTxEntry> readMap,
+ Map<IgniteTxKey, IgniteTxEntry> writeMap) {
+ this.readMap = readMap;
+ this.writeMap = writeMap;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ IgniteTxEntry e = writeMap == null ? null : writeMap.get(key);
+
+ if (e == null)
+ e = readMap == null ? null : readMap.get(key);
+
+ return e;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return writeMap.containsKey(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return readMap.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return writeMap.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return writeMap.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return readMap.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return writeMap;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return readMap;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return readMap.isEmpty() && writeMap.isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ public void addWriteEntry(IgniteTxKey key, IgniteTxEntry e) {
+ writeMap.put(key, e);
+ }
+
+ /** {@inheritDoc} */
+ public void clearEntry(IgniteTxKey key) {
+ readMap.remove(key);
+ writeMap.remove(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return F.concat(false, writeEntries(), readEntries());
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry singleWrite() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxRemoteStateImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
new file mode 100644
index 0000000..81707ba
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxState.java
@@ -0,0 +1,171 @@
+/*
+ * 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.cache.transactions;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public interface IgniteTxState {
+ /**
+ *
+ * @return Flag indicating whether transaction is implicit with only one key.
+ */
+ public boolean implicitSingle();
+
+ /**
+ * @return First tx cache id.
+ */
+ @Nullable public Integer firstCacheId();
+
+ /**
+ * @param cctx Context.
+ * @return cctx Non-null cache context if tx has only one active cache.
+ */
+ @Nullable public GridCacheContext singleCacheContext(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Awaits for previous async operations on active caches to be completed.
+ */
+ public void awaitLastFut(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @param topFut Topology future.
+ * @return Error if validation failed.
+ */
+ public IgniteCheckedException validateTopology(GridCacheSharedContext cctx, GridDhtTopologyFuture topFut);
+
+ /**
+ * @param cctx Context.
+ * @return {@code True} if transaction is fully synchronous.
+ */
+ public boolean sync(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @return {@code True} is tx has active near cache.
+ */
+ public boolean hasNearCache(GridCacheSharedContext cctx);
+
+ /**
+ * @param cacheCtx Ccntext.
+ * @param tx Transaction.
+ * @throws IgniteCheckedException If cache check failed.
+ */
+ public void addActiveCache(GridCacheContext cacheCtx, IgniteTxLocalAdapter tx) throws IgniteCheckedException;
+
+ /**
+ * @param cctx Context.
+ * @param fut Future to finish with error if some cache is stopping.
+ * @return Topology future.
+ */
+ public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut);
+
+ /**
+ * @param cctx Context.
+ */
+ public void topologyReadUnlock(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @return {@code True} if transaction is allowed to use store and transactions spans one or more caches with
+ * store enabled.
+ */
+ public boolean storeUsed(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @return Configured stores for active caches.
+ */
+ public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx);
+
+ /**
+ * @param cctx Context.
+ * @param tx Transaction.
+ * @param commit Commit flag.
+ */
+ public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit);
+
+ /**
+ * @param key Key.
+ * @return Entry.
+ */
+ @Nullable public IgniteTxEntry entry(IgniteTxKey key);
+
+ /**
+ * @param key Key.
+ * @return {@code True} if tx has write key.
+ */
+ public boolean hasWriteKey(IgniteTxKey key);
+
+ /**
+ * @return Read entries keys.
+ */
+ public Set<IgniteTxKey> readSet();
+
+ /**
+ * @return Write entries keys.
+ */
+ public Set<IgniteTxKey> writeSet();
+
+ /**
+ * @return Write entries.
+ */
+ public Collection<IgniteTxEntry> writeEntries();
+
+ /**
+ * @return Read entries.
+ */
+ public Collection<IgniteTxEntry> readEntries();
+
+ /**
+ * @return Write entries map.
+ */
+ public Map<IgniteTxKey, IgniteTxEntry> writeMap();
+
+ /**
+ * @return Read entries map.
+ */
+ public Map<IgniteTxKey, IgniteTxEntry> readMap();
+
+ /**
+ * @return All entries.
+ */
+ public Collection<IgniteTxEntry> allEntries();
+
+ /**
+ * @return Non-null entry if tx has only one write entry.
+ */
+ @Nullable public IgniteTxEntry singleWrite();
+
+ /**
+ * @return {@code True} if transaction is empty.
+ */
+ public boolean empty();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
new file mode 100644
index 0000000..c95fb19
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxStateImpl.java
@@ -0,0 +1,375 @@
+/*
+ * 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.cache.transactions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.tostring.GridToStringExclude;
+import org.apache.ignite.internal.util.tostring.GridToStringInclude;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class IgniteTxStateImpl extends IgniteTxLocalStateAdapter {
+ /** Active cache IDs. */
+ private Set<Integer> activeCacheIds = new HashSet<>();
+ /** Per-transaction read map. */
+
+ @GridToStringInclude
+ protected Map<IgniteTxKey, IgniteTxEntry> txMap;
+
+ /** Read view on transaction map. */
+ @GridToStringExclude
+ protected IgniteTxMap readView;
+
+ /** Write view on transaction map. */
+ @GridToStringExclude
+ protected IgniteTxMap writeView;
+
+ /** {@inheritDoc} */
+ @Override public boolean implicitSingle() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public Integer firstCacheId() {
+ return F.first(activeCacheIds);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
+ if (activeCacheIds.size() == 1) {
+ int cacheId = F.first(activeCacheIds);
+
+ return cctx.cacheContext(cacheId);
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void awaitLastFut(GridCacheSharedContext cctx) {
+ for (Integer cacheId : activeCacheIds)
+ cctx.cacheContext(cacheId).cache().awaitLastFut();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException validateTopology(GridCacheSharedContext cctx,
+ GridDhtTopologyFuture topFut) {
+ StringBuilder invalidCaches = null;
+
+ for (Integer cacheId : activeCacheIds) {
+ GridCacheContext ctx = cctx.cacheContext(cacheId);
+
+ assert ctx != null : cacheId;
+
+ Throwable err = topFut.validateCache(ctx);
+
+ if (err != null) {
+ if (invalidCaches != null)
+ invalidCaches.append(", ");
+ else
+ invalidCaches = new StringBuilder();
+
+ invalidCaches.append(U.maskName(ctx.name()));
+ }
+ }
+
+ if (invalidCaches != null) {
+ return new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
+ invalidCaches.toString());
+ }
+
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (CU.affinityNodes(cacheCtx, topFut.topologyVersion()).isEmpty()) {
+ return new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
+ "partition nodes left the grid): " + cacheCtx.name());
+ }
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sync(GridCacheSharedContext cctx) {
+ for (int cacheId : activeCacheIds) {
+ if (cctx.cacheContext(cacheId).config().getWriteSynchronizationMode() == FULL_SYNC)
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNearCache(GridCacheSharedContext cctx) {
+ for (Integer cacheId : activeCacheIds) {
+ GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
+
+ if (cacheCtx.isNear())
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addActiveCache(GridCacheContext cacheCtx, IgniteTxLocalAdapter tx)
+ throws IgniteCheckedException {
+ GridCacheSharedContext cctx = cacheCtx.shared();
+
+ int cacheId = cacheCtx.cacheId();
+
+ // Check if we can enlist new cache to transaction.
+ if (!activeCacheIds.contains(cacheId)) {
+ String err = cctx.verifyTxCompatibility(tx, activeCacheIds, cacheCtx);
+
+ if (err != null) {
+ StringBuilder cacheNames = new StringBuilder();
+
+ int idx = 0;
+
+ for (Integer activeCacheId : activeCacheIds) {
+ cacheNames.append(cctx.cacheContext(activeCacheId).name());
+
+ if (idx++ < activeCacheIds.size() - 1)
+ cacheNames.append(", ");
+ }
+
+ throw new IgniteCheckedException("Failed to enlist new cache to existing transaction (" +
+ err +
+ ") [activeCaches=[" + cacheNames + "]" +
+ ", cacheName=" + cacheCtx.name() +
+ ", cacheSystem=" + cacheCtx.systemTx() +
+ ", txSystem=" + tx.system() + ']');
+ }
+ else
+ activeCacheIds.add(cacheId);
+
+ if (activeCacheIds.size() == 1)
+ tx.activeCachesDeploymentEnabled(cacheCtx.deploymentEnabled());
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
+ if (activeCacheIds.isEmpty())
+ return cctx.exchange().lastTopologyFuture();
+
+ GridCacheContext<?, ?> nonLocCtx = null;
+
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (!cacheCtx.isLocal()) {
+ nonLocCtx = cacheCtx;
+
+ break;
+ }
+ }
+
+ if (nonLocCtx == null)
+ return cctx.exchange().lastTopologyFuture();
+
+ nonLocCtx.topology().readLock();
+
+ if (nonLocCtx.topology().stopping()) {
+ fut.onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
+ nonLocCtx.name()));
+
+ return null;
+ }
+
+ return nonLocCtx.topology().topologyVersionFuture();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
+ if (!activeCacheIds.isEmpty()) {
+ GridCacheContext<?, ?> nonLocCtx = null;
+
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
+
+ if (!cacheCtx.isLocal()) {
+ nonLocCtx = cacheCtx;
+
+ break;
+ }
+ }
+
+ if (nonLocCtx != null)
+ nonLocCtx.topology().readUnlock();
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean storeUsed(GridCacheSharedContext cctx) {
+ if (!activeCacheIds.isEmpty()) {
+ for (int cacheId : activeCacheIds) {
+ CacheStoreManager store = cctx.cacheContext(cacheId).store();
+
+ if (store.configured())
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
+ Collection<Integer> cacheIds = activeCacheIds;
+
+ if (!cacheIds.isEmpty()) {
+ Collection<CacheStoreManager> stores = new ArrayList<>(cacheIds.size());
+
+ for (int cacheId : cacheIds) {
+ CacheStoreManager store = cctx.cacheContext(cacheId).store();
+
+ if (store.configured())
+ stores.add(store);
+ }
+
+ return stores;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
+ for (int cacheId : activeCacheIds) {
+ GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
+
+ onTxEnd(cacheCtx, tx, commit);
+ }
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean init(int txSize) {
+ if (txMap == null) {
+ txMap = U.newLinkedHashMap(txSize > 0 ? txSize : 16);
+
+ readView = new IgniteTxMap(txMap, CU.reads());
+ writeView = new IgniteTxMap(txMap, CU.writes());
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean initialized() {
+ return txMap != null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return txMap == null ? Collections.<IgniteTxEntry>emptySet() : txMap.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ return txMap == null ? null : txMap.get(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return writeView.containsKey(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return txMap == null ? Collections.<IgniteTxKey>emptySet() : readView.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return txMap == null ? Collections.<IgniteTxKey>emptySet() : writeView.keySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return writeView == null ? Collections.<IgniteTxEntry>emptyList() : writeView.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return readView == null ? Collections.<IgniteTxEntry>emptyList() : readView.values();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return writeView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : writeView;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return readView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : readView;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return txMap.isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addEntry(IgniteTxEntry entry) {
+ txMap.put(entry.txKey(), entry);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void seal() {
+ if (readView != null)
+ readView.seal();
+
+ if (writeView != null)
+ writeView.seal();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry singleWrite() {
+ return writeView != null && writeView.size() == 1 ? F.firstValue(writeView) : null;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxStateImpl.class, this);
+ }
+}
[3/4] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
index db4a4b8..434b6c7 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxLocal.java
@@ -68,9 +68,7 @@ import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
import org.apache.ignite.transactions.TransactionState;
import org.jetbrains.annotations.Nullable;
-import org.jsr166.ConcurrentHashMap8;
-import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
import static org.apache.ignite.transactions.TransactionState.COMMITTED;
import static org.apache.ignite.transactions.TransactionState.COMMITTING;
import static org.apache.ignite.transactions.TransactionState.PREPARING;
@@ -87,7 +85,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
private static final long serialVersionUID = 0L;
/** DHT mappings. */
- private Map<UUID, GridDistributedTxMapping> mappings = new ConcurrentHashMap8<>();
+ private IgniteTxMappings mappings;
/** Future. */
@GridToStringExclude
@@ -172,6 +170,8 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
subjId,
taskNameHash);
+ mappings = implicitSingle ? new IgniteTxMappingsSingleImpl() : new IgniteTxMappingsImpl();
+
initResult();
}
@@ -208,13 +208,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/** {@inheritDoc} */
- @Override protected IgniteUuid nearMiniId() {
- assert false : "nearMiniId should not be called for colocated transactions.";
-
- return null;
- }
-
- /** {@inheritDoc} */
@Override protected IgniteInternalFuture<Boolean> addReader(
long msgId,
GridDhtCacheEntry cached,
@@ -280,15 +273,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
* @return {@code True} if transaction is fully synchronous.
*/
private boolean sync() {
- if (super.syncCommit())
- return true;
-
- for (int cacheId : activeCacheIds()) {
- if (cctx.cacheContext(cacheId).config().getWriteSynchronizationMode() == FULL_SYNC)
- return true;
- }
-
- return false;
+ return super.syncCommit() || txState().sync(cctx);
}
/**
@@ -471,7 +456,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
/**
* @return DHT map.
*/
- Map<UUID, GridDistributedTxMapping> mappings() {
+ IgniteTxMappings mappings() {
return mappings;
}
@@ -518,9 +503,9 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
GridDistributedTxMapping m = mappings.get(node.id());
if (m == null)
- mappings.put(node.id(), m = new GridDistributedTxMapping(node));
+ mappings.put(m = new GridDistributedTxMapping(node));
- IgniteTxEntry txEntry = txMap.get(key);
+ IgniteTxEntry txEntry = entry(key);
assert txEntry != null;
@@ -534,26 +519,10 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/**
- * Adds keys mapping.
- *
- * @param n Mapped node.
- * @param mappedKeys Mapped keys.
+ * @return Non-null entry if tx has only one write entry.
*/
- private void addKeyMapping(ClusterNode n, Iterable<IgniteTxKey> mappedKeys) {
- GridDistributedTxMapping m = mappings.get(n.id());
-
- if (m == null)
- mappings.put(n.id(), m = new GridDistributedTxMapping(n));
-
- for (IgniteTxKey key : mappedKeys) {
- IgniteTxEntry txEntry = txMap.get(key);
-
- assert txEntry != null;
-
- txEntry.nodeId(n.id());
-
- m.add(txEntry);
- }
+ @Nullable IgniteTxEntry singleWrite() {
+ return txState.singleWrite();
}
/**
@@ -567,7 +536,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
GridDistributedTxMapping m = mappings.get(n.id());
if (m == null) {
- m = F.addIfAbsent(mappings, n.id(), new GridDistributedTxMapping(n));
+ mappings.put(m = new GridDistributedTxMapping(n));
m.near(map.near());
@@ -575,8 +544,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
m.markExplicitLock();
}
- assert m != null;
-
for (IgniteTxEntry entry : map.entries())
m.add(entry);
}
@@ -588,6 +555,25 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
}
/**
+ * @param map Mapping.
+ * @param entry Entry.
+ */
+ void addSingleEntryMapping(GridDistributedTxMapping map, IgniteTxEntry entry) {
+ ClusterNode n = map.node();
+
+ GridDistributedTxMapping m = new GridDistributedTxMapping(n);
+
+ mappings.put(m);
+
+ m.near(map.near());
+
+ if (map.explicitLock())
+ m.markExplicitLock();
+
+ m.add(entry);
+ }
+
+ /**
* @param nodeId Node ID to mark with explicit lock.
* @return {@code True} if mapping was found.
*/
@@ -623,8 +609,23 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
Collection<GridCacheVersion> committedVers,
Collection<GridCacheVersion> rolledbackVers)
{
- Collection<IgniteTxEntry> entries = F.concat(false, mapping.writes(), mapping.reads());
+ readyNearLocks(mapping.writes(), mapping.dhtVersion(), pendingVers, committedVers, rolledbackVers);
+ readyNearLocks(mapping.reads(), mapping.dhtVersion(), pendingVers, committedVers, rolledbackVers);
+ }
+ /**
+ * @param entries Entries.
+ * @param dhtVer DHT version.
+ * @param pendingVers Pending versions.
+ * @param committedVers Committed versions.
+ * @param rolledbackVers Rolled back versions.
+ */
+ void readyNearLocks(Collection<IgniteTxEntry> entries,
+ GridCacheVersion dhtVer,
+ Collection<GridCacheVersion> pendingVers,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers)
+ {
for (IgniteTxEntry txEntry : entries) {
while (true) {
GridCacheContext cacheCtx = txEntry.cached().context();
@@ -637,8 +638,13 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
// Handle explicit locks.
GridCacheVersion explicit = txEntry.explicitVersion();
- if (explicit == null)
- entry.readyNearLock(xidVer, mapping.dhtVersion(), committedVers, rolledbackVers, pendingVers);
+ if (explicit == null) {
+ entry.readyNearLock(xidVer,
+ dhtVer,
+ committedVers,
+ rolledbackVers,
+ pendingVers);
+ }
break;
}
@@ -871,7 +877,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
* @param writes Write entries.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this is last prepare request.
- * @param lastBackups IDs of backup nodes receiving last prepare request.
* @return Future that will be completed when locks are acquired.
*/
@SuppressWarnings("TypeMayBeWeakened")
@@ -879,8 +884,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
@Nullable Collection<IgniteTxEntry> reads,
@Nullable Collection<IgniteTxEntry> writes,
Map<UUID, Collection<UUID>> txNodes,
- boolean last,
- Collection<UUID> lastBackups
+ boolean last
) {
if (state() != PREPARING) {
if (timedOut())
@@ -901,8 +905,7 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
IgniteUuid.randomUuid(),
Collections.<IgniteTxKey, GridCacheVersion>emptyMap(),
last,
- needReturnValue() && implicit(),
- lastBackups);
+ needReturnValue() && implicit());
try {
// At this point all the entries passed in must be enlisted in transaction because this is an
@@ -1274,6 +1277,6 @@ public class GridNearTxLocal extends GridDhtTxLocalAdapter {
/** {@inheritDoc} */
@Override public String toString() {
- return S.toString(GridNearTxLocal.class, this, "mappings", mappings.keySet(), "super", super.toString());
+ return S.toString(GridNearTxLocal.class, this, "mappings", mappings, "super", super.toString());
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
index 456d726..798635a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxPrepareRequest.java
@@ -99,7 +99,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
* @param near {@code True} if mapping is for near caches.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this last prepare request for node.
- * @param lastBackups IDs of backup nodes receiving last prepare request during this prepare.
* @param onePhaseCommit One phase commit flag.
* @param retVal Return value flag.
* @param implicitSingle Implicit single flag.
@@ -118,7 +117,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
boolean near,
Map<UUID, Collection<UUID>> txNodes,
boolean last,
- Collection<UUID> lastBackups,
boolean onePhaseCommit,
boolean retVal,
boolean implicitSingle,
@@ -137,7 +135,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
this.topVer = topVer;
this.near = near;
this.last = last;
- this.lastBackups = lastBackups;
this.retVal = retVal;
this.implicitSingle = implicitSingle;
this.explicitLock = explicitLock;
@@ -153,12 +150,6 @@ public class GridNearTxPrepareRequest extends GridDistributedTxPrepareRequest {
return firstClientReq;
}
- /**
- * @return IDs of backup nodes receiving last prepare request during this prepare.
- */
- public Collection<UUID> lastBackups() {
- return lastBackups;
- }
/**
* @return {@code True} if this last prepare request for node.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
index 87c68b2..d078df4 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxRemote.java
@@ -34,10 +34,12 @@ import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxRemoteAdapter;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteStateImpl;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.GridLeanMap;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.transactions.TransactionConcurrency;
import org.apache.ignite.transactions.TransactionIsolation;
import org.jetbrains.annotations.Nullable;
@@ -74,7 +76,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
* @param ldr Class loader.
* @param nodeId Node ID.
* @param nearNodeId Near node ID.
- * @param rmtThreadId Remote thread ID.
* @param xidVer XID version.
* @param commitVer Commit version.
* @param sys System flag.
@@ -92,7 +93,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
ClassLoader ldr,
UUID nodeId,
UUID nearNodeId,
- long rmtThreadId,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
boolean sys,
@@ -109,8 +109,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
super(
ctx,
nodeId,
- rmtThreadId,
- xidVer,
+ xidVer,
commitVer,
sys,
plc,
@@ -127,10 +126,10 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
this.nearNodeId = nearNodeId;
- readMap = Collections.emptyMap();
+ int writeSize = writeEntries != null ? Math.max(txSize, writeEntries.size()) : txSize;
- writeMap = new LinkedHashMap<>(
- writeEntries != null ? Math.max(txSize, writeEntries.size()) : txSize, 1.0f);
+ txState = new IgniteTxRemoteStateImpl(Collections.<IgniteTxKey, IgniteTxEntry>emptyMap(),
+ U.<IgniteTxKey, IgniteTxEntry>newLinkedHashMap(writeSize));
if (writeEntries != null) {
for (IgniteTxEntry entry : writeEntries) {
@@ -147,7 +146,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
* @param nodeId Node ID.
* @param nearNodeId Near node ID.
* @param nearXidVer Near transaction ID.
- * @param rmtThreadId Remote thread ID.
* @param xidVer XID version.
* @param commitVer Commit version.
* @param sys System flag.
@@ -163,7 +161,6 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
UUID nodeId,
UUID nearNodeId,
GridCacheVersion nearXidVer,
- long rmtThreadId,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
boolean sys,
@@ -179,8 +176,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
super(
ctx,
nodeId,
- rmtThreadId,
- xidVer,
+ xidVer,
commitVer,
sys,
plc,
@@ -198,8 +194,8 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
this.nearXidVer = nearXidVer;
this.nearNodeId = nearNodeId;
- readMap = new LinkedHashMap<>(1, 1.0f);
- writeMap = new LinkedHashMap<>(txSize, 1.0f);
+ txState = new IgniteTxRemoteStateImpl(U.<IgniteTxKey, IgniteTxEntry>newLinkedHashMap(1),
+ U.<IgniteTxKey, IgniteTxEntry>newLinkedHashMap(txSize));
}
/** {@inheritDoc} */
@@ -322,7 +318,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
// Initialize cache entry.
entry.cached(cached);
- writeMap.put(entry.txKey(), entry);
+ txState.addWriteEntry(entry.txKey(), entry);
addExplicit(entry);
@@ -391,7 +387,7 @@ public class GridNearTxRemote extends GridDistributedTxRemoteAdapter {
drVer,
skipStore);
- writeMap.put(key, txEntry);
+ txState.addWriteEntry(key, txEntry);
return true;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java
new file mode 100644
index 0000000..0465510
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappings.java
@@ -0,0 +1,75 @@
+/*
+ * 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.cache.distributed.near;
+
+import java.util.Collection;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public interface IgniteTxMappings {
+ /**
+ * Clears this mappings.
+ */
+ public void clear();
+
+ /**
+ * @return {@code True} if there are no mappings.
+ */
+ public boolean empty();
+
+ /**
+ * @param nodeId Node ID.
+ * @return Node mapping.
+ */
+ @Nullable public GridDistributedTxMapping get(UUID nodeId);
+
+ /**
+ * @param mapping Mapping.
+ */
+ public void put(GridDistributedTxMapping mapping);
+
+ /**
+ * @param nodeId Node ID.
+ * @return Removed mapping.
+ */
+ @Nullable public GridDistributedTxMapping remove(UUID nodeId);
+
+ /**
+ * @return Mapping for local node.
+ */
+ @Nullable public GridDistributedTxMapping localMapping();
+
+ /**
+ * @return Non null instance if this mappings contain only one mapping.
+ */
+ @Nullable public GridDistributedTxMapping singleMapping();
+
+ /**
+ * @return All mappings.
+ */
+ public Collection<GridDistributedTxMapping> mappings();
+
+ /**
+ * @return {@code True} if this is single mapping.
+ */
+ public boolean single();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java
new file mode 100644
index 0000000..7dec7af
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsImpl.java
@@ -0,0 +1,92 @@
+/*
+ * 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.cache.distributed.near;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.apache.ignite.internal.util.typedef.F;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+import org.jsr166.ConcurrentHashMap8;
+
+/**
+ *
+ */
+public class IgniteTxMappingsImpl implements IgniteTxMappings {
+ /** */
+ private final Map<UUID, GridDistributedTxMapping> mappings = new ConcurrentHashMap8<>();
+
+ /** {@inheritDoc} */
+ @Override public void clear() {
+ mappings.clear();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return mappings.isEmpty();
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping get(UUID nodeId) {
+ return mappings.get(nodeId);
+ }
+
+ /** {@inheritDoc} */
+ @Override public void put(GridDistributedTxMapping mapping) {
+ mappings.put(mapping.node().id(), mapping);
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping remove(UUID nodeId) {
+ return mappings.remove(nodeId);
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping localMapping() {
+ for (GridDistributedTxMapping m : mappings.values()) {
+ if (m.node().isLocal())
+ return m;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean single() {
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping singleMapping() {
+ assert mappings.size() == 1 : mappings;
+
+ return F.firstValue(mappings);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridDistributedTxMapping> mappings() {
+ return mappings.values();
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxMappingsImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java
new file mode 100644
index 0000000..fc15592
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/IgniteTxMappingsSingleImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.cache.distributed.near;
+
+import java.util.Collection;
+import java.util.UUID;
+import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *
+ */
+public class IgniteTxMappingsSingleImpl implements IgniteTxMappings {
+ /** */
+ private volatile GridDistributedTxMapping mapping;
+
+ /** {@inheritDoc} */
+ @Override public void clear() {
+ mapping = null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return mapping == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping get(UUID nodeId) {
+ GridDistributedTxMapping mapping0 = mapping;
+
+ return (mapping0 != null && mapping0.node().id().equals(nodeId)) ? mapping0 : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void put(GridDistributedTxMapping mapping) {
+ assert this.mapping == null;
+
+ this.mapping = mapping;
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDistributedTxMapping remove(UUID nodeId) {
+ GridDistributedTxMapping mapping0 = mapping;
+
+ if (mapping0 != null && mapping0.node().id().equals(nodeId)) {
+ this.mapping = null;
+
+ return mapping0;
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping localMapping() {
+ GridDistributedTxMapping mapping0 = mapping;
+
+ if (mapping0 != null && mapping0.node().isLocal())
+ return mapping0;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean single() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridDistributedTxMapping singleMapping() {
+ return mapping;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<GridDistributedTxMapping> mappings() {
+ assert false;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxMappingsSingleImpl.class, this);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
index 94af6bb..f5f99f5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteInternalTx.java
@@ -275,9 +275,9 @@ public interface IgniteInternalTx extends AutoCloseable, GridTimeoutObject {
public boolean implicitSingle();
/**
- * @return Collection of cache IDs involved in this transaction.
+ * @return Transaction state.
*/
- public Collection<Integer> activeCacheIds();
+ public IgniteTxState txState();
/**
* @return {@code true} or {@code false} if the deployment is enabled or disabled for all active caches involved
@@ -669,14 +669,6 @@ public interface IgniteInternalTx extends AutoCloseable, GridTimeoutObject {
public boolean serializable();
/**
- * Checks whether given key has been removed within transaction.
- *
- * @param key Key to check.
- * @return {@code True} if key has been removed.
- */
- public boolean removed(IgniteTxKey key);
-
- /**
* Gets allowed remaining time for this transaction.
*
* @return Remaining time.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
index eb2ca2c..6a0f8ab 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxAdapter.java
@@ -22,7 +22,6 @@ import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.ObjectStreamException;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -50,7 +49,6 @@ import org.apache.ignite.internal.processors.cache.GridCacheOperation;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.near.GridNearCacheEntry;
-import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
import org.apache.ignite.internal.processors.cache.version.GridCachePlainVersionedEntry;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
@@ -120,10 +118,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
@GridToStringInclude
protected boolean implicit;
- /** Implicit with one key flag. */
- @GridToStringInclude
- protected boolean implicitSingle;
-
/** Local flag. */
@GridToStringInclude
protected boolean loc;
@@ -262,7 +256,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
* @param cctx Cache registry.
* @param xidVer Transaction ID.
* @param implicit Implicit flag.
- * @param implicitSingle Implicit with one key flag.
* @param loc Local flag.
* @param sys System transaction flag.
* @param plc IO policy.
@@ -275,7 +268,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
GridCacheSharedContext<?, ?> cctx,
GridCacheVersion xidVer,
boolean implicit,
- boolean implicitSingle,
boolean loc,
boolean sys,
byte plc,
@@ -295,7 +287,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
this.cctx = cctx;
this.xidVer = xidVer;
this.implicit = implicit;
- this.implicitSingle = implicitSingle;
this.loc = loc;
this.sys = sys;
this.plc = plc;
@@ -362,7 +353,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
this.taskNameHash = taskNameHash;
implicit = false;
- implicitSingle = false;
loc = false;
if (log == null)
@@ -421,45 +411,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
/** {@inheritDoc} */
@Override public boolean storeUsed() {
- if (!storeEnabled())
- return false;
-
- Collection<Integer> cacheIds = activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- for (int cacheId : cacheIds) {
- CacheStoreManager store = cctx.cacheContext(cacheId).store();
-
- if (store.configured())
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Store manager for current transaction.
- *
- * @return Store manager.
- */
- protected Collection<CacheStoreManager> stores() {
- Collection<Integer> cacheIds = activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- Collection<CacheStoreManager> stores = new ArrayList<>(cacheIds.size());
-
- for (int cacheId : cacheIds) {
- CacheStoreManager store = cctx.cacheContext(cacheId).store();
-
- if (store.configured())
- stores.add(store);
- }
-
- return stores;
- }
-
- return null;
+ return storeEnabled() && txState().storeUsed(cctx);
}
/**
@@ -645,7 +597,7 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
/** {@inheritDoc} */
@Override public boolean implicitSingle() {
- return implicitSingle;
+ return txState().implicitSingle();
}
/** {@inheritDoc} */
@@ -1758,11 +1710,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
}
/** {@inheritDoc} */
- @Override public Collection<Integer> activeCacheIds() {
- throw new IllegalStateException("Deserialized transaction can only be used as read-only.");
- }
-
- /** {@inheritDoc} */
@Override public boolean activeCachesDeploymentEnabled() {
return false;
}
@@ -1877,6 +1824,11 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
}
/** {@inheritDoc} */
+ @Override public IgniteTxState txState() {
+ return null;
+ }
+
+ /** {@inheritDoc} */
@Override public Collection<UUID> masterNodeIds() {
return null;
}
@@ -2150,11 +2102,6 @@ public abstract class IgniteTxAdapter extends GridMetadataAwareAdapter
}
/** {@inheritDoc} */
- @Override public boolean removed(IgniteTxKey key) {
- return false;
- }
-
- /** {@inheritDoc} */
@Override public long remainingTime() throws IgniteTxTimeoutCheckedException {
return 0;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
index 570aa48..0e5657b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxHandler.java
@@ -216,8 +216,7 @@ public class IgniteTxHandler {
req.reads(),
req.writes(),
req.transactionNodes(),
- req.last(),
- req.lastBackups());
+ req.last());
if (locTx.isRollbackOnly())
locTx.rollbackAsync();
@@ -398,7 +397,6 @@ public class IgniteTxHandler {
if (req.onePhaseCommit()) {
assert req.last();
- assert F.isEmpty(req.lastBackups()) || req.lastBackups().size() <= 1;
tx.onePhaseCommit(true);
}
@@ -413,8 +411,7 @@ public class IgniteTxHandler {
req.messageId(),
req.miniId(),
req.transactionNodes(),
- req.last(),
- req.lastBackups());
+ req.last());
if (tx.isRollbackOnly()) {
try {
@@ -1091,12 +1088,13 @@ public class IgniteTxHandler {
GridDhtTxRemote tx = ctx.tm().tx(req.version());
if (tx == null) {
+ boolean single = req.last() && req.writes().size() == 1;
+
tx = new GridDhtTxRemote(
ctx,
req.nearNodeId(),
req.futureId(),
nodeId,
- req.threadId(),
req.topologyVersion(),
req.version(),
null,
@@ -1110,7 +1108,8 @@ public class IgniteTxHandler {
req.nearXidVersion(),
req.transactionNodes(),
req.subjectId(),
- req.taskNameHash());
+ req.taskNameHash(),
+ single);
tx.writeVersion(req.writeVersion());
@@ -1138,7 +1137,7 @@ public class IgniteTxHandler {
tx.transactionNodes(req.transactionNodes());
}
- if (!tx.isSystemInvalidate() && !F.isEmpty(req.writes())) {
+ if (!tx.isSystemInvalidate()) {
int idx = 0;
for (IgniteTxEntry entry : req.writes()) {
@@ -1236,7 +1235,6 @@ public class IgniteTxHandler {
ldr,
nodeId,
req.nearNodeId(),
- req.threadId(),
req.version(),
null,
req.system(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
new file mode 100644
index 0000000..5f48469
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxImplicitSingleStateImpl.java
@@ -0,0 +1,259 @@
+/*
+ * 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.cache.transactions;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import org.apache.ignite.IgniteCheckedException;
+import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
+import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
+import org.apache.ignite.internal.processors.cache.store.CacheStoreManager;
+import org.apache.ignite.internal.util.future.GridFutureAdapter;
+import org.apache.ignite.internal.util.typedef.internal.CU;
+import org.apache.ignite.internal.util.typedef.internal.S;
+import org.apache.ignite.internal.util.typedef.internal.U;
+import org.jetbrains.annotations.Nullable;
+
+import static org.apache.ignite.cache.CacheWriteSynchronizationMode.FULL_SYNC;
+
+/**
+ *
+ */
+public class IgniteTxImplicitSingleStateImpl extends IgniteTxLocalStateAdapter {
+ /** */
+ private GridCacheContext cacheCtx;
+
+ /** */
+ private IgniteTxEntry entry;
+
+ /** */
+ private boolean init;
+
+ /** {@inheritDoc} */
+ @Override public void addActiveCache(GridCacheContext ctx, IgniteTxLocalAdapter tx)
+ throws IgniteCheckedException {
+ assert cacheCtx == null : "Cache already set [cur=" + cacheCtx.name() + ", new=" + ctx.name() + ']';
+
+ this.cacheCtx = ctx;
+
+ tx.activeCachesDeploymentEnabled(cacheCtx.deploymentEnabled());
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public GridCacheContext singleCacheContext(GridCacheSharedContext cctx) {
+ return cacheCtx;
+ }
+
+ /** {@inheritDoc} */
+ @Nullable @Override public Integer firstCacheId() {
+ return cacheCtx != null ? cacheCtx.cacheId() : null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void awaitLastFut(GridCacheSharedContext ctx) {
+ if (cacheCtx == null)
+ return;
+
+ cacheCtx.cache().awaitLastFut();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean implicitSingle() {
+ return true;
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteCheckedException validateTopology(GridCacheSharedContext cctx, GridDhtTopologyFuture topFut) {
+ if (cacheCtx == null)
+ return null;
+
+ Throwable err = topFut.validateCache(cacheCtx);
+
+ if (err != null) {
+ return new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
+ U.maskName(cacheCtx.name()));
+ }
+
+ if (CU.affinityNodes(cacheCtx, topFut.topologyVersion()).isEmpty()) {
+ return new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
+ "partition nodes left the grid): " + cacheCtx.name());
+ }
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean sync(GridCacheSharedContext cctx) {
+ return cacheCtx != null && cacheCtx.config().getWriteSynchronizationMode() == FULL_SYNC;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasNearCache(GridCacheSharedContext cctx) {
+ return cacheCtx != null && cacheCtx.isNear();
+ }
+
+ /** {@inheritDoc} */
+ @Override public GridDhtTopologyFuture topologyReadLock(GridCacheSharedContext cctx, GridFutureAdapter<?> fut) {
+ if (cacheCtx == null || cacheCtx.isLocal())
+ return cctx.exchange().lastTopologyFuture();
+
+ cacheCtx.topology().readLock();
+
+ if (cacheCtx.topology().stopping()) {
+ fut.onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
+ cacheCtx.name()));
+
+ return null;
+ }
+
+ return cacheCtx.topology().topologyVersionFuture();
+ }
+
+ /** {@inheritDoc} */
+ @Override public void topologyReadUnlock(GridCacheSharedContext cctx) {
+ if (cacheCtx == null || cacheCtx.isLocal())
+ return;
+
+ cacheCtx.topology().readUnlock();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean storeUsed(GridCacheSharedContext cctx) {
+ if (cacheCtx == null)
+ return false;
+
+ CacheStoreManager store = cacheCtx.store();
+
+ return store.configured();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<CacheStoreManager> stores(GridCacheSharedContext cctx) {
+ if (cacheCtx == null)
+ return null;
+
+ CacheStoreManager store = cacheCtx.store();
+
+ if (store.configured())
+ return Collections.singleton(store);
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void onTxEnd(GridCacheSharedContext cctx, IgniteInternalTx tx, boolean commit) {
+ if (cacheCtx != null)
+ onTxEnd(cacheCtx, tx, commit);
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry entry(IgniteTxKey key) {
+ if (entry != null && entry.txKey().equals(key))
+ return entry;
+
+ return null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean hasWriteKey(IgniteTxKey key) {
+ return entry != null && entry.txKey().equals(key);
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> readSet() {
+ return Collections.emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Set<IgniteTxKey> writeSet() {
+ return entry != null ? Collections.singleton(entry.txKey()) : Collections.<IgniteTxKey>emptySet();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> writeEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> readEntries() {
+ return Collections.emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
+ return entry != null ? Collections.singletonMap(entry.txKey(), entry) :
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
+ return Collections.emptyMap();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean empty() {
+ return entry == null;
+ }
+
+ /** {@inheritDoc} */
+ @Override public Collection<IgniteTxEntry> allEntries() {
+ return entry != null ? Collections.singletonList(entry) : Collections.<IgniteTxEntry>emptyList();
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean init(int txSize) {
+ if (!init) {
+ init = true;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /** {@inheritDoc} */
+ @Override public boolean initialized() {
+ return init;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void addEntry(IgniteTxEntry entry) {
+ assert this.entry == null : "Entry already set [cur=" + this.entry + ", new=" + entry + ']';
+
+ this.entry = entry;
+ }
+
+ /** {@inheritDoc} */
+ @Override public void seal() {
+ // No-op.
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxEntry singleWrite() {
+ return entry;
+ }
+
+ /** {@inheritDoc} */
+ public String toString() {
+ return S.toString(IgniteTxImplicitSingleStateImpl.class, this);
+ }
+}
[2/4] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by sb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
index 2c7bf8a..758f82c 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalAdapter.java
@@ -66,9 +66,7 @@ import org.apache.ignite.internal.processors.dr.GridDrType;
import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxRollbackCheckedException;
import org.apache.ignite.internal.transactions.IgniteTxTimeoutCheckedException;
-import org.apache.ignite.internal.util.F0;
import org.apache.ignite.internal.util.GridLeanMap;
-import org.apache.ignite.internal.util.GridLeanSet;
import org.apache.ignite.internal.util.future.GridEmbeddedFuture;
import org.apache.ignite.internal.util.future.GridFinishedFuture;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
@@ -123,18 +121,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** */
private static final long serialVersionUID = 0L;
- /** Per-transaction read map. */
- @GridToStringInclude
- protected Map<IgniteTxKey, IgniteTxEntry> txMap;
-
- /** Read view on transaction map. */
- @GridToStringExclude
- protected IgniteTxMap readView;
-
- /** Write view on transaction map. */
- @GridToStringExclude
- protected IgniteTxMap writeView;
-
/** Minimal version encountered (either explicit lock or XID of this transaction). */
protected GridCacheVersion minVer;
@@ -156,9 +142,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** Commit error. */
protected AtomicReference<Throwable> commitErr = new AtomicReference<>();
- /** Active cache IDs. */
- protected Set<Integer> activeCacheIds = new HashSet<>();
-
/** Need return value. */
protected boolean needRetVal;
@@ -168,6 +151,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** Flag indicating whether deployment is enabled for caches from this transaction or not. */
private boolean depEnabled;
+ /** */
+ @GridToStringInclude
+ protected IgniteTxLocalState txState;
+
/**
* Empty constructor required for {@link Externalizable}.
*/
@@ -209,7 +196,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cctx,
xidVer,
implicit,
- implicitSingle,
/*local*/true,
sys,
plc,
@@ -225,6 +211,13 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
);
minVer = xidVer;
+
+ txState = implicitSingle ? new IgniteTxImplicitSingleStateImpl() : new IgniteTxStateImpl();
+ }
+
+ /** {@inheritDoc} */
+ @Override public IgniteTxState txState() {
+ return txState;
}
/**
@@ -246,7 +239,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public boolean empty() {
- return txMap.isEmpty();
+ return txState.empty();
}
/** {@inheritDoc} */
@@ -267,16 +260,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public boolean onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner) {
assert false;
- return false;
- }
- /**
- * Gets collection of active cache IDs for this transaction.
- *
- * @return Collection of active cache IDs.
- */
- @Override public Collection<Integer> activeCacheIds() {
- return activeCacheIds;
+ return false;
}
/** {@inheritDoc} */
@@ -284,77 +269,70 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
return depEnabled;
}
+ /**
+ * @param depEnabled Flag indicating whether deployment is enabled for caches from this transaction or not.
+ */
+ public void activeCachesDeploymentEnabled(boolean depEnabled) {
+ this.depEnabled = depEnabled;
+ }
+
/** {@inheritDoc} */
@Override public boolean isStarted() {
- return txMap != null;
+ return txState.initialized();
}
/** {@inheritDoc} */
@Override public boolean hasWriteKey(IgniteTxKey key) {
- return writeView.containsKey(key);
+ return txState.hasWriteKey(key);
}
/**
* @return Transaction read set.
*/
@Override public Set<IgniteTxKey> readSet() {
- return txMap == null ? Collections.<IgniteTxKey>emptySet() : readView.keySet();
+ return txState.readSet();
}
/**
* @return Transaction write set.
*/
@Override public Set<IgniteTxKey> writeSet() {
- return txMap == null ? Collections.<IgniteTxKey>emptySet() : writeView.keySet();
- }
-
- /** {@inheritDoc} */
- @Override public boolean removed(IgniteTxKey key) {
- if (txMap == null)
- return false;
-
- IgniteTxEntry e = txMap.get(key);
-
- return e != null && e.op() == DELETE;
+ return txState.writeSet();
}
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
- return readView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : readView;
+ return txState.readMap();
}
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
- return writeView == null ? Collections.<IgniteTxKey, IgniteTxEntry>emptyMap() : writeView;
+ return txState.writeMap();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> allEntries() {
- return txMap == null ? Collections.<IgniteTxEntry>emptySet() : txMap.values();
+ return txState.allEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> readEntries() {
- return readView == null ? Collections.<IgniteTxEntry>emptyList() : readView.values();
+ return txState.readEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> writeEntries() {
- return writeView == null ? Collections.<IgniteTxEntry>emptyList() : writeView.values();
+ return txState.writeEntries();
}
/** {@inheritDoc} */
@Nullable @Override public IgniteTxEntry entry(IgniteTxKey key) {
- return txMap == null ? null : txMap.get(key);
+ return txState.entry(key);
}
/** {@inheritDoc} */
@Override public void seal() {
- if (readView != null)
- readView.seal();
-
- if (writeView != null)
- writeView.seal();
+ txState.seal();
}
/** {@inheritDoc} */
@@ -409,7 +387,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
KeyCacheObject key,
CacheEntryPredicate[] filter
) throws GridCacheFilterFailedException {
- IgniteTxEntry e = txMap == null ? null : txMap.get(cacheCtx.txKey(key));
+ IgniteTxEntry e = entry(cacheCtx.txKey(key));
if (e != null) {
// We should look at tx entry previous value. If this is a user peek then previous
@@ -652,7 +630,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (!storeEnabled() || internal())
return;
- Collection<CacheStoreManager> stores = stores();
+ Collection<CacheStoreManager> stores = txState.stores(cctx);
if (stores == null || stores.isEmpty())
return;
@@ -854,7 +832,9 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
checkValid();
- boolean empty = F.isEmpty(near() ? txMap : writeMap());
+ Collection<IgniteTxEntry> commitEntries = near() ? allEntries() : writeEntries();
+
+ boolean empty = F.isEmpty(commitEntries);
// Register this transaction as completed prior to write-phase to
// ensure proper lock ordering for removed entries.
@@ -874,7 +854,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/*
* Commit to cache. Note that for 'near' transaction we loop through all the entries.
*/
- for (IgniteTxEntry txEntry : (near() ? allEntries() : writeEntries())) {
+ for (IgniteTxEntry txEntry : commitEntries) {
GridCacheContext cacheCtx = txEntry.context();
GridDrType drType = cacheCtx.isDrEnabled() ? DR_PRIMARY : DR_NONE;
@@ -1282,7 +1262,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
cctx.tm().rollbackTx(this);
if (!internal()) {
- Collection<CacheStoreManager> stores = stores();
+ Collection<CacheStoreManager> stores = txState.stores(cctx);
if (stores != null && !stores.isEmpty()) {
assert isWriteToStoreFromDhtValid(stores) :
@@ -1582,25 +1562,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
- * Adds skipped key.
- *
- * @param skipped Skipped set (possibly {@code null}).
- * @param key Key to add.
- * @return Skipped set.
- */
- private Set<KeyCacheObject> skip(Set<KeyCacheObject> skipped, KeyCacheObject key) {
- if (skipped == null)
- skipped = new GridLeanSet<>();
-
- skipped.add(key);
-
- if (log.isDebugEnabled())
- log.debug("Added key to skipped set: " + key);
-
- return skipped;
- }
-
- /**
* Loads all missed keys for
* {@link #getAllAsync(GridCacheContext, Collection, boolean, boolean, boolean, boolean)} method.
*
@@ -1954,6 +1915,24 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
+ @Override public <K, V> IgniteInternalFuture<GridCacheReturn> putAsync(
+ GridCacheContext cacheCtx,
+ K key,
+ V val,
+ boolean retval,
+ CacheEntryPredicate[] filter) {
+ return putAsync0(cacheCtx, key, val, null, null, retval, filter);
+ }
+
+ /** {@inheritDoc} */
+ @Override public <K, V> IgniteInternalFuture<GridCacheReturn> invokeAsync(GridCacheContext cacheCtx,
+ K key,
+ EntryProcessor<K, V, Object> entryProcessor,
+ Object... invokeArgs) {
+ return (IgniteInternalFuture)putAsync0(cacheCtx, key, null, entryProcessor, invokeArgs, true, null);
+ }
+
+ /** {@inheritDoc} */
@Override public IgniteInternalFuture<?> putAllDrAsync(
GridCacheContext cacheCtx,
Map<KeyCacheObject, GridCacheDrInfo> drMap
@@ -2009,12 +1988,88 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param cacheCtx Cache context.
+ * @param cacheKey Key to enlist.
+ * @param val Value.
+ * @param expiryPlc Explicitly specified expiry policy for entry.
+ * @param entryProcessor Entry processor (for invoke operation).
+ * @param invokeArgs Optional arguments for EntryProcessor.
+ * @param retval Flag indicating whether a value should be returned.
+ * @param lockOnly If {@code true}, then entry will be enlisted as noop.
+ * @param filter User filters.
+ * @param ret Return value.
+ * @param skipStore Skip store flag.
+ * @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
+ * @return Future for entry values loading.
+ */
+ private <K, V> IgniteInternalFuture<Void> enlistWrite(
+ final GridCacheContext cacheCtx,
+ KeyCacheObject cacheKey,
+ Object val,
+ @Nullable ExpiryPolicy expiryPlc,
+ @Nullable EntryProcessor<K, V, Object> entryProcessor,
+ @Nullable Object[] invokeArgs,
+ final boolean retval,
+ boolean lockOnly,
+ final CacheEntryPredicate[] filter,
+ final GridCacheReturn ret,
+ boolean skipStore,
+ final boolean singleRmv) {
+ try {
+ addActiveCache(cacheCtx);
+
+ final boolean hasFilters = !F.isEmptyOrNulls(filter) && !F.isAlwaysTrue(filter);
+ final boolean needVal = singleRmv || retval || hasFilters;
+ final boolean needReadVer = needVal && (serializable() && optimistic());
+
+ if (entryProcessor != null)
+ transform = true;
+
+ boolean loadMissed = enlistWriteEntry(cacheCtx,
+ cacheKey,
+ val,
+ entryProcessor,
+ invokeArgs,
+ expiryPlc,
+ retval,
+ lockOnly,
+ filter,
+ /*drVer*/null,
+ /*drTtl*/-1L,
+ /*drExpireTime*/-1L,
+ ret,
+ /*enlisted*/null,
+ skipStore,
+ singleRmv,
+ hasFilters,
+ needVal,
+ needReadVer);
+
+ if (loadMissed) {
+ return loadMissing(cacheCtx,
+ Collections.singleton(cacheKey),
+ filter,
+ ret,
+ needReadVer,
+ singleRmv,
+ hasFilters,
+ skipStore,
+ retval);
+ }
+
+ return new GridFinishedFuture<>();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
+ }
+ }
+
+ /**
* Internal routine for <tt>putAll(..)</tt>
*
* @param cacheCtx Cache context.
* @param keys Keys to enlist.
* @param expiryPlc Explicitly specified expiry policy for entry.
- * @param implicit Implicit flag.
* @param lookup Value lookup map ({@code null} for remove).
* @param invokeMap Map with entry processors for invoke operation.
* @param invokeArgs Optional arguments for EntryProcessor.
@@ -2027,13 +2082,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @param drRmvMap DR remove map (optional).
* @param skipStore Skip store flag.
* @param singleRmv {@code True} for single key remove operation ({@link Cache#remove(Object)}.
- * @return Future with skipped keys (the ones that didn't pass filter for pessimistic transactions).
+ * @return Future for missing values loading.
*/
- private <K, V> IgniteInternalFuture<Set<KeyCacheObject>> enlistWrite(
+ private <K, V> IgniteInternalFuture<Void> enlistWrite(
final GridCacheContext cacheCtx,
Collection<?> keys,
@Nullable ExpiryPolicy expiryPlc,
- boolean implicit,
@Nullable Map<?, ?> lookup,
@Nullable Map<?, EntryProcessor<K, V, Object>> invokeMap,
@Nullable Object[] invokeArgs,
@@ -2056,8 +2110,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
return new GridFinishedFuture<>(e);
}
- Set<KeyCacheObject> skipped = null;
-
boolean rmv = lookup == null && invokeMap == null;
Set<KeyCacheObject> missedForLoad = null;
@@ -2115,345 +2167,441 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
- IgniteTxKey txKey = cacheCtx.txKey(cacheKey);
-
- IgniteTxEntry txEntry = entry(txKey);
-
- // First time access.
- if (txEntry == null) {
- while (true) {
- GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topologyVersion());
-
- try {
- entry.unswap(false);
-
- // Check if lock is being explicitly acquired by the same thread.
- if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() &&
- entry.lockedByThread(threadId, xidVer))
- throw new IgniteCheckedException("Cannot access key within transaction if lock is " +
- "externally held [key=" + key + ", entry=" + entry + ", xidVer=" + xidVer +
- ", threadId=" + threadId +
- ", locNodeId=" + cctx.localNodeId() + ']');
-
- CacheObject old = null;
- GridCacheVersion readVer = null;
+ boolean loadMissed = enlistWriteEntry(cacheCtx,
+ cacheKey,
+ val,
+ entryProcessor,
+ invokeArgs,
+ expiryPlc,
+ retval,
+ lockOnly,
+ filter,
+ drVer,
+ drTtl,
+ drExpireTime,
+ ret,
+ enlisted,
+ skipStore,
+ singleRmv,
+ hasFilters,
+ needVal,
+ needReadVer);
+
+ if (loadMissed) {
+ if (missedForLoad == null)
+ missedForLoad = new HashSet<>();
+
+ missedForLoad.add(cacheKey);
+ }
+ }
- if (optimistic() && !implicit()) {
- try {
- if (needReadVer) {
- T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
- entry.innerGetVersioned(this,
- /*swap*/false,
- /*unmarshal*/retval,
- /*metrics*/retval,
- /*events*/retval,
- CU.subjectId(this, cctx),
- entryProcessor,
- resolveTaskName(),
- null) : null;
+ if (missedForLoad != null) {
+ return loadMissing(cacheCtx,
+ missedForLoad,
+ filter,
+ ret,
+ needReadVer,
+ singleRmv,
+ hasFilters,
+ skipStore,
+ retval);
+ }
- if (res != null) {
- old = res.get1();
- readVer = res.get2();
- }
- }
- else {
- old = entry.innerGet(this,
- /*swap*/false,
- /*read-through*/false,
- /*fail-fast*/false,
- /*unmarshal*/retval,
- /*metrics*/retval,
- /*events*/retval,
- /*temporary*/false,
- CU.subjectId(this, cctx),
- entryProcessor,
- resolveTaskName(),
- null);
- }
- }
- catch (ClusterTopologyCheckedException e) {
- entry.context().evicts().touch(entry, topologyVersion());
+ return new GridFinishedFuture<>();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
+ }
+ }
- throw e;
- }
- }
- else
- old = retval ? entry.rawGetOrUnmarshal(false) : entry.rawGet();
+ /**
+ * @param cacheCtx Cache context.
+ * @param keys Keys to load.
+ * @param ret Return value.
+ * @param needReadVer Read version flag.
+ * @param singleRmv {@code True} for single remove operation.
+ * @param hasFilters {@code True} if filters not empty.
+ * @param skipStore Skip store flag.
+ * @param retval Return value flag.
+ * @return Load future.
+ */
+ private IgniteInternalFuture<Void> loadMissing(
+ final GridCacheContext cacheCtx,
+ final Set<KeyCacheObject> keys,
+ final CacheEntryPredicate[] filter,
+ final GridCacheReturn ret,
+ final boolean needReadVer,
+ final boolean singleRmv,
+ final boolean hasFilters,
+ final boolean skipStore,
+ final boolean retval) {
+ GridInClosure3<KeyCacheObject, Object, GridCacheVersion> c =
+ new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
+ @Override public void apply(KeyCacheObject key,
+ @Nullable Object val,
+ @Nullable GridCacheVersion loadVer) {
+ if (log.isDebugEnabled())
+ log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
- if (old != null && hasFilters && !filter(entry.context(), cacheKey, old, filter)) {
- skipped = skip(skipped, cacheKey);
+ IgniteTxEntry e = entry(new IgniteTxKey(key, cacheCtx.cacheId()));
- ret.set(cacheCtx, old, false);
+ assert e != null;
- if (!readCommitted()) {
- // Enlist failed filters as reads for non-read-committed mode,
- // so future ops will get the same values.
- txEntry = addEntry(READ,
- old,
- null,
- null,
- entry,
- null,
- CU.empty0(),
- false,
- -1L,
- -1L,
- null,
- skipStore);
+ if (needReadVer) {
+ assert loadVer != null;
- txEntry.markValid();
+ e.serializableReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
+ }
- if (needReadVer) {
- assert readVer != null;
+ if (singleRmv) {
+ assert !hasFilters && !retval;
+ assert val == null || Boolean.TRUE.equals(val) : val;
- txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
- }
- }
+ ret.set(cacheCtx, null, val != null);
+ }
+ else {
+ CacheObject cacheVal = cacheCtx.toCacheObject(val);
- if (readCommitted())
- cacheCtx.evicts().touch(entry, topologyVersion());
+ if (e.op() == TRANSFORM) {
+ GridCacheVersion ver;
- break; // While.
+ try {
+ ver = e.cached().version();
}
+ catch (GridCacheEntryRemovedException ex) {
+ assert optimistic() : e;
- final GridCacheOperation op = lockOnly ? NOOP : rmv ? DELETE :
- entryProcessor != null ? TRANSFORM : old != null ? UPDATE : CREATE;
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
- txEntry = addEntry(op,
- cacheCtx.toCacheObject(val),
- entryProcessor,
- invokeArgs,
- entry,
- expiryPlc,
- filter,
- true,
- drTtl,
- drExpireTime,
- drVer,
- skipStore);
+ ver = null;
+ }
- if (!implicit() && readCommitted() && !cacheCtx.offheapTiered())
- cacheCtx.evicts().touch(entry, topologyVersion());
+ addInvokeResult(e, cacheVal, ret, ver);
+ }
+ else {
+ boolean success = !hasFilters || isAll(e.context(), key, cacheVal, filter);
- enlisted.add(cacheKey);
+ ret.set(cacheCtx, cacheVal, success);
+ }
+ }
+ }
+ };
- if (!pessimistic() && !implicit()) {
- txEntry.markValid();
+ return loadMissing(
+ cacheCtx,
+ /*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore,
+ /*async*/true,
+ keys,
+ /*skipVals*/singleRmv,
+ needReadVer,
+ c);
+ }
- if (old == null) {
- if (needVal) {
- if (missedForLoad == null)
- missedForLoad = new HashSet<>();
+ /**
+ * @param cacheCtx Cache context.
+ * @param cacheKey Key.
+ * @param val Value.
+ * @param entryProcessor Entry processor.
+ * @param invokeArgs Optional arguments for EntryProcessor.
+ * @param expiryPlc Explicitly specified expiry policy for entry.
+ * @param retval Return value flag.
+ * @param lockOnly
+ * @param filter Filter.
+ * @param drVer DR version.
+ * @param drTtl DR ttl.
+ * @param drExpireTime DR expire time.
+ * @param ret Return value.
+ * @param enlisted Enlisted keys collection.
+ * @param skipStore Skip store flag.
+ * @param singleRmv {@code True} for single remove operation.
+ * @param hasFilters {@code True} if filters not empty.
+ * @param needVal {@code True} if value is needed.
+ * @param needReadVer {@code True} if need read entry version.
+ * @return {@code True} if entry value should be loaded.
+ * @throws IgniteCheckedException If failed.
+ */
+ private boolean enlistWriteEntry(GridCacheContext cacheCtx,
+ final KeyCacheObject cacheKey,
+ final @Nullable Object val,
+ final @Nullable EntryProcessor<?, ?, ?> entryProcessor,
+ final @Nullable Object[] invokeArgs,
+ final @Nullable ExpiryPolicy expiryPlc,
+ final boolean retval,
+ final boolean lockOnly,
+ final CacheEntryPredicate[] filter,
+ final GridCacheVersion drVer,
+ final long drTtl,
+ long drExpireTime,
+ final GridCacheReturn ret,
+ @Nullable final Collection<KeyCacheObject> enlisted,
+ boolean skipStore,
+ boolean singleRmv,
+ boolean hasFilters,
+ final boolean needVal,
+ boolean needReadVer
+ ) throws IgniteCheckedException {
+ boolean loadMissed = false;
- missedForLoad.add(cacheKey);
- }
- else {
- assert !implicit() || !transform : this;
- assert txEntry.op() != TRANSFORM : txEntry;
+ final boolean rmv = val == null && entryProcessor == null;
- if (retval)
- ret.set(cacheCtx, null, true);
- else
- ret.success(true);
- }
- }
- else {
- if (needReadVer) {
- assert readVer != null;
+ IgniteTxKey txKey = cacheCtx.txKey(cacheKey);
- txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
- }
+ IgniteTxEntry txEntry = entry(txKey);
- if (retval && !transform)
- ret.set(cacheCtx, old, true);
- else {
- if (txEntry.op() == TRANSFORM) {
- GridCacheVersion ver;
+ // First time access.
+ if (txEntry == null) {
+ while (true) {
+ GridCacheEntryEx entry = entryEx(cacheCtx, txKey, topologyVersion());
- try {
- ver = entry.version();
- }
- catch (GridCacheEntryRemovedException ex) {
- assert optimistic() : txEntry;
+ try {
+ entry.unswap(false);
+
+ // Check if lock is being explicitly acquired by the same thread.
+ if (!implicit && cctx.kernalContext().config().isCacheSanityCheckEnabled() &&
+ entry.lockedByThread(threadId, xidVer)) {
+ throw new IgniteCheckedException("Cannot access key within transaction if lock is " +
+ "externally held [key=" + CU.value(cacheKey, cacheCtx, false) +
+ ", entry=" + entry +
+ ", xidVer=" + xidVer +
+ ", threadId=" + threadId +
+ ", locNodeId=" + cctx.localNodeId() + ']');
+ }
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version " +
- "[err=" + ex.getMessage() + ']');
+ CacheObject old = null;
+ GridCacheVersion readVer = null;
- ver = null;
- }
+ if (optimistic() && !implicit()) {
+ try {
+ if (needReadVer) {
+ T2<CacheObject, GridCacheVersion> res = primaryLocal(entry) ?
+ entry.innerGetVersioned(this,
+ /*swap*/false,
+ /*unmarshal*/retval,
+ /*metrics*/retval,
+ /*events*/retval,
+ CU.subjectId(this, cctx),
+ entryProcessor,
+ resolveTaskName(),
+ null) : null;
- addInvokeResult(txEntry, old, ret, ver);
- }
- else
- ret.success(true);
- }
+ if (res != null) {
+ old = res.get1();
+ readVer = res.get2();
}
}
- // Pessimistic.
else {
- if (retval && !transform)
- ret.set(cacheCtx, old, true);
- else
- ret.success(true);
+ old = entry.innerGet(this,
+ /*swap*/false,
+ /*read-through*/false,
+ /*fail-fast*/false,
+ /*unmarshal*/retval,
+ /*metrics*/retval,
+ /*events*/retval,
+ /*temporary*/false,
+ CU.subjectId(this, cctx),
+ entryProcessor,
+ resolveTaskName(),
+ null);
}
-
- break; // While.
}
- catch (GridCacheEntryRemovedException ignore) {
- if (log.isDebugEnabled())
- log.debug("Got removed entry in transaction putAll0 method: " + entry);
+ catch (ClusterTopologyCheckedException e) {
+ entry.context().evicts().touch(entry, topologyVersion());
+
+ throw e;
}
}
- }
- else {
- if (entryProcessor == null && txEntry.op() == TRANSFORM)
- throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " +
- "transaction after EntryProcessor is applied): " + key);
+ else
+ old = retval ? entry.rawGetOrUnmarshal(false) : entry.rawGet();
- GridCacheEntryEx entry = txEntry.cached();
+ if (old != null && hasFilters && !filter(entry.context(), cacheKey, old, filter)) {
+ ret.set(cacheCtx, old, false);
- CacheObject v = txEntry.value();
-
- boolean del = txEntry.op() == DELETE && rmv;
+ if (!readCommitted()) {
+ // Enlist failed filters as reads for non-read-committed mode,
+ // so future ops will get the same values.
+ txEntry = addEntry(READ,
+ old,
+ null,
+ null,
+ entry,
+ null,
+ CU.empty0(),
+ false,
+ -1L,
+ -1L,
+ null,
+ skipStore);
- if (!del) {
- if (hasFilters && !filter(entry.context(), cacheKey, v, filter)) {
- skipped = skip(skipped, cacheKey);
+ txEntry.markValid();
- ret.set(cacheCtx, v, false);
+ if (needReadVer) {
+ assert readVer != null;
- continue;
+ txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
+ }
}
- GridCacheOperation op = rmv ? DELETE : entryProcessor != null ? TRANSFORM :
- v != null ? UPDATE : CREATE;
+ if (readCommitted())
+ cacheCtx.evicts().touch(entry, topologyVersion());
- txEntry = addEntry(op,
- cacheCtx.toCacheObject(val),
- entryProcessor,
- invokeArgs,
- entry,
- expiryPlc,
- filter,
- true,
- drTtl,
- drExpireTime,
- drVer,
- skipStore);
+ break; // While.
+ }
+
+ final GridCacheOperation op = lockOnly ? NOOP : rmv ? DELETE :
+ entryProcessor != null ? TRANSFORM : old != null ? UPDATE : CREATE;
+
+ txEntry = addEntry(op,
+ cacheCtx.toCacheObject(val),
+ entryProcessor,
+ invokeArgs,
+ entry,
+ expiryPlc,
+ filter,
+ true,
+ drTtl,
+ drExpireTime,
+ drVer,
+ skipStore);
+ if (!implicit() && readCommitted() && !cacheCtx.offheapTiered())
+ cacheCtx.evicts().touch(entry, topologyVersion());
+
+ if (enlisted != null)
enlisted.add(cacheKey);
- if (txEntry.op() == TRANSFORM) {
- GridCacheVersion ver;
+ if (!pessimistic() && !implicit()) {
+ txEntry.markValid();
- try {
- ver = entry.version();
- }
- catch (GridCacheEntryRemovedException e) {
- assert optimistic() : txEntry;
+ if (old == null) {
+ if (needVal)
+ loadMissed = true;
+ else {
+ assert !implicit() || !transform : this;
+ assert txEntry.op() != TRANSFORM : txEntry;
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
+ if (retval)
+ ret.set(cacheCtx, null, true);
+ else
+ ret.success(true);
+ }
+ }
+ else {
+ if (needReadVer) {
+ assert readVer != null;
- ver = null;
+ txEntry.serializableReadVersion(singleRmv ? SER_READ_NOT_EMPTY_VER : readVer);
}
- addInvokeResult(txEntry, txEntry.value(), ret, ver);
- }
- }
+ if (retval && !transform)
+ ret.set(cacheCtx, old, true);
+ else {
+ if (txEntry.op() == TRANSFORM) {
+ GridCacheVersion ver;
- if (!pessimistic()) {
- txEntry.markValid();
+ try {
+ ver = entry.version();
+ }
+ catch (GridCacheEntryRemovedException ex) {
+ assert optimistic() : txEntry;
+
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version " +
+ "[err=" + ex.getMessage() + ']');
+
+ ver = null;
+ }
+ addInvokeResult(txEntry, old, ret, ver);
+ }
+ else
+ ret.success(true);
+ }
+ }
+ }
+ // Pessimistic.
+ else {
if (retval && !transform)
- ret.set(cacheCtx, v, true);
+ ret.set(cacheCtx, old, true);
else
ret.success(true);
}
- }
+
+ break; // While.
+ }
+ catch (GridCacheEntryRemovedException ignore) {
+ if (log.isDebugEnabled())
+ log.debug("Got removed entry in transaction putAll0 method: " + entry);
+ }
}
}
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
-
- if (missedForLoad != null) {
- final boolean skipVals = singleRmv;
-
- IgniteInternalFuture<Void> fut = loadMissing(
- cacheCtx,
- /*read through*/cacheCtx.config().isLoadPreviousValue() && !skipStore,
- /*async*/true,
- missedForLoad,
- skipVals,
- needReadVer,
- new GridInClosure3<KeyCacheObject, Object, GridCacheVersion>() {
- @Override public void apply(KeyCacheObject key,
- @Nullable Object val,
- @Nullable GridCacheVersion loadVer) {
- if (log.isDebugEnabled())
- log.debug("Loaded value from remote node [key=" + key + ", val=" + val + ']');
+ else {
+ if (entryProcessor == null && txEntry.op() == TRANSFORM)
+ throw new IgniteCheckedException("Failed to enlist write value for key (cannot have update value in " +
+ "transaction after EntryProcessor is applied): " + CU.value(cacheKey, cacheCtx, false));
- IgniteTxEntry e = entry(new IgniteTxKey(key, cacheCtx.cacheId()));
+ GridCacheEntryEx entry = txEntry.cached();
- assert e != null;
+ CacheObject v = txEntry.value();
- if (needReadVer) {
- assert loadVer != null;
+ boolean del = txEntry.op() == DELETE && rmv;
- e.serializableReadVersion(singleRmv && val != null ? SER_READ_NOT_EMPTY_VER : loadVer);
- }
+ if (!del) {
+ if (hasFilters && !filter(entry.context(), cacheKey, v, filter)) {
+ ret.set(cacheCtx, v, false);
- if (singleRmv) {
- assert !hasFilters && !retval;
- assert val == null || Boolean.TRUE.equals(val) : val;
+ return loadMissed;
+ }
- ret.set(cacheCtx, null, val != null);
- }
- else {
- CacheObject cacheVal = cacheCtx.toCacheObject(val);
+ GridCacheOperation op = rmv ? DELETE : entryProcessor != null ? TRANSFORM :
+ v != null ? UPDATE : CREATE;
- if (e.op() == TRANSFORM) {
- GridCacheVersion ver;
+ txEntry = addEntry(op,
+ cacheCtx.toCacheObject(val),
+ entryProcessor,
+ invokeArgs,
+ entry,
+ expiryPlc,
+ filter,
+ true,
+ drTtl,
+ drExpireTime,
+ drVer,
+ skipStore);
- try {
- ver = e.cached().version();
- }
- catch (GridCacheEntryRemovedException ex) {
- assert optimistic() : e;
+ if (enlisted != null)
+ enlisted.add(cacheKey);
- if (log.isDebugEnabled())
- log.debug("Failed to get entry version: [msg=" + ex.getMessage() + ']');
+ if (txEntry.op() == TRANSFORM) {
+ GridCacheVersion ver;
- ver = null;
- }
+ try {
+ ver = entry.version();
+ }
+ catch (GridCacheEntryRemovedException e) {
+ assert optimistic() : txEntry;
- addInvokeResult(e, cacheVal, ret, ver);
- }
- else {
- boolean success = !hasFilters || isAll(e.context(), key, cacheVal, filter);
+ if (log.isDebugEnabled())
+ log.debug("Failed to get entry version: [msg=" + e.getMessage() + ']');
- ret.set(cacheCtx, cacheVal, success);
- }
- }
+ ver = null;
}
- });
- return new GridEmbeddedFuture<>(
- new C2<Void, Exception, Set<KeyCacheObject>>() {
- @Override public Set<KeyCacheObject> apply(Void b, Exception e) {
- if (e != null)
- throw new GridClosureException(e);
+ addInvokeResult(txEntry, txEntry.value(), ret, ver);
+ }
+ }
- return Collections.emptySet();
- }
- }, fut
- );
+ if (!pessimistic()) {
+ txEntry.markValid();
+
+ if (retval && !transform)
+ ret.set(cacheCtx, v, true);
+ else
+ ret.success(true);
+ }
}
- return new GridFinishedFuture<>(skipped);
+ return loadMissed;
}
/**
@@ -2486,22 +2634,19 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
*
* @param cacheCtx Context.
* @param keys Keys.
- * @param failed Collection of potentially failed keys (need to populate in this method).
* @param ret Return value.
* @param rmv {@code True} if remove.
* @param retval Flag to return value or not.
* @param read {@code True} if read.
* @param accessTtl TTL for read operation.
* @param filter Filter to check entries.
- * @return Failed keys.
* @throws IgniteCheckedException If error.
* @param computeInvoke If {@code true} computes return value for invoke operation.
*/
@SuppressWarnings("unchecked")
- protected Set<KeyCacheObject> postLockWrite(
+ protected final void postLockWrite(
GridCacheContext cacheCtx,
Iterable<KeyCacheObject> keys,
- Set<KeyCacheObject> failed,
GridCacheReturn ret,
boolean rmv,
boolean retval,
@@ -2606,8 +2751,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
log.debug("Filter passed in post lock for key: " + k);
}
else {
- failed = skip(failed, k);
-
// Revert operation to previous. (if no - NOOP, so entry will be unlocked).
txEntry.setAndMarkValid(txEntry.previousOperation(), cacheCtx.toCacheObject(ret.value()));
txEntry.filters(CU.empty0());
@@ -2638,11 +2781,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
}
}
-
- if (log.isDebugEnabled())
- log.debug("Entries that failed after lock filter check: " + failed);
-
- return failed;
}
/**
@@ -2696,6 +2834,144 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
/**
+ * @param cacheCtx Cache context.
+ * @param retval Return value flag.
+ * @throws IgniteCheckedException If failed.
+ */
+ private void beforePut(GridCacheContext cacheCtx, boolean retval) throws IgniteCheckedException {
+ checkUpdatesAllowed(cacheCtx);
+
+ cacheCtx.checkSecurity(SecurityPermission.CACHE_PUT);
+
+ if (retval)
+ needReturnValue(true);
+
+ checkValid();
+
+ init();
+ }
+
+ /**
+ * Internal method for single update operation.
+ *
+ * @param cacheCtx Cache context.
+ * @param key Key.
+ * @param val Value.
+ * @param entryProcessor Entry processor.
+ * @param invokeArgs Optional arguments for EntryProcessor.
+ * @param retval Return value flag.
+ * @param filter Filter.
+ * @return Operation future.
+ */
+ private <K, V> IgniteInternalFuture putAsync0(
+ final GridCacheContext cacheCtx,
+ K key,
+ @Nullable V val,
+ @Nullable EntryProcessor entryProcessor,
+ @Nullable final Object[] invokeArgs,
+ final boolean retval,
+ @Nullable final CacheEntryPredicate[] filter
+ ) {
+ assert key != null;
+
+ try {
+ beforePut(cacheCtx, retval);
+
+ final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
+
+ CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
+
+ KeyCacheObject cacheKey = cacheCtx.toCacheKeyObject(key);
+
+ final IgniteInternalFuture<Void> loadFut = enlistWrite(
+ cacheCtx,
+ cacheKey,
+ val,
+ opCtx != null ? opCtx.expiry() : null,
+ entryProcessor,
+ invokeArgs,
+ retval,
+ /*lockOnly*/false,
+ filter,
+ ret,
+ opCtx != null && opCtx.skipStore(),
+ /*singleRmv*/false);
+
+ if (pessimistic()) {
+ assert loadFut == null || loadFut.isDone() : loadFut;
+
+ final Collection<KeyCacheObject> enlisted = Collections.singleton(cacheKey);
+
+ if (log.isDebugEnabled())
+ log.debug("Before acquiring transaction lock for put on key: " + enlisted);
+
+ IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted,
+ lockTimeout(),
+ this,
+ false,
+ retval,
+ isolation,
+ isInvalidate(),
+ -1L);
+
+ PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
+ @Override public GridCacheReturn postLock(GridCacheReturn ret)
+ throws IgniteCheckedException
+ {
+ if (log.isDebugEnabled())
+ log.debug("Acquired transaction lock for put on keys: " + enlisted);
+
+ postLockWrite(cacheCtx,
+ enlisted,
+ ret,
+ /*remove*/false,
+ retval,
+ /*read*/false,
+ -1L,
+ filter,
+ /*computeInvoke*/true);
+
+ return ret;
+ }
+ };
+
+ if (fut.isDone()) {
+ try {
+ return nonInterruptable(plc1.apply(fut.get(), null));
+ }
+ catch (GridClosureException e) {
+ return new GridFinishedFuture<>(e.unwrap());
+ }
+ catch (IgniteCheckedException e) {
+ try {
+ return nonInterruptable(plc1.apply(false, e));
+ }
+ catch (Exception e1) {
+ return new GridFinishedFuture<>(e1);
+ }
+ }
+ }
+ else {
+ return nonInterruptable(new GridEmbeddedFuture<>(
+ fut,
+ plc1
+ ));
+ }
+ }
+ else
+ return optimisticPutFuture(loadFut, ret);
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture(e);
+ }
+ catch (RuntimeException e) {
+ onException();
+
+ throw e;
+ }
+ }
+
+ /**
* Internal method for all put and transform operations. Only one of {@code map}, {@code transformMap}
* maps must be non-null.
*
@@ -2721,17 +2997,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert filter == null || invokeMap == null;
try {
- checkUpdatesAllowed(cacheCtx);
+ beforePut(cacheCtx, retval);
}
catch (IgniteCheckedException e) {
return new GridFinishedFuture(e);
}
- cacheCtx.checkSecurity(SecurityPermission.CACHE_PUT);
-
- if (retval)
- needReturnValue(true);
-
// Cached entry may be passed only from entry wrapper.
final Map<?, ?> map0;
final Map<?, EntryProcessor<K, V, Object>> invokeMap0;
@@ -2757,15 +3028,6 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert map0 != null || invokeMap0 != null;
- try {
- checkValid();
- }
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
-
- init();
-
final GridCacheReturn ret = new GridCacheReturn(localResult(), false);
if (F.isEmpty(map0) && F.isEmpty(invokeMap0)) {
@@ -2783,15 +3045,14 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
try {
Set<?> keySet = map0 != null ? map0.keySet() : invokeMap0.keySet();
- Collection<KeyCacheObject> enlisted = new ArrayList<>();
+ final Collection<KeyCacheObject> enlisted = new ArrayList<>();
CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
- final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
+ final IgniteInternalFuture<Void> loadFut = enlistWrite(
cacheCtx,
keySet,
opCtx != null ? opCtx.expiry() : null,
- implicit,
map0,
invokeMap0,
invokeArgs,
@@ -2806,15 +3067,12 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
false);
if (pessimistic()) {
- // Loose all skipped.
- final Set<KeyCacheObject> loaded = loadFut.get();
-
- final Collection<KeyCacheObject> keys = F.view(enlisted, F0.notIn(loaded));
+ assert loadFut == null || loadFut.isDone() : loadFut;
if (log.isDebugEnabled())
- log.debug("Before acquiring transaction lock for put on keys: " + keys);
+ log.debug("Before acquiring transaction lock for put on keys: " + enlisted);
- IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(keys,
+ IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted,
lockTimeout(),
this,
false,
@@ -2828,11 +3086,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
throws IgniteCheckedException
{
if (log.isDebugEnabled())
- log.debug("Acquired transaction lock for put on keys: " + keys);
+ log.debug("Acquired transaction lock for put on keys: " + enlisted);
postLockWrite(cacheCtx,
- keys,
- loaded,
+ enlisted,
ret,
/*remove*/false,
retval,
@@ -2861,64 +3118,79 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
}
}
}
- else
+ else {
return nonInterruptable(new GridEmbeddedFuture<>(
fut,
plc1
));
+ }
}
- else {
- if (implicit()) {
- // Should never load missing values for implicit transaction as values will be returned
- // with prepare response, if required.
- assert loadFut.isDone();
+ else
+ return optimisticPutFuture(loadFut, ret);
+ }
+ catch (RuntimeException e) {
+ onException();
- try {
- loadFut.get();
- }
- catch (IgniteCheckedException e) {
- return new GridFinishedFuture<>(e);
- }
+ throw e;
+ }
+ }
- return nonInterruptable(commitAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut) throws IgniteCheckedException {
- try {
- txFut.get();
+ /**
+ * @param loadFut Missing keys load future.
+ * @param ret Future result.
+ * @return Future.
+ */
+ private IgniteInternalFuture optimisticPutFuture(IgniteInternalFuture<Void> loadFut, final GridCacheReturn ret) {
+ if (implicit()) {
+ // Should never load missing values for implicit transaction as values will be returned
+ // with prepare response, if required.
+ assert loadFut.isDone();
- return implicitRes;
- }
- catch (IgniteCheckedException | RuntimeException e) {
- rollbackAsync();
+ try {
+ loadFut.get();
+ }
+ catch (IgniteCheckedException e) {
+ return new GridFinishedFuture<>(e);
+ }
- throw e;
- }
+ return nonInterruptable(commitAsync().chain(
+ new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut)
+ throws IgniteCheckedException {
+ try {
+ txFut.get();
+
+ return implicitRes;
}
- }));
- }
- else
- return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Set<KeyCacheObject>>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f) throws IgniteCheckedException {
- f.get();
+ catch (IgniteCheckedException | RuntimeException e) {
+ rollbackAsync();
- return ret;
+ throw e;
}
- }));
- }
+ }
+ }
+ ));
}
- catch (RuntimeException e) {
- for (IgniteTxEntry txEntry : txMap.values()) {
- GridCacheEntryEx cached0 = txEntry.cached();
-
- if (cached0 != null)
- txEntry.context().evicts().touch(cached0, topologyVersion());
- }
+ else {
+ return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Void>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<Void> f) throws IgniteCheckedException {
+ f.get();
- throw e;
+ return ret;
+ }
+ }));
}
- catch (IgniteCheckedException e) {
- setRollbackOnly();
+ }
- return new GridFinishedFuture<>(e);
+ /**
+ *
+ */
+ private void onException() {
+ for (IgniteTxEntry txEntry : allEntries()) {
+ GridCacheEntryEx cached0 = txEntry.cached();
+
+ if (cached0 != null)
+ txEntry.context().evicts().touch(cached0, topologyVersion());
}
}
@@ -2974,9 +3246,10 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
assert keys0 != null;
- if (log.isDebugEnabled())
+ if (log.isDebugEnabled()) {
log.debug("Called removeAllAsync(...) [tx=" + this + ", keys=" + keys0 + ", implicit=" + implicit +
", retval=" + retval + "]");
+ }
try {
checkValid();
@@ -3002,140 +3275,131 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
init();
- try {
- Collection<KeyCacheObject> enlisted = new ArrayList<>();
-
- CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
+ final Collection<KeyCacheObject> enlisted = new ArrayList<>();
- ExpiryPolicy plc;
+ CacheOperationContext opCtx = cacheCtx.operationContextPerCall();
- if (!F.isEmpty(filter))
- plc = opCtx != null ? opCtx.expiry() : null;
- else
- plc = null;
+ ExpiryPolicy plc;
- final IgniteInternalFuture<Set<KeyCacheObject>> loadFut = enlistWrite(
- cacheCtx,
- keys0,
- plc,
- implicit,
- /** lookup map */null,
- /** invoke map */null,
- /** invoke arguments */null,
- retval,
- /** lock only */false,
- filter,
- ret,
- enlisted,
- null,
- drMap,
- opCtx != null && opCtx.skipStore(),
- singleRmv
- );
+ if (!F.isEmpty(filter))
+ plc = opCtx != null ? opCtx.expiry() : null;
+ else
+ plc = null;
- if (log.isDebugEnabled())
- log.debug("Remove keys: " + enlisted);
+ final IgniteInternalFuture<Void> loadFut = enlistWrite(
+ cacheCtx,
+ keys0,
+ plc,
+ /** lookup map */null,
+ /** invoke map */null,
+ /** invoke arguments */null,
+ retval,
+ /** lock only */false,
+ filter,
+ ret,
+ enlisted,
+ null,
+ drMap,
+ opCtx != null && opCtx.skipStore(),
+ singleRmv
+ );
- // Acquire locks only after having added operation to the write set.
- // Otherwise, during rollback we will not know whether locks need
- // to be rolled back.
- if (pessimistic()) {
- // Loose all skipped.
- final Collection<KeyCacheObject> passedKeys = F.view(enlisted, F0.notIn(loadFut.get()));
+ if (log.isDebugEnabled())
+ log.debug("Remove keys: " + enlisted);
- if (log.isDebugEnabled())
- log.debug("Before acquiring transaction lock for remove on keys: " + passedKeys);
+ // Acquire locks only after having added operation to the write set.
+ // Otherwise, during rollback we will not know whether locks need
+ // to be rolled back.
+ if (pessimistic()) {
+ assert loadFut.isDone() : loadFut;
- IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(passedKeys,
- lockTimeout(),
- this,
- false,
- retval,
- isolation,
- isInvalidate(),
- -1L);
+ if (log.isDebugEnabled())
+ log.debug("Before acquiring transaction lock for remove on keys: " + enlisted);
- PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
- @Override protected GridCacheReturn postLock(GridCacheReturn ret)
- throws IgniteCheckedException
- {
- if (log.isDebugEnabled())
- log.debug("Acquired transaction lock for remove on keys: " + passedKeys);
+ IgniteInternalFuture<Boolean> fut = cacheCtx.cache().txLockAsync(enlisted,
+ lockTimeout(),
+ this,
+ false,
+ retval,
+ isolation,
+ isInvalidate(),
+ -1L);
+
+ PLC1<GridCacheReturn> plc1 = new PLC1<GridCacheReturn>(ret) {
+ @Override protected GridCacheReturn postLock(GridCacheReturn ret)
+ throws IgniteCheckedException
+ {
+ if (log.isDebugEnabled())
+ log.debug("Acquired transaction lock for remove on keys: " + enlisted);
- postLockWrite(cacheCtx,
- passedKeys,
- loadFut.get(),
- ret,
+ postLockWrite(cacheCtx,
+ enlisted,
+ ret,
/*remove*/true,
- retval,
+ retval,
/*read*/false,
- -1L,
- filter,
+ -1L,
+ filter,
/*computeInvoke*/false);
- return ret;
- }
- };
+ return ret;
+ }
+ };
- if (fut.isDone()) {
+ if (fut.isDone()) {
+ try {
+ return nonInterruptable(plc1.apply(fut.get(), null));
+ }
+ catch (GridClosureException e) {
+ return new GridFinishedFuture<>(e.unwrap());
+ }
+ catch (IgniteCheckedException e) {
try {
- return nonInterruptable(plc1.apply(fut.get(), null));
+ return nonInterruptable(plc1.apply(false, e));
}
- catch (GridClosureException e) {
- return new GridFinishedFuture<>(e.unwrap());
- }
- catch (IgniteCheckedException e) {
- try {
- return nonInterruptable(plc1.apply(false, e));
- }
- catch (Exception e1) {
- return new GridFinishedFuture<>(e1);
- }
+ catch (Exception e1) {
+ return new GridFinishedFuture<>(e1);
}
}
- else
- return nonInterruptable(new GridEmbeddedFuture<>(
- fut,
- plc1
- ));
}
- else {
- if (implicit()) {
- // Should never load missing values for implicit transaction as values will be returned
- // with prepare response, if required.
- assert loadFut.isDone();
-
- return nonInterruptable(commitAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut)
- throws IgniteCheckedException {
- try {
- txFut.get();
+ else
+ return nonInterruptable(new GridEmbeddedFuture<>(
+ fut,
+ plc1
+ ));
+ }
+ else {
+ if (implicit()) {
+ // Should never load missing values for implicit transaction as values will be returned
+ // with prepare response, if required.
+ assert loadFut.isDone();
- return implicitRes;
- }
- catch (IgniteCheckedException | RuntimeException e) {
- rollbackAsync();
+ return nonInterruptable(commitAsync().chain(new CX1<IgniteInternalFuture<IgniteInternalTx>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<IgniteInternalTx> txFut)
+ throws IgniteCheckedException {
+ try {
+ txFut.get();
- throw e;
- }
+ return implicitRes;
}
- }));
- }
- else
- return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Set<KeyCacheObject>>, GridCacheReturn>() {
- @Override public GridCacheReturn applyx(IgniteInternalFuture<Set<KeyCacheObject>> f)
- throws IgniteCheckedException {
- f.get();
+ catch (IgniteCheckedException | RuntimeException e) {
+ rollbackAsync();
- return ret;
+ throw e;
}
- }));
+ }
+ }));
}
- }
- catch (IgniteCheckedException e) {
- setRollbackOnly();
+ else {
+ return nonInterruptable(loadFut.chain(new CX1<IgniteInternalFuture<Void>, GridCacheReturn>() {
+ @Override public GridCacheReturn applyx(IgniteInternalFuture<Void> f)
+ throws IgniteCheckedException {
+ f.get();
- return new GridFinishedFuture<>(e);
+ return ret;
+ }
+ }));
+ }
}
}
@@ -3169,16 +3433,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @return {@code True} if transaction was successfully started.
*/
public boolean init() {
- if (txMap == null) {
- txMap = new LinkedHashMap<>(txSize > 0 ? txSize : 16, 1.0f);
+ return !txState.init(txSize) || cctx.tm().onStarted(this);
- readView = new IgniteTxMap(txMap, CU.reads());
- writeView = new IgniteTxMap(txMap, CU.writes());
-
- return cctx.tm().onStarted(this);
- }
-
- return true;
}
/**
@@ -3188,38 +3444,8 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
* @throws IgniteCheckedException If caches already enlisted in this transaction are not compatible with given
* cache (e.g. they have different stores).
*/
- protected void addActiveCache(GridCacheContext cacheCtx) throws IgniteCheckedException {
- int cacheId = cacheCtx.cacheId();
-
- // Check if we can enlist new cache to transaction.
- if (!activeCacheIds.contains(cacheId)) {
- String err = cctx.verifyTxCompatibility(this, activeCacheIds, cacheCtx);
-
- if (err != null) {
- StringBuilder cacheNames = new StringBuilder();
-
- int idx = 0;
-
- for (Integer activeCacheId : activeCacheIds) {
- cacheNames.append(cctx.cacheContext(activeCacheId).name());
-
- if (idx++ < activeCacheIds.size() - 1)
- cacheNames.append(", ");
- }
-
- throw new IgniteCheckedException("Failed to enlist new cache to existing transaction (" +
- err +
- ") [activeCaches=[" + cacheNames + "]" +
- ", cacheName=" + cacheCtx.name() +
- ", cacheSystem=" + cacheCtx.systemTx() +
- ", txSystem=" + system() + ']');
- }
- else
- activeCacheIds.add(cacheId);
-
- if (activeCacheIds.size() == 1)
- depEnabled = cacheCtx.deploymentEnabled();
- }
+ protected final void addActiveCache(GridCacheContext cacheCtx) throws IgniteCheckedException {
+ txState.addActiveCache(cacheCtx, this);
}
/**
@@ -3294,7 +3520,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
"Invalid tx state for adding entry [op=" + op + ", val=" + val + ", entry=" + entry + ", filter=" +
Arrays.toString(filter) + ", txCtx=" + cctx.tm().txContextVersion() + ", tx=" + this + ']';
- IgniteTxEntry old = txMap.get(key);
+ IgniteTxEntry old = entry(key);
// Keep old filter if already have one (empty filter is always overridden).
if (!filtersSet || !F.isEmptyOrNulls(filter)) {
@@ -3358,7 +3584,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
if (!hasDrTtl)
txEntry.expiry(expiryPlc);
- txMap.put(key, txEntry);
+ txState.addEntry(txEntry);
if (log.isDebugEnabled())
log.debug("Created transaction entry: " + txEntry);
@@ -3420,7 +3646,7 @@ public abstract class IgniteTxLocalAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public String toString() {
return GridToStringBuilder.toString(IgniteTxLocalAdapter.class, this, "super", super.toString(),
- "size", (txMap == null ? 0 : txMap.size()));
+ "size", allEntries().size());
}
/**
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
index 0d83338..5dc3338 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalEx.java
@@ -93,9 +93,37 @@ public interface IgniteTxLocalEx extends IgniteInternalTx {
/**
* @param cacheCtx Cache context.
+ * @param key Key.
+ * @param val Value.
+ * @param retval Return value flag.
+ * @param filter Filter.
+ * @return Future for put operation.
+ */
+ public <K, V> IgniteInternalFuture<GridCacheReturn> putAsync(
+ GridCacheContext cacheCtx,
+ K key,
+ V val,
+ boolean retval,
+ CacheEntryPredicate[] filter);
+
+ /**
+ * @param cacheCtx Cache context.
+ * @param key Key.
+ * @param entryProcessor Entry processor.
+ * @param invokeArgs Optional arguments for entry processor.
+ * @return Operation future.
+ */
+ public <K, V> IgniteInternalFuture<GridCacheReturn> invokeAsync(
+ GridCacheContext cacheCtx,
+ K key,
+ EntryProcessor<K, V, Object> entryProcessor,
+ Object... invokeArgs);
+
+ /**
+ * @param cacheCtx Cache context.
* @param map Entry processors map.
* @param invokeArgs Optional arguments for entry processor.
- * @return Transform operation future.
+ * @return Operation future.
*/
public <K, V, T> IgniteInternalFuture<GridCacheReturn> invokeAsync(
GridCacheContext cacheCtx,
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
new file mode 100644
index 0000000..123d396
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalState.java
@@ -0,0 +1,44 @@
+/*
+ * 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.cache.transactions;
+
+/**
+ *
+ */
+public interface IgniteTxLocalState extends IgniteTxState {
+ /**
+ * @param entry Entry.
+ */
+ public void addEntry(IgniteTxEntry entry);
+
+ /**
+ * @param txSize Transaction size.
+ * @return {@code True} if transaction was successfully started.
+ */
+ public boolean init(int txSize);
+
+ /**
+ * @return {@code True} if init method was called.
+ */
+ public boolean initialized();
+
+ /**
+ *
+ */
+ public void seal();
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java
new file mode 100644
index 0000000..cde5203
--- /dev/null
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxLocalStateAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * 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.cache.transactions;
+
+import org.apache.ignite.internal.processors.cache.GridCacheContext;
+import org.apache.ignite.internal.util.typedef.internal.U;
+
+/**
+ *
+ */
+public abstract class IgniteTxLocalStateAdapter implements IgniteTxLocalState {
+ /**
+ * @param cacheCtx Cache context.
+ * @param tx Transaction.
+ * @param commit {@code False} if transaction rolled back.
+ */
+ protected final void onTxEnd(GridCacheContext cacheCtx, IgniteInternalTx tx, boolean commit) {
+ if (cacheCtx.cache().configuration().isStatisticsEnabled()) {
+ // Convert start time from ms to ns.
+ if (commit)
+ cacheCtx.cache().metrics0().onTxCommit((U.currentTimeMillis() - tx.startTime()) * 1000);
+ else
+ cacheCtx.cache().metrics0().onTxRollback((U.currentTimeMillis() - tx.startTime()) * 1000);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
index c2e7dea..ccccca0 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxManager.java
@@ -1092,13 +1092,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (!tx.system())
cctx.txMetrics().onTxCommit();
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
-
- if (cacheCtx.cache().configuration().isStatisticsEnabled())
- // Convert start time from ms to ns.
- cacheCtx.cache().metrics0().onTxCommit((U.currentTimeMillis() - tx.startTime()) * 1000);
- }
+ tx.txState().onTxEnd(cctx, tx, true);
}
if (slowTxWarnTimeout > 0 && tx.local() &&
@@ -1163,13 +1157,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (!tx.system())
cctx.txMetrics().onTxRollback();
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext cacheCtx = cctx.cacheContext(cacheId);
-
- if (cacheCtx.cache().configuration().isStatisticsEnabled())
- // Convert start time from ms to ns.
- cacheCtx.cache().metrics0().onTxRollback((U.currentTimeMillis() - tx.startTime()) * 1000);
- }
+ tx.txState().onTxEnd(cctx, tx, false);
}
if (log.isDebugEnabled())
@@ -1233,7 +1221,7 @@ public class IgniteTxManager extends GridCacheSharedManagerAdapter {
if (!tx.system())
threadMap.remove(tx.threadId(), tx);
else {
- Integer cacheId = F.first(tx.activeCacheIds());
+ Integer cacheId = tx.txState().firstCacheId();
if (cacheId != null)
sysThreadMap.remove(new TxThreadKey(tx.threadId(), cacheId), tx);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
index 6408573..429c995 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxMap.java
@@ -170,8 +170,7 @@ public class IgniteTxMap extends AbstractMap<IgniteTxKey, IgniteTxEntry> impleme
}
/** {@inheritDoc} */
- @Nullable
- @Override public IgniteTxEntry get(Object key) {
+ @Nullable @Override public IgniteTxEntry get(Object key) {
IgniteTxEntry e = txMap.get(key);
return e == null ? null : filter.apply(e) ? e : null;
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
index 9660e4e..b80909f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/transactions/IgniteTxRemoteEx.java
@@ -25,22 +25,13 @@ import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
*/
public interface IgniteTxRemoteEx extends IgniteInternalTx {
/**
- * @return Remote thread ID.
- */
- public long remoteThreadId();
-
- /**
* @param baseVer Base version.
* @param committedVers Committed version.
* @param rolledbackVers Rolled back version.
* @param pendingVers Pending versions.
*/
- public void doneRemote(GridCacheVersion baseVer, Collection<GridCacheVersion> committedVers,
- Collection<GridCacheVersion> rolledbackVers, Collection<GridCacheVersion> pendingVers);
-
- /**
- * @param e Sets write value for pessimistic transactions.
- * @return {@code True} if entry was found.
- */
- public boolean setWriteValue(IgniteTxEntry e);
+ public void doneRemote(GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
+ Collection<GridCacheVersion> pendingVers);
}
\ No newline at end of file
[4/4] ignite git commit: 'Single' operations optimizations for tx
cache.
Posted by sb...@apache.org.
'Single' operations optimizations for tx cache.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3ff71fd7
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3ff71fd7
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3ff71fd7
Branch: refs/heads/ignite-1.5
Commit: 3ff71fd742efda91fef6ed6d92dac11cc6d00976
Parents: 38e66d9
Author: sboikov <sb...@gridgain.com>
Authored: Tue Nov 17 19:38:05 2015 +0300
Committer: sboikov <sb...@gridgain.com>
Committed: Tue Nov 17 19:38:05 2015 +0300
----------------------------------------------------------------------
.../processors/cache/GridCacheAdapter.java | 48 +-
.../processors/cache/GridCacheMapEntry.java | 11 +-
.../cache/GridCacheSharedContext.java | 31 +-
.../distributed/GridDistributedTxMapping.java | 78 -
.../GridDistributedTxRemoteAdapter.java | 136 +-
.../dht/GridDhtTransactionalCacheAdapter.java | 1 -
.../cache/distributed/dht/GridDhtTxLocal.java | 24 +-
.../distributed/dht/GridDhtTxLocalAdapter.java | 80 +-
.../cache/distributed/dht/GridDhtTxMapping.java | 134 +-
.../distributed/dht/GridDhtTxPrepareFuture.java | 59 +-
.../cache/distributed/dht/GridDhtTxRemote.java | 29 +-
...arOptimisticSerializableTxPrepareFuture.java | 16 -
.../near/GridNearOptimisticTxPrepareFuture.java | 103 +-
...ridNearOptimisticTxPrepareFutureAdapter.java | 72 +-
.../GridNearPessimisticTxPrepareFuture.java | 1 -
.../near/GridNearTransactionalCache.java | 1 -
.../near/GridNearTxFinishFuture.java | 61 +-
.../cache/distributed/near/GridNearTxLocal.java | 109 +-
.../near/GridNearTxPrepareRequest.java | 9 -
.../distributed/near/GridNearTxRemote.java | 26 +-
.../distributed/near/IgniteTxMappings.java | 75 +
.../distributed/near/IgniteTxMappingsImpl.java | 92 ++
.../near/IgniteTxMappingsSingleImpl.java | 101 ++
.../cache/transactions/IgniteInternalTx.java | 12 +-
.../cache/transactions/IgniteTxAdapter.java | 67 +-
.../cache/transactions/IgniteTxHandler.java | 16 +-
.../IgniteTxImplicitSingleStateImpl.java | 259 ++++
.../transactions/IgniteTxLocalAdapter.java | 1388 ++++++++++--------
.../cache/transactions/IgniteTxLocalEx.java | 30 +-
.../cache/transactions/IgniteTxLocalState.java | 44 +
.../transactions/IgniteTxLocalStateAdapter.java | 41 +
.../cache/transactions/IgniteTxManager.java | 18 +-
.../cache/transactions/IgniteTxMap.java | 3 +-
.../cache/transactions/IgniteTxRemoteEx.java | 17 +-
.../IgniteTxRemoteSingleStateImpl.java | 108 ++
.../cache/transactions/IgniteTxRemoteState.java | 34 +
.../IgniteTxRemoteStateAdapter.java | 110 ++
.../transactions/IgniteTxRemoteStateImpl.java | 124 ++
.../cache/transactions/IgniteTxState.java | 171 +++
.../cache/transactions/IgniteTxStateImpl.java | 375 +++++
40 files changed, 2709 insertions(+), 1405 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
index 419ccec..cbb7486 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheAdapter.java
@@ -1854,7 +1854,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
V prevVal = syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, filter).get().value();
+ return (V)tx.putAsync(ctx, key, val, true, filter).get().value();
}
@Override public String toString() {
@@ -1909,7 +1909,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, filter)
+ return tx.putAsync(ctx, key, val, true, filter)
.chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@@ -1948,7 +1948,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Boolean stored = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, filter).get().success();
+ return tx.putAsync(ctx, key, val, false, filter).get().success();
}
@Override public String toString() {
@@ -2013,10 +2013,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<EntryProcessorResult<T>>(true) {
@Nullable @Override public EntryProcessorResult<T> op(IgniteTxLocalAdapter tx)
throws IgniteCheckedException {
- Map<? extends K, EntryProcessor<K, V, Object>> invokeMap =
- Collections.singletonMap(key, (EntryProcessor<K, V, Object>) entryProcessor);
-
- IgniteInternalFuture<GridCacheReturn> fut = tx.invokeAsync(ctx, invokeMap, args);
+ IgniteInternalFuture<GridCacheReturn> fut =
+ tx.invokeAsync(ctx, key, (EntryProcessor<K, V, Object>)entryProcessor, args);
Map<K, EntryProcessorResult<T>> resMap = fut.get().value();
@@ -2240,8 +2238,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, filter).chain(
- (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
+ return tx.putAsync(ctx, key, val, false, filter).chain(
+ (IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@Override public String toString() {
@@ -2275,7 +2273,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray()).get().value();
+ return (V)tx.putAsync(ctx, key, val, true, ctx.noValArray()).get().value();
}
@Override public String toString() {
@@ -2299,8 +2297,8 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, ctx.noValArray())
- .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>) RET2VAL);
+ return tx.putAsync(ctx, key, val, true, ctx.noValArray())
+ .chain((IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@Override public String toString() {
@@ -2329,7 +2327,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
Boolean stored = syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).get().success();
+ return tx.putAsync(ctx, key, val, false, ctx.noValArray()).get().success();
}
@Override public String toString() {
@@ -2358,7 +2356,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<Boolean> fut = asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.noValArray()).chain(
+ return tx.putAsync(ctx, key, val, false, ctx.noValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2384,7 +2382,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<V>(true) {
@Override public V op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return (V)tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).get().value();
+ return (V)tx.putAsync(ctx, key, val, true, ctx.hasValArray()).get().value();
}
@Override public String toString() {
@@ -2408,7 +2406,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
IgniteInternalFuture<V> fut = asyncOp(new AsyncOp<V>() {
@Override public IgniteInternalFuture<V> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), true, ctx.hasValArray()).chain(
+ return tx.putAsync(ctx, key, val, true, ctx.hasValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, V>)RET2VAL);
}
@@ -2434,7 +2432,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return syncOp(new SyncOp<Boolean>(true) {
@Override public Boolean op(IgniteTxLocalAdapter tx) throws IgniteCheckedException {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).get().success();
+ return tx.putAsync(ctx, key, val, false, ctx.hasValArray()).get().success();
}
@Override public String toString() {
@@ -2454,7 +2452,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return asyncOp(new AsyncOp<Boolean>() {
@Override public IgniteInternalFuture<Boolean> op(IgniteTxLocalAdapter tx) {
- return tx.putAllAsync(ctx, F.t(key, val), false, ctx.hasValArray()).chain(
+ return tx.putAsync(ctx, key, val, false, ctx.hasValArray()).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>) RET2FLAG);
}
@@ -2481,7 +2479,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (ctx.deploymentEnabled())
ctx.deploy().registerClass(oldVal);
- return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).get()
+ return tx.putAsync(ctx, key, newVal, false, ctx.equalsValArray(oldVal)).get()
.success();
}
@@ -2518,7 +2516,7 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
}
}
- return tx.putAllAsync(ctx, F.t(key, newVal), false, ctx.equalsValArray(oldVal)).chain(
+ return tx.putAsync(ctx, key, newVal, false, ctx.equalsValArray(oldVal)).chain(
(IgniteClosure<IgniteInternalFuture<GridCacheReturn>, Boolean>)RET2FLAG);
}
@@ -2883,8 +2881,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
if (ctx.deploymentEnabled())
ctx.deploy().registerClass(oldVal);
- return tx.putAllAsync(ctx,
- F.t(key, newVal),
+ return tx.putAsync(ctx,
+ key,
+ newVal,
true,
ctx.equalsValArray(oldVal)).get();
}
@@ -2945,8 +2944,9 @@ public abstract class GridCacheAdapter<K, V> implements IgniteInternalCache<K, V
return new GridFinishedFuture<>(e);
}
- return (IgniteInternalFuture)tx.putAllAsync(ctx,
- F.t(key, newVal),
+ return (IgniteInternalFuture)tx.putAsync(ctx,
+ key,
+ newVal,
true,
ctx.equalsValArray(oldVal));
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
index df9f5c4..0786a50 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMapEntry.java
@@ -74,6 +74,7 @@ import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_EXPIRED;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_PUT;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;
import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_REMOVED;
+import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE;
import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE;
/**
@@ -4014,7 +4015,15 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme
IgniteInternalTx tx = cctx.tm().localTxx();
- return tx == null || !tx.removed(txKey());
+ if (tx != null) {
+ IgniteTxEntry e = tx.entry(txKey());
+
+ boolean rmvd = e != null && e.op() == DELETE;
+
+ return !rmvd;
+ }
+
+ return true;
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
index b37742c..4293b90 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheSharedContext.java
@@ -582,12 +582,7 @@ public class GridCacheSharedContext<K, V> {
* @throws IgniteCheckedException If failed.
*/
public void endTx(IgniteInternalTx tx) throws IgniteCheckedException {
- Collection<Integer> cacheIds = tx.activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- for (Integer cacheId : cacheIds)
- cacheContext(cacheId).cache().awaitLastFut();
- }
+ tx.txState().awaitLastFut(this);
tx.close();
}
@@ -596,22 +591,17 @@ public class GridCacheSharedContext<K, V> {
* @param tx Transaction to commit.
* @return Commit future.
*/
+ @SuppressWarnings("unchecked")
public IgniteInternalFuture<IgniteInternalTx> commitTxAsync(IgniteInternalTx tx) {
- Collection<Integer> cacheIds = tx.activeCacheIds();
-
- if (cacheIds.isEmpty())
- return tx.commitAsync();
- else if (cacheIds.size() == 1) {
- int cacheId = F.first(cacheIds);
+ GridCacheContext ctx = tx.txState().singleCacheContext(this);
- return cacheContext(cacheId).cache().commitTxAsync(tx);
- }
- else {
- for (Integer cacheId : cacheIds)
- cacheContext(cacheId).cache().awaitLastFut();
+ if (ctx == null) {
+ tx.txState().awaitLastFut(this);
return tx.commitAsync();
}
+ else
+ return ctx.cache().commitTxAsync(tx);
}
/**
@@ -620,12 +610,7 @@ public class GridCacheSharedContext<K, V> {
* @return Rollback future.
*/
public IgniteInternalFuture rollbackTxAsync(IgniteInternalTx tx) throws IgniteCheckedException {
- Collection<Integer> cacheIds = tx.activeCacheIds();
-
- if (!cacheIds.isEmpty()) {
- for (Integer cacheId : cacheIds)
- cacheContext(cacheId).cache().awaitLastFut();
- }
+ tx.txState().awaitLastFut(this);
return tx.rollbackAsync();
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
index 2d2d935..8c9f181 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxMapping.java
@@ -24,9 +24,7 @@ import java.io.ObjectOutput;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.UUID;
import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
@@ -59,15 +57,9 @@ public class GridDistributedTxMapping implements Externalizable {
/** DHT version. */
private GridCacheVersion dhtVer;
- /** Copy on remove flag. */
- private boolean readOnly;
-
/** {@code True} if this is last mapping for node. */
private boolean last;
- /** IDs of backup nodes receiving last prepare request during this mapping. */
- private Collection<UUID> lastBackups;
-
/** {@code True} if mapping is for near caches, {@code false} otherwise. */
private boolean near;
@@ -91,20 +83,6 @@ public class GridDistributedTxMapping implements Externalizable {
}
/**
- * @return IDs of backup nodes receiving last prepare request during this mapping.
- */
- @Nullable public Collection<UUID> lastBackups() {
- return lastBackups;
- }
-
- /**
- * @param lastBackups IDs of backup nodes receiving last prepare request during this mapping.
- */
- public void lastBackups(@Nullable Collection<UUID> lastBackups) {
- this.lastBackups = lastBackups;
- }
-
- /**
* @return {@code True} if this is last mapping for node.
*/
public boolean last() {
@@ -161,17 +139,6 @@ public class GridDistributedTxMapping implements Externalizable {
}
/**
- * @param entries Mapped entries.
- * @param readOnly Flag indicating that passed in collection is read-only.
- */
- public void entries(Collection<IgniteTxEntry> entries, boolean readOnly) {
- this.entries = entries;
-
- // Set copy on remove flag as passed in collection is unmodifiable.
- this.readOnly = true;
- }
-
- /**
* @return {@code True} if lock is explicit.
*/
public boolean explicitLock() {
@@ -221,8 +188,6 @@ public class GridDistributedTxMapping implements Externalizable {
* @param entry Adds entry.
*/
public void add(IgniteTxEntry entry) {
- ensureModifiable();
-
entries.add(entry);
}
@@ -231,48 +196,16 @@ public class GridDistributedTxMapping implements Externalizable {
* @return {@code True} if entry was removed.
*/
public boolean removeEntry(IgniteTxEntry entry) {
- ensureModifiable();
-
return entries.remove(entry);
}
/**
- * @param parts Evicts partitions from mapping.
- */
- public void evictPartitions(@Nullable int[] parts) {
- if (!F.isEmpty(parts)) {
- ensureModifiable();
-
- evictPartitions(parts, entries);
- }
- }
-
- /**
- * @param parts Partitions.
- * @param c Collection.
- */
- private void evictPartitions(int[] parts, Collection<IgniteTxEntry> c) {
- assert parts != null;
-
- for (Iterator<IgniteTxEntry> it = c.iterator(); it.hasNext();) {
- IgniteTxEntry e = it.next();
-
- GridCacheEntryEx cached = e.cached();
-
- if (U.containsIntArray(parts, cached.partition()))
- it.remove();
- }
- }
-
- /**
* @param keys Keys to evict readers for.
*/
public void evictReaders(@Nullable Collection<IgniteTxKey> keys) {
if (keys == null || keys.isEmpty())
return;
- ensureModifiable();
-
evictReaders(keys, entries);
}
@@ -293,17 +226,6 @@ public class GridDistributedTxMapping implements Externalizable {
}
/**
- * Copies collection of entries if it is read-only.
- */
- private void ensureModifiable() {
- if (readOnly) {
- entries = new LinkedHashSet<>(entries);
-
- readOnly = false;
- }
- }
-
- /**
* Whether empty or not.
*
* @return Empty or not.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
index 93303c8..0d49584 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedTxRemoteAdapter.java
@@ -45,6 +45,8 @@ import org.apache.ignite.internal.processors.cache.transactions.IgniteTxAdapter;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteEx;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteState;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxState;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersionConflictContext;
import org.apache.ignite.internal.transactions.IgniteTxHeuristicCheckedException;
@@ -85,18 +87,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** */
private static final long serialVersionUID = 0L;
- /** Read set. */
- @GridToStringInclude
- protected Map<IgniteTxKey, IgniteTxEntry> readMap;
-
- /** Write map. */
- @GridToStringInclude
- protected Map<IgniteTxKey, IgniteTxEntry> writeMap;
-
- /** Remote thread ID. */
- @GridToStringInclude
- private long rmtThreadId;
-
/** Explicit versions. */
@GridToStringInclude
private List<GridCacheVersion> explicitVers;
@@ -109,6 +99,10 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
@GridToStringInclude
private AtomicBoolean commitAllowed = new AtomicBoolean(false);
+ /** */
+ @GridToStringInclude
+ protected IgniteTxRemoteState txState;
+
/**
* Empty constructor required for {@link Externalizable}.
*/
@@ -119,7 +113,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/**
* @param ctx Cache registry.
* @param nodeId Node ID.
- * @param rmtThreadId Remote thread ID.
* @param xidVer XID version.
* @param commitVer Commit version.
* @param sys System flag.
@@ -135,7 +128,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
public GridDistributedTxRemoteAdapter(
GridCacheSharedContext<?, ?> ctx,
UUID nodeId,
- long rmtThreadId,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
boolean sys,
@@ -163,7 +155,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
subjId,
taskNameHash);
- this.rmtThreadId = rmtThreadId;
this.invalidate = invalidate;
commitVersion(commitVer);
@@ -173,6 +164,11 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
+ @Override public IgniteTxState txState() {
+ return txState;
+ }
+
+ /** {@inheritDoc} */
@Override public UUID eventNodeId() {
return nodeId;
}
@@ -188,11 +184,6 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
}
/** {@inheritDoc} */
- @Override public Collection<Integer> activeCacheIds() {
- return Collections.emptyList();
- }
-
- /** {@inheritDoc} */
@Override public boolean activeCachesDeploymentEnabled() {
return false;
}
@@ -201,14 +192,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @return Checks if transaction has no entries.
*/
@Override public boolean empty() {
- return readMap.isEmpty() && writeMap.isEmpty();
- }
-
- /** {@inheritDoc} */
- @Override public boolean removed(IgniteTxKey key) {
- IgniteTxEntry e = writeMap.get(key);
-
- return e != null && e.op() == DELETE;
+ return txState.empty();
}
/** {@inheritDoc} */
@@ -218,12 +202,12 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> writeMap() {
- return writeMap;
+ return txState.writeMap();
}
/** {@inheritDoc} */
@Override public Map<IgniteTxKey, IgniteTxEntry> readMap() {
- return readMap;
+ return txState.readMap();
}
/** {@inheritDoc} */
@@ -245,12 +229,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public IgniteTxEntry entry(IgniteTxKey key) {
- IgniteTxEntry e = writeMap == null ? null : writeMap.get(key);
-
- if (e == null)
- e = readMap == null ? null : readMap.get(key);
-
- return e;
+ return txState.entry(key);
}
/**
@@ -259,8 +238,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @param key key to be removed.
*/
public void clearEntry(IgniteTxKey key) {
- readMap.remove(key);
- writeMap.remove(key);
+ txState.clearEntry(key);
}
/**
@@ -268,13 +246,19 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @param committedVers Committed versions.
* @param rolledbackVers Rolled back versions.
*/
- @Override public void doneRemote(GridCacheVersion baseVer, Collection<GridCacheVersion> committedVers,
- Collection<GridCacheVersion> rolledbackVers, Collection<GridCacheVersion> pendingVers) {
+ @Override public void doneRemote(GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
+ Collection<GridCacheVersion> pendingVers) {
+ Map<IgniteTxKey, IgniteTxEntry> readMap = txState.readMap();
+
if (readMap != null && !readMap.isEmpty()) {
for (IgniteTxEntry txEntry : readMap.values())
doneRemote(txEntry, baseVer, committedVers, rolledbackVers, pendingVers);
}
+ Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
+
if (writeMap != null && !writeMap.isEmpty()) {
for (IgniteTxEntry txEntry : writeMap.values())
doneRemote(txEntry, baseVer, committedVers, rolledbackVers, pendingVers);
@@ -290,8 +274,10 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
* @param rolledbackVers Rolled back versions relative to base version.
* @param pendingVers Pending versions.
*/
- private void doneRemote(IgniteTxEntry txEntry, GridCacheVersion baseVer,
- Collection<GridCacheVersion> committedVers, Collection<GridCacheVersion> rolledbackVers,
+ private void doneRemote(IgniteTxEntry txEntry,
+ GridCacheVersion baseVer,
+ Collection<GridCacheVersion> committedVers,
+ Collection<GridCacheVersion> rolledbackVers,
Collection<GridCacheVersion> pendingVers) {
while (true) {
GridDistributedCacheEntry entry = (GridDistributedCacheEntry)txEntry.cached();
@@ -337,59 +323,9 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
return started;
}
- /**
- * @return Remote node thread ID.
- */
- @Override public long remoteThreadId() {
- return rmtThreadId;
- }
-
- /**
- * @param e Transaction entry to set.
- * @return {@code True} if value was set.
- */
- @Override public boolean setWriteValue(IgniteTxEntry e) {
- checkInternal(e.txKey());
-
- IgniteTxEntry entry = writeMap.get(e.txKey());
-
- if (entry == null) {
- IgniteTxEntry rmv = readMap.remove(e.txKey());
-
- if (rmv != null) {
- e.cached(rmv.cached());
-
- writeMap.put(e.txKey(), e);
- }
- // If lock is explicit.
- else {
- e.cached(e.context().cache().entryEx(e.key()));
-
- // explicit lock.
- writeMap.put(e.txKey(), e);
- }
- }
- else {
- // Copy values.
- entry.value(e.value(), e.hasWriteValue(), e.hasReadValue());
- entry.entryProcessors(e.entryProcessors());
- entry.op(e.op());
- entry.ttl(e.ttl());
- entry.explicitVersion(e.explicitVersion());
-
- // Conflict resolution stuff.
- entry.conflictVersion(e.conflictVersion());
- entry.conflictExpireTime(e.conflictExpireTime());
- }
-
- addExplicit(e);
-
- return true;
- }
-
/** {@inheritDoc} */
@Override public boolean hasWriteKey(IgniteTxKey key) {
- return writeMap.containsKey(key);
+ return txState.hasWriteKey(key);
}
/** {@inheritDoc} */
@@ -400,27 +336,27 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
/** {@inheritDoc} */
@Override public Set<IgniteTxKey> readSet() {
- return readMap.keySet();
+ return txState.readSet();
}
/** {@inheritDoc} */
@Override public Set<IgniteTxKey> writeSet() {
- return writeMap.keySet();
+ return txState.writeSet();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> allEntries() {
- return F.concat(false, writeEntries(), readEntries());
+ return txState.allEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> writeEntries() {
- return writeMap.values();
+ return txState.writeEntries();
}
/** {@inheritDoc} */
@Override public Collection<IgniteTxEntry> readEntries() {
- return readMap.values();
+ return txState.readEntries();
}
/**
@@ -459,7 +395,7 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
@SuppressWarnings({"CatchGenericClass"})
private void commitIfLocked() throws IgniteCheckedException {
if (state() == COMMITTING) {
- for (IgniteTxEntry txEntry : writeMap.values()) {
+ for (IgniteTxEntry txEntry : writeEntries()) {
assert txEntry != null : "Missing transaction entry for tx: " + this;
while (true) {
@@ -494,6 +430,8 @@ public class GridDistributedTxRemoteAdapter extends IgniteTxAdapter
if (commitAllowed.compareAndSet(false, true)) {
IgniteCheckedException err = null;
+ Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
+
if (!F.isEmpty(writeMap)) {
// Register this transaction as completed prior to write-phase to
// ensure proper lock ordering for removed entries.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
index 3069afd..fe91e5b 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTransactionalCacheAdapter.java
@@ -228,7 +228,6 @@ public abstract class GridDhtTransactionalCacheAdapter<K, V> extends GridDhtCach
req.futureId(),
nodeId,
req.nearXidVersion(),
- req.threadId(),
req.topologyVersion(),
req.version(),
/*commitVer*/null,
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
index 44f34aa..2bed931 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocal.java
@@ -223,11 +223,6 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
}
/** {@inheritDoc} */
- @Override protected IgniteUuid nearMiniId() {
- return nearMiniId;
- }
-
- /** {@inheritDoc} */
@Override public boolean dht() {
return true;
}
@@ -307,8 +302,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
0,
nearMiniId,
null,
- true,
- null);
+ true);
}
// For pessimistic mode we don't distribute prepare request.
@@ -322,8 +316,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
nearMiniId,
Collections.<IgniteTxKey, GridCacheVersion>emptyMap(),
true,
- needReturnValue(),
- null)))
+ needReturnValue())))
return prepFut.get();
}
else
@@ -378,7 +371,6 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
* @param nearMiniId Near mini future ID.
* @param txNodes Transaction nodes mapping.
* @param last {@code True} if this is last prepare request.
- * @param lastBackups IDs of backup nodes receiving last prepare request.
* @return Future that will be completed when locks are acquired.
*/
public IgniteInternalFuture<GridNearTxPrepareResponse> prepareAsync(
@@ -388,8 +380,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
long msgId,
IgniteUuid nearMiniId,
Map<UUID, Collection<UUID>> txNodes,
- boolean last,
- Collection<UUID> lastBackups
+ boolean last
) {
// In optimistic mode prepare still can be called explicitly from salvageTx.
GridDhtTxPrepareFuture fut = prepFut.get();
@@ -404,8 +395,7 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
nearMiniId,
verMap,
last,
- needReturnValue(),
- lastBackups))) {
+ needReturnValue()))) {
GridDhtTxPrepareFuture f = prepFut.get();
assert f.nearMiniId().equals(nearMiniId) : "Wrong near mini id on existing future " +
@@ -443,13 +433,15 @@ public class GridDhtTxLocal extends GridDhtTxLocalAdapter implements GridCacheMa
}
try {
- if (reads != null)
+ if (reads != null) {
for (IgniteTxEntry e : reads)
addEntry(msgId, e);
+ }
- if (writes != null)
+ if (writes != null) {
for (IgniteTxEntry e : writes)
addEntry(msgId, e);
+ }
userPrepare();
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
index 6de8795..70ebf3f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxLocalAdapter.java
@@ -86,9 +86,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
protected volatile boolean mapped;
/** */
- private long dhtThreadId;
-
- /** */
protected boolean explicitLock;
/** Versions of pending locks for entries of this tx. */
@@ -159,7 +156,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
this.explicitLock = explicitLock;
threadId = Thread.currentThread().getId();
- dhtThreadId = threadId;
}
/**
@@ -216,11 +212,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
protected abstract IgniteUuid nearFutureId();
/**
- * @return Near future mini ID.
- */
- protected abstract IgniteUuid nearMiniId();
-
- /**
* Adds reader to cached entry.
*
* @param msgId Message ID.
@@ -260,13 +251,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
- * @return DHT thread ID.
- */
- long dhtThreadId() {
- return dhtThreadId;
- }
-
- /**
* Map explicit locks.
*/
protected void mapExplicitLocks() {
@@ -355,22 +339,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
- * @param nodeId Node ID.
- * @return Mapping.
- */
- GridDistributedTxMapping dhtMapping(UUID nodeId) {
- return dhtMap.get(nodeId);
- }
-
- /**
- * @param nodeId Node ID.
- * @return Mapping.
- */
- GridDistributedTxMapping nearMapping(UUID nodeId) {
- return nearMap.get(nodeId);
- }
-
- /**
* @param mappings Mappings to add.
*/
void addDhtNodeEntryMapping(Map<ClusterNode, List<GridDhtCacheEntry>> mappings) {
@@ -385,19 +353,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
/**
- * @param mappings Mappings to add.
- */
- public void addDhtMapping(Map<UUID, GridDistributedTxMapping> mappings) {
- addMapping0(mappings, dhtMap);
- }
-
- /**
- * @param mappings Mappings to add.
- */
- public void addNearMapping(Map<UUID, GridDistributedTxMapping> mappings) {
- addMapping0(mappings, nearMap);
- }
- /**
* @param nodeId Node ID.
* @return {@code True} if mapping was removed.
*/
@@ -435,7 +390,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
if (log.isDebugEnabled())
log.debug("Removing mapping for entry [nodeId=" + nodeId + ", entry=" + entry + ']');
- IgniteTxEntry txEntry = txMap.get(entry.txKey());
+ IgniteTxEntry txEntry = entry(entry.txKey());
if (txEntry == null)
return false;
@@ -469,7 +424,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
List<GridDhtCacheEntry> entries = mapping.getValue();
for (GridDhtCacheEntry entry : entries) {
- IgniteTxEntry txEntry = txMap.get(entry.txKey());
+ IgniteTxEntry txEntry = entry(entry.txKey());
if (txEntry != null) {
if (m == null)
@@ -481,26 +436,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
}
}
- /**
- * @param mappings Mappings to add.
- * @param dst Map to add to.
- */
- private void addMapping0(
- Map<UUID, GridDistributedTxMapping> mappings,
- Map<UUID, GridDistributedTxMapping> dst
- ) {
- for (Map.Entry<UUID, GridDistributedTxMapping> entry : mappings.entrySet()) {
- GridDistributedTxMapping targetMapping = dst.get(entry.getKey());
-
- if (targetMapping == null)
- dst.put(entry.getKey(), entry.getValue());
- else {
- for (IgniteTxEntry txEntry : entry.getValue().entries())
- targetMapping.add(txEntry);
- }
- }
- }
-
/** {@inheritDoc} */
@Override public void addInvalidPartition(GridCacheContext ctx, int part) {
assert false : "DHT transaction encountered invalid partition [part=" + part + ", tx=" + this + ']';
@@ -529,7 +464,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
GridDhtCacheAdapter dhtCache = cacheCtx.isNear() ? cacheCtx.near().dht() : cacheCtx.dht();
try {
- IgniteTxEntry existing = txMap.get(e.txKey());
+ IgniteTxEntry existing = entry(e.txKey());
if (existing != null) {
// Must keep NOOP operation if received READ because it means that the lock was sent to a backup node.
@@ -569,7 +504,7 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
existing.explicitVersion(dhtVer);
}
- txMap.put(existing.txKey(), existing);
+ txState.addEntry(existing);
if (log.isDebugEnabled())
log.debug("Added entry to transaction: " + existing);
@@ -705,7 +640,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
passedKeys,
read,
needRetVal,
- skipped,
accessTtl,
null,
skipStore);
@@ -723,7 +657,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
* @param passedKeys Passed keys.
* @param read {@code True} if read.
* @param needRetVal Return value flag.
- * @param skipped Skipped keys.
* @param accessTtl TTL for read operation.
* @param filter Entry write filter.
* @param skipStore Skip store flag.
@@ -735,13 +668,11 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
final Collection<KeyCacheObject> passedKeys,
final boolean read,
final boolean needRetVal,
- final Set<KeyCacheObject> skipped,
final long accessTtl,
@Nullable final CacheEntryPredicate[] filter,
boolean skipStore) {
if (log.isDebugEnabled())
- log.debug("Before acquiring transaction lock on keys [passedKeys=" + passedKeys + ", skipped=" +
- skipped + ']');
+ log.debug("Before acquiring transaction lock on keys [keys=" + passedKeys + ']');
if (passedKeys.isEmpty())
return new GridFinishedFuture<>(ret);
@@ -768,7 +699,6 @@ public abstract class GridDhtTxLocalAdapter extends IgniteTxLocalAdapter {
postLockWrite(cacheCtx,
passedKeys,
- skipped,
ret,
/*remove*/false,
/*retval*/false,
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
index 55cbe96..9ec35b6 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxMapping.java
@@ -17,18 +17,15 @@
package org.apache.ignite.internal.processors.cache.distributed.dht;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.UUID;
import org.apache.ignite.cluster.ClusterNode;
-import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxMapping;
import org.apache.ignite.internal.util.GridLeanMap;
+import org.apache.ignite.internal.util.GridLeanSet;
import org.apache.ignite.internal.util.typedef.F;
-import org.jetbrains.annotations.Nullable;
+import org.apache.ignite.internal.util.typedef.internal.U;
/**
* DHT transaction mapping.
@@ -37,12 +34,6 @@ public class GridDhtTxMapping {
/** Transaction nodes mapping (primary node -> related backup nodes). */
private final Map<UUID, Collection<UUID>> txNodes = new GridLeanMap<>();
- /** */
- private final List<TxMapping> mappings = new ArrayList<>();
-
- /** */
- private TxMapping last;
-
/**
* Adds information about next mapping.
*
@@ -50,24 +41,26 @@ public class GridDhtTxMapping {
*/
@SuppressWarnings("ConstantConditions")
public void addMapping(List<ClusterNode> nodes) {
- ClusterNode primary = F.first(nodes);
+ assert !F.isEmpty(nodes) : nodes;
- Collection<ClusterNode> backups = F.view(nodes, F.notEqualTo(primary));
+ ClusterNode primary = nodes.get(0);
- if (last == null || !last.primary.equals(primary.id())) {
- last = new TxMapping(primary, backups);
+ int size = nodes.size();
- mappings.add(last);
- }
- else
- last.add(backups);
+ if (size > 1) {
+ Collection<UUID> backups = txNodes.get(primary.id());
- Collection<UUID> storedBackups = txNodes.get(last.primary);
+ if (backups == null) {
+ backups = U.newHashSet(size - 1);
- if (storedBackups == null)
- txNodes.put(last.primary, storedBackups = new HashSet<>());
+ txNodes.put(primary.id(), backups);
+ }
- storedBackups.addAll(last.backups);
+ for (int i = 1; i < size; i++)
+ backups.add(nodes.get(i).id());
+ }
+ else
+ txNodes.put(primary.id(), new GridLeanSet<UUID>());
}
/**
@@ -76,99 +69,4 @@ public class GridDhtTxMapping {
public Map<UUID, Collection<UUID>> transactionNodes() {
return txNodes;
}
-
- /**
- * For each mapping sets flags indicating if mapping is last for node.
- *
- * @param mappings Mappings.
- */
- public void initLast(Collection<GridDistributedTxMapping> mappings) {
- assert this.mappings.size() == mappings.size();
-
- int idx = 0;
-
- for (GridDistributedTxMapping map : mappings) {
- TxMapping mapping = this.mappings.get(idx);
-
- map.lastBackups(lastBackups(mapping, idx));
-
- boolean last = true;
-
- for (int i = idx + 1; i < this.mappings.size(); i++) {
- TxMapping nextMap = this.mappings.get(i);
-
- if (nextMap.primary.equals(mapping.primary)) {
- last = false;
-
- break;
- }
- }
-
- map.last(last);
-
- idx++;
- }
- }
-
- /**
- * @param mapping Mapping.
- * @param idx Mapping index.
- * @return IDs of backup nodes receiving last prepare request during this mapping.
- */
- @Nullable private Collection<UUID> lastBackups(TxMapping mapping, int idx) {
- Collection<UUID> res = null;
-
- for (UUID backup : mapping.backups) {
- boolean foundNext = false;
-
- for (int i = idx + 1; i < mappings.size(); i++) {
- TxMapping nextMap = mappings.get(i);
-
- if (nextMap.primary.equals(mapping.primary) && nextMap.backups.contains(backup)) {
- foundNext = true;
-
- break;
- }
- }
-
- if (!foundNext) {
- if (res == null)
- res = new ArrayList<>(mapping.backups.size());
-
- res.add(backup);
- }
- }
-
- return res;
- }
-
- /**
- */
- private static class TxMapping {
- /** */
- private final UUID primary;
-
- /** */
- private final Set<UUID> backups;
-
- /**
- * @param primary Primary node.
- * @param backups Backup nodes.
- */
- private TxMapping(ClusterNode primary, Iterable<ClusterNode> backups) {
- this.primary = primary.id();
-
- this.backups = new HashSet<>();
-
- add(backups);
- }
-
- /**
- * @param backups Backup nodes.
- */
- private void add(Iterable<ClusterNode> backups) {
- for (ClusterNode n : backups)
- this.backups.add(n.id());
- }
- }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
index 1d6f633..a67950d 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxPrepareFuture.java
@@ -165,9 +165,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
/** {@code True} if this is last prepare operation for node. */
private boolean last;
- /** IDs of backup nodes receiving last prepare request during this prepare. */
- private Collection<UUID> lastBackups;
-
/** Needs return value flag. */
private boolean retVal;
@@ -197,7 +194,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
* @param dhtVerMap DHT versions map.
* @param last {@code True} if this is last prepare operation for node.
* @param retVal Return value flag.
- * @param lastBackups IDs of backup nodes receiving last prepare request during this prepare.
*/
public GridDhtTxPrepareFuture(
GridCacheSharedContext cctx,
@@ -205,8 +201,7 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
IgniteUuid nearMiniId,
Map<IgniteTxKey, GridCacheVersion> dhtVerMap,
boolean last,
- boolean retVal,
- Collection<UUID> lastBackups
+ boolean retVal
) {
super(REDUCER);
@@ -214,7 +209,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
this.tx = tx;
this.dhtVerMap = dhtVerMap;
this.last = last;
- this.lastBackups = lastBackups;
futId = IgniteUuid.randomUuid();
@@ -864,14 +858,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
}
/**
- * @param backupId Backup node ID.
- * @return {@code True} if backup node receives last prepare request for this transaction.
- */
- private boolean lastBackup(UUID backupId) {
- return lastBackups != null && lastBackups.contains(backupId);
- }
-
- /**
* Checks if this transaction needs previous value for the given tx entry. Will use passed in map to store
* required key or will create new map if passed in map is {@code null}.
*
@@ -1022,18 +1008,15 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
tx.writeVersion(cctx.versions().next(tx.topologyVersion()));
{
- Map<UUID, GridDistributedTxMapping> futDhtMap = new HashMap<>();
- Map<UUID, GridDistributedTxMapping> futNearMap = new HashMap<>();
-
// Assign keys to primary nodes.
if (!F.isEmpty(writes)) {
for (IgniteTxEntry write : writes)
- map(tx.entry(write.txKey()), futDhtMap, futNearMap);
+ map(tx.entry(write.txKey()));
}
if (!F.isEmpty(reads)) {
for (IgniteTxEntry read : reads)
- map(tx.entry(read.txKey()), futDhtMap, futNearMap);
+ map(tx.entry(read.txKey()));
}
}
@@ -1225,14 +1208,8 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
/**
* @param entry Transaction entry.
- * @param futDhtMap DHT mapping.
- * @param futNearMap Near mapping.
*/
- private void map(
- IgniteTxEntry entry,
- Map<UUID, GridDistributedTxMapping> futDhtMap,
- Map<UUID, GridDistributedTxMapping> futNearMap
- ) {
+ private void map(IgniteTxEntry entry) {
if (entry.cached().isLocal())
return;
@@ -1258,26 +1235,25 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
log.debug("Mapping entry to DHT nodes [nodes=" + U.toShortString(dhtNodes) +
", entry=" + entry + ']');
- Collection<UUID> readers = cached.readers();
+ // Exclude local node.
+ map(entry, F.view(dhtNodes, F.remoteNodes(cctx.localNodeId())), dhtMap);
- Collection<ClusterNode> nearNodes = null;
+ Collection<UUID> readers = cached.readers();
if (!F.isEmpty(readers)) {
- nearNodes = cctx.discovery().nodes(readers, F0.not(F.idForNodeId(tx.nearNodeId())));
+ Collection<ClusterNode> nearNodes =
+ cctx.discovery().nodes(readers, F0.not(F.idForNodeId(tx.nearNodeId())));
if (log.isDebugEnabled())
log.debug("Mapping entry to near nodes [nodes=" + U.toShortString(nearNodes) +
", entry=" + entry + ']');
+
+ // Exclude DHT nodes.
+ map(entry, F.view(nearNodes, F0.notIn(dhtNodes)), nearMap);
}
else if (log.isDebugEnabled())
log.debug("Entry has no near readers: " + entry);
- // Exclude local node.
- map(entry, F.view(dhtNodes, F.remoteNodes(cctx.localNodeId())), dhtMap, futDhtMap);
-
- // Exclude DHT nodes.
- map(entry, F.view(nearNodes, F0.notIn(dhtNodes)), nearMap, futNearMap);
-
break;
}
catch (GridCacheEntryRemovedException ignore) {
@@ -1292,13 +1268,11 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
* @param entry Entry.
* @param nodes Nodes.
* @param globalMap Map.
- * @param locMap Exclude map.
*/
private void map(
IgniteTxEntry entry,
Iterable<ClusterNode> nodes,
- Map<UUID, GridDistributedTxMapping> globalMap,
- Map<UUID, GridDistributedTxMapping> locMap
+ Map<UUID, GridDistributedTxMapping> globalMap
) {
if (nodes != null) {
for (ClusterNode n : nodes) {
@@ -1321,13 +1295,6 @@ public final class GridDhtTxPrepareFuture extends GridCompoundFuture<IgniteInter
globalMap.put(n.id(), global = new GridDistributedTxMapping(n));
global.add(entry);
-
- GridDistributedTxMapping loc = locMap.get(n.id());
-
- if (loc == null)
- locMap.put(n.id(), loc = new GridDistributedTxMapping(n));
-
- loc.add(entry);
}
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
index e268a88..0cbe10f 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtTxRemote.java
@@ -36,6 +36,8 @@ import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedTxRemoteAdapter;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteTxKey;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteSingleStateImpl;
+import org.apache.ignite.internal.processors.cache.transactions.IgniteTxRemoteStateImpl;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.tostring.GridToStringBuilder;
import org.apache.ignite.internal.util.typedef.T2;
@@ -77,7 +79,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
* @param nearNodeId Near node ID.
* @param rmtFutId Remote future ID.
* @param nodeId Node ID.
- * @param rmtThreadId Remote thread ID.
* @param topVer Topology version.
* @param xidVer XID version.
* @param commitVer Commit version.
@@ -96,7 +97,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
UUID nearNodeId,
IgniteUuid rmtFutId,
UUID nodeId,
- long rmtThreadId,
AffinityTopologyVersion topVer,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
@@ -110,12 +110,12 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
GridCacheVersion nearXidVer,
Map<UUID, Collection<UUID>> txNodes,
@Nullable UUID subjId,
- int taskNameHash
+ int taskNameHash,
+ boolean single
) {
super(
ctx,
nodeId,
- rmtThreadId,
xidVer,
commitVer,
sys,
@@ -137,9 +137,10 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
this.nearXidVer = nearXidVer;
this.txNodes = txNodes;
- readMap = Collections.emptyMap();
-
- writeMap = new ConcurrentLinkedHashMap<>(U.capacity(txSize), 0.75f, 1);
+ txState = single ? new IgniteTxRemoteSingleStateImpl() :
+ new IgniteTxRemoteStateImpl(
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap(),
+ new ConcurrentLinkedHashMap<IgniteTxKey, IgniteTxEntry>(U.capacity(txSize), 0.75f, 1));
topologyVersion(topVer);
}
@@ -151,7 +152,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
* @param rmtFutId Remote future ID.
* @param nodeId Node ID.
* @param nearXidVer Near transaction ID.
- * @param rmtThreadId Remote thread ID.
* @param topVer Topology version.
* @param xidVer XID version.
* @param commitVer Commit version.
@@ -169,7 +169,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
IgniteUuid rmtFutId,
UUID nodeId,
GridCacheVersion nearXidVer,
- long rmtThreadId,
AffinityTopologyVersion topVer,
GridCacheVersion xidVer,
GridCacheVersion commitVer,
@@ -186,7 +185,6 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
super(
ctx,
nodeId,
- rmtThreadId,
xidVer,
commitVer,
sys,
@@ -207,8 +205,9 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
this.nearNodeId = nearNodeId;
this.rmtFutId = rmtFutId;
- readMap = Collections.emptyMap();
- writeMap = new ConcurrentLinkedHashMap<>(U.capacity(txSize), 0.75f, 1);
+ txState = new IgniteTxRemoteStateImpl(
+ Collections.<IgniteTxKey, IgniteTxEntry>emptyMap(),
+ new ConcurrentLinkedHashMap<IgniteTxKey, IgniteTxEntry>(U.capacity(txSize), 0.75f, 1));
topologyVersion(topVer);
}
@@ -280,6 +279,8 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
@Override public void addInvalidPartition(GridCacheContext cacheCtx, int part) {
super.addInvalidPartition(cacheCtx, part);
+ Map<IgniteTxKey, IgniteTxEntry> writeMap = txState.writeMap();
+
for (Iterator<IgniteTxEntry> it = writeMap.values().iterator(); it.hasNext();) {
IgniteTxEntry e = it.next();
@@ -312,7 +313,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
// Initialize cache entry.
entry.cached(cached);
- writeMap.put(entry.txKey(), entry);
+ txState.addWriteEntry(entry.txKey(), entry);
addExplicit(entry);
}
@@ -356,7 +357,7 @@ public class GridDhtTxRemote extends GridDistributedTxRemoteAdapter {
txEntry.entryProcessors(entryProcessors);
- writeMap.put(key, txEntry);
+ txState.addWriteEntry(key, txEntry);
}
/** {@inheritDoc} */
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
index 5488bb1..29774a5 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticSerializableTxPrepareFuture.java
@@ -29,7 +29,6 @@ import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.cluster.ClusterTopologyException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
-import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -57,7 +56,6 @@ import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.P1;
import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteBiTuple;
@@ -326,19 +324,6 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
txMapping = new GridDhtTxMapping();
- if (!F.isEmpty(reads) || !F.isEmpty(writes)) {
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (CU.affinityNodes(cacheCtx, topVer).isEmpty()) {
- onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
- "partition nodes left the grid): " + cacheCtx.name()));
-
- return;
- }
- }
- }
-
Map<IgniteBiTuple<ClusterNode, Boolean>, GridDistributedTxMapping> mappings = new HashMap<>();
for (IgniteTxEntry write : writes)
@@ -437,7 +422,6 @@ public class GridNearOptimisticSerializableTxPrepareFuture extends GridNearOptim
m.near(),
txMapping.transactionNodes(),
m.last(),
- m.lastBackups(),
tx.onePhaseCommit(),
tx.needReturnValue() && tx.implicit(),
tx.implicitSingle(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
index 0002180..791d2f3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFuture.java
@@ -19,7 +19,9 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
import java.util.ArrayDeque;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -28,7 +30,6 @@ import org.apache.ignite.cluster.ClusterNode;
import org.apache.ignite.cluster.ClusterTopologyException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.cluster.ClusterTopologyCheckedException;
-import org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheEntryEx;
@@ -50,7 +51,6 @@ import org.apache.ignite.internal.util.typedef.C1;
import org.apache.ignite.internal.util.typedef.CI1;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.X;
-import org.apache.ignite.internal.util.typedef.internal.CU;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.lang.IgniteClosure;
@@ -267,7 +267,12 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
return;
}
- prepare(tx.writeEntries(), topLocked);
+ IgniteTxEntry singleWrite = tx.singleWrite();
+
+ if (singleWrite != null)
+ prepareSingle(singleWrite, topLocked);
+ else
+ prepare(tx.writeEntries(), topLocked);
markInitialized();
}
@@ -280,6 +285,46 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
}
/**
+ * @param write Write.
+ * @param topLocked {@code True} if thread already acquired lock preventing topology change.
+ */
+ private void prepareSingle(IgniteTxEntry write, boolean topLocked) {
+ AffinityTopologyVersion topVer = tx.topologyVersion();
+
+ assert topVer.topologyVersion() > 0;
+
+ txMapping = new GridDhtTxMapping();
+
+ GridDistributedTxMapping mapping = map(write, topVer, null, topLocked);
+
+ if (mapping.node().isLocal()) {
+ if (write.context().isNear())
+ tx.nearLocallyMapped(true);
+ else if (write.context().isColocated())
+ tx.colocatedLocallyMapped(true);
+ }
+
+ if (isDone()) {
+ if (log.isDebugEnabled())
+ log.debug("Abandoning (re)map because future is done: " + this);
+
+ return;
+ }
+
+ tx.addSingleEntryMapping(mapping, write);
+
+ cctx.mvcc().recheckPendingLocks();
+
+ mapping.last(true);
+
+ tx.transactionNodes(txMapping.transactionNodes());
+
+ checkOnePhase();
+
+ proceedPrepare(mapping, null);
+ }
+
+ /**
* @param writes Write entries.
* @param topLocked {@code True} if thread already acquired lock preventing topology change.
* @throws IgniteCheckedException If failed.
@@ -294,30 +339,26 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
txMapping = new GridDhtTxMapping();
- Queue<GridDistributedTxMapping> mappings = new ArrayDeque<>();
-
- if (!F.isEmpty(writes)) {
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (CU.affinityNodes(cacheCtx, topVer).isEmpty()) {
- onDone(new ClusterTopologyServerNotFoundException("Failed to map keys for cache (all " +
- "partition nodes left the grid): " + cacheCtx.name()));
-
- return;
- }
- }
- }
+ Map<UUID, GridDistributedTxMapping> map = new HashMap<>();
// Assign keys to primary nodes.
GridDistributedTxMapping cur = null;
+ Queue<GridDistributedTxMapping> mappings = new ArrayDeque<>();
+
for (IgniteTxEntry write : writes) {
GridDistributedTxMapping updated = map(write, topVer, cur, topLocked);
if (cur != updated) {
mappings.offer(updated);
+ updated.last(true);
+
+ GridDistributedTxMapping prev = map.put(updated.node().id(), updated);
+
+ if (prev != null)
+ prev.last(false);
+
if (updated.node().isLocal()) {
if (write.context().isNear())
tx.nearLocallyMapped(true);
@@ -340,8 +381,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
cctx.mvcc().recheckPendingLocks();
- txMapping.initLast(mappings);
-
tx.transactionNodes(txMapping.transactionNodes());
checkOnePhase();
@@ -355,14 +394,24 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
* @param mappings Queue of mappings.
*/
private void proceedPrepare(final Queue<GridDistributedTxMapping> mappings) {
- if (isDone())
- return;
-
final GridDistributedTxMapping m = mappings.poll();
if (m == null)
return;
+ proceedPrepare(m, mappings);
+ }
+
+ /**
+ * Continues prepare after previous mapping successfully finished.
+ *
+ * @param m Mapping.
+ * @param mappings Queue of mappings.
+ */
+ private void proceedPrepare(GridDistributedTxMapping m, @Nullable final Queue<GridDistributedTxMapping> mappings) {
+ if (isDone())
+ return;
+
assert !m.empty();
final ClusterNode n = m.node();
@@ -376,7 +425,6 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
m.near(),
txMapping.transactionNodes(),
m.last(),
- m.lastBackups(),
tx.onePhaseCommit(),
tx.needReturnValue() && tx.implicit(),
tx.implicitSingle(),
@@ -457,7 +505,14 @@ public class GridNearOptimisticTxPrepareFuture extends GridNearOptimisticTxPrepa
) {
GridCacheContext cacheCtx = entry.context();
- List<ClusterNode> nodes = cacheCtx.affinity().nodes(entry.key(), topVer);
+ List<ClusterNode> nodes;
+
+ GridCacheEntryEx cached0 = entry.cached();
+
+ if (cached0.isDht())
+ nodes = cacheCtx.affinity().nodes(cached0.partition(), topVer);
+ else
+ nodes = cacheCtx.affinity().nodes(entry.key(), topVer);
txMapping.addMapping(nodes);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
index fd9183e..6b7244a 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearOptimisticTxPrepareFutureAdapter.java
@@ -20,13 +20,11 @@ package org.apache.ignite.internal.processors.cache.distributed.near;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.IgniteInternalFuture;
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
-import org.apache.ignite.internal.processors.cache.GridCacheContext;
import org.apache.ignite.internal.processors.cache.GridCacheSharedContext;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFuture;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.util.lang.GridPlainRunnable;
import org.apache.ignite.internal.util.typedef.CI1;
-import org.apache.ignite.internal.util.typedef.internal.U;
import org.jetbrains.annotations.Nullable;
/**
@@ -75,56 +73,14 @@ public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearT
* @return Topology ready future.
*/
protected final GridDhtTopologyFuture topologyReadLock() {
- if (tx.activeCacheIds().isEmpty())
- return cctx.exchange().lastTopologyFuture();
-
- GridCacheContext<?, ?> nonLocCtx = null;
-
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (!cacheCtx.isLocal()) {
- nonLocCtx = cacheCtx;
-
- break;
- }
- }
-
- if (nonLocCtx == null)
- return cctx.exchange().lastTopologyFuture();
-
- nonLocCtx.topology().readLock();
-
- if (nonLocCtx.topology().stopping()) {
- onDone(new IgniteCheckedException("Failed to perform cache operation (cache is stopped): " +
- nonLocCtx.name()));
-
- return null;
- }
-
- return nonLocCtx.topology().topologyVersionFuture();
+ return tx.txState().topologyReadLock(cctx, this);
}
/**
* Releases topology read lock.
*/
protected final void topologyReadUnlock() {
- if (!tx.activeCacheIds().isEmpty()) {
- GridCacheContext<?, ?> nonLocCtx = null;
-
- for (int cacheId : tx.activeCacheIds()) {
- GridCacheContext<?, ?> cacheCtx = cctx.cacheContext(cacheId);
-
- if (!cacheCtx.isLocal()) {
- nonLocCtx = cacheCtx;
-
- break;
- }
- }
-
- if (nonLocCtx != null)
- nonLocCtx.topology().readUnlock();
- }
+ tx.txState().topologyReadUnlock(cctx);
}
/**
@@ -160,28 +116,10 @@ public abstract class GridNearOptimisticTxPrepareFutureAdapter extends GridNearT
}
if (topVer != null) {
- StringBuilder invalidCaches = null;
-
- for (Integer cacheId : tx.activeCacheIds()) {
- GridCacheContext ctx = cctx.cacheContext(cacheId);
-
- assert ctx != null : cacheId;
-
- Throwable err = topFut.validateCache(ctx);
-
- if (err != null) {
- if (invalidCaches != null)
- invalidCaches.append(", ");
- else
- invalidCaches = new StringBuilder();
-
- invalidCaches.append(U.maskName(ctx.name()));
- }
- }
+ IgniteCheckedException err = tx.txState().validateTopology(cctx, topFut);
- if (invalidCaches != null) {
- onDone(new IgniteCheckedException("Failed to perform cache operation (cache topology is not valid): " +
- invalidCaches.toString()));
+ if (err != null) {
+ onDone(err);
return;
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
index 11d31b2..1554a62 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearPessimisticTxPrepareFuture.java
@@ -200,7 +200,6 @@ public class GridNearPessimisticTxPrepareFuture extends GridNearTxPrepareFutureA
m.near(),
txMapping.transactionNodes(),
true,
- txMapping.transactionNodes().get(node.id()),
tx.onePhaseCommit(),
tx.needReturnValue() && tx.implicit(),
tx.implicitSingle(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
index 5ab85b2..e8546ef 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTransactionalCache.java
@@ -315,7 +315,6 @@ public class GridNearTransactionalCache<K, V> extends GridNearCacheAdapter<K, V>
nodeId,
req.nearNodeId(),
req.nearXidVersion(),
- req.threadId(),
req.version(),
null,
ctx.systemTx(),
http://git-wip-us.apache.org/repos/asf/ignite/blob/3ff71fd7/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
index a9dbda2..31aa8c3 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/near/GridNearTxFinishFuture.java
@@ -88,7 +88,7 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
private boolean commit;
/** Node mappings. */
- private Map<UUID, GridDistributedTxMapping> mappings;
+ private IgniteTxMappings mappings;
/** Trackable flag. */
private boolean trackable = true;
@@ -347,8 +347,16 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
try {
if (tx.finish(commit) || (!commit && tx.state() == UNKNOWN)) {
- if ((tx.onePhaseCommit() && needFinishOnePhase()) || (!tx.onePhaseCommit() && mappings != null))
- finish(mappings.values());
+ if ((tx.onePhaseCommit() && needFinishOnePhase()) || (!tx.onePhaseCommit() && mappings != null)) {
+ if (mappings.single()) {
+ GridDistributedTxMapping mapping = mappings.singleMapping();
+
+ if (mapping != null)
+ finish(mapping);
+ }
+ else
+ finish(mappings.mappings());
+ }
markInitialized();
@@ -381,11 +389,10 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
*
*/
private void checkBackup() {
- assert mappings.size() <= 1;
+ GridDistributedTxMapping mapping = mappings.singleMapping();
- for (Map.Entry<UUID, GridDistributedTxMapping> entry : mappings.entrySet()) {
- UUID nodeId = entry.getKey();
- GridDistributedTxMapping mapping = entry.getValue();
+ if (mapping != null) {
+ UUID nodeId = mapping.node().id();
Collection<UUID> backups = tx.transactionNodes().get(nodeId);
@@ -482,25 +489,13 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
*
*/
private boolean needFinishOnePhase() {
- if (F.isEmpty(tx.mappings()))
+ if (tx.mappings().empty())
return false;
- assert tx.mappings().size() == 1;
-
- boolean finish = false;
-
- for (Integer cacheId : tx.activeCacheIds()) {
- GridCacheContext<K, V> cacheCtx = cctx.cacheContext(cacheId);
-
- if (cacheCtx.isNear()) {
- finish = true;
-
- break;
- }
- }
+ boolean finish = tx.txState().hasNearCache(cctx);
if (finish) {
- GridDistributedTxMapping mapping = F.first(tx.mappings().values());
+ GridDistributedTxMapping mapping = tx.mappings().singleMapping();
if (FINISH_NEAR_ONE_PHASE_SINCE.compareTo(mapping.node().version()) > 0)
finish = false;
@@ -520,18 +515,16 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
finishOnePhaseCalled = true;
- // No need to send messages as transaction was already committed on remote node.
- // Finish local mapping only as we need send commit message to backups.
- for (GridDistributedTxMapping m : mappings.values()) {
- if (m.node().isLocal()) {
- IgniteInternalFuture<IgniteInternalTx> fut = cctx.tm().txHandler().finishColocatedLocal(commit, tx);
+ GridDistributedTxMapping locMapping = mappings.localMapping();
- // Add new future.
- if (fut != null)
- add(fut);
+ if (locMapping != null) {
+ // No need to send messages as transaction was already committed on remote node.
+ // Finish local mapping only as we need send commit message to backups.
+ IgniteInternalFuture<IgniteInternalTx> fut = cctx.tm().txHandler().finishColocatedLocal(commit, tx);
- break;
- }
+ // Add new future.
+ if (fut != null)
+ add(fut);
}
}
@@ -544,7 +537,9 @@ public final class GridNearTxFinishFuture<K, V> extends GridCompoundIdentityFutu
mapping.dhtVersion(xidVer, xidVer);
- tx.readyNearLocks(mapping, Collections.<GridCacheVersion>emptyList(), Collections.<GridCacheVersion>emptyList(),
+ tx.readyNearLocks(mapping,
+ Collections.<GridCacheVersion>emptyList(),
+ Collections.<GridCacheVersion>emptyList(),
Collections.<GridCacheVersion>emptyList());
}
}