Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id E87C8200BCE for ; Fri, 2 Dec 2016 10:25:10 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id E7444160B16; Fri, 2 Dec 2016 09:25:10 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id AF421160B37 for ; Fri, 2 Dec 2016 10:25:08 +0100 (CET) Received: (qmail 79031 invoked by uid 500); 2 Dec 2016 09:25:07 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 78586 invoked by uid 99); 2 Dec 2016 09:25:07 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 02 Dec 2016 09:25:07 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 82024F17BF; Fri, 2 Dec 2016 09:25:07 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sboikov@apache.org To: commits@ignite.apache.org Date: Fri, 02 Dec 2016 09:25:24 -0000 Message-Id: <82918e3f5f9d41d6bf4b838571ef5c5d@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [18/19] ignite git commit: ignite-4285 For serializable txs allow multiple threads to get read lock for the same key archived-at: Fri, 02 Dec 2016 09:25:11 -0000 ignite-4285 For serializable txs allow multiple threads to get read lock for the same key Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/33dda460 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/33dda460 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/33dda460 Branch: refs/heads/master Commit: 33dda46061aae73e5c138851cfdd5f49a1c254cb Parents: 12bdd6a Author: sboikov Authored: Fri Dec 2 12:13:38 2016 +0300 Committer: sboikov Committed: Fri Dec 2 12:15:14 2016 +0300 ---------------------------------------------------------------------- .../processors/cache/CacheLockCandidates.java | 42 ++ .../cache/CacheLockCandidatesList.java | 71 +++ .../processors/cache/GridCacheEntryEx.java | 3 +- .../processors/cache/GridCacheMapEntry.java | 117 +++- .../processors/cache/GridCacheMvcc.java | 376 ++++++++---- .../processors/cache/GridCacheMvccCallback.java | 4 +- .../cache/GridCacheMvccCandidate.java | 80 ++- .../processors/cache/GridCacheMvccManager.java | 19 +- .../distributed/GridDistributedCacheEntry.java | 303 +++------- .../distributed/dht/GridDhtCacheEntry.java | 32 +- .../distributed/dht/GridDhtLockFuture.java | 34 +- .../dht/GridDhtTransactionalCacheAdapter.java | 1 - .../distributed/dht/GridDhtTxPrepareFuture.java | 5 +- .../colocated/GridDhtColocatedLockFuture.java | 8 +- .../distributed/near/GridNearCacheEntry.java | 44 +- .../distributed/near/GridNearLockFuture.java | 3 +- .../near/GridNearTransactionalCache.java | 5 +- .../cache/local/GridLocalCacheEntry.java | 173 ++---- .../cache/local/GridLocalLockFuture.java | 2 +- .../cache/transactions/IgniteTxManager.java | 6 +- .../CacheSerializableTransactionsTest.java | 604 ++++++++++++++++++- .../cache/GridCacheMvccFlagsTest.java | 8 +- .../cache/GridCacheMvccPartitionedSelfTest.java | 334 ++++++++-- .../processors/cache/GridCacheMvccSelfTest.java | 212 +++---- .../processors/cache/GridCacheTestEntryEx.java | 77 +-- .../loadtests/hashmap/GridHashMapLoadTest.java | 7 +- 26 files changed, 1721 insertions(+), 849 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidates.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidates.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidates.java new file mode 100644 index 0000000..9cf16f4 --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidates.java @@ -0,0 +1,42 @@ +/* + * 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; + +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; + +/** + * + */ +public interface CacheLockCandidates { + /** + * @param idx Candidate index. + * @return Candidate. + */ + public GridCacheMvccCandidate candidate(int idx); + + /** + * @return Number of candidates. + */ + public int size(); + + /** + * @param ver Candidate version. + * @return {@code True} if contains candidate with given version. + */ + public boolean hasCandidate(GridCacheVersion ver); +} http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidatesList.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidatesList.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidatesList.java new file mode 100644 index 0000000..e026bce --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/CacheLockCandidatesList.java @@ -0,0 +1,71 @@ +/* + * 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; + +import java.util.ArrayList; +import java.util.List; +import org.apache.ignite.internal.processors.cache.version.GridCacheVersion; +import org.apache.ignite.internal.util.tostring.GridToStringInclude; +import org.apache.ignite.internal.util.typedef.internal.S; + +/** + * + */ +class CacheLockCandidatesList implements CacheLockCandidates { + /** */ + @GridToStringInclude + private List list = new ArrayList<>(); + + /** + * @param cand Candidate to add. + */ + void add(GridCacheMvccCandidate cand) { + assert !hasCandidate(cand.version()) : cand; + + list.add(cand); + } + + /** {@inheritDoc} */ + @Override public GridCacheMvccCandidate candidate(int idx) { + assert idx < list.size() : idx; + + return list.get(idx); + } + + /** {@inheritDoc} */ + @Override public int size() { + return list.size(); + } + + /** {@inheritDoc} */ + @Override public boolean hasCandidate(GridCacheVersion ver) { + for (int i = 0; i < list.size(); i++) { + GridCacheMvccCandidate cand = list.get(i); + + if (cand.version().equals(ver)) + return true; + } + + return false; + } + + /** {@inheritDoc} */ + @Override public String toString() { + return S.toString(CacheLockCandidatesList.class, this); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java index 176fe77..d8194fc 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheEntryEx.java @@ -565,6 +565,7 @@ public interface GridCacheEntryEx { * @param timeout Timeout for lock acquisition. * @param serOrder Version for serializable transactions ordering. * @param serReadVer Optional read entry version for optimistic serializable transaction. + * @param read Read lock flag. * @return {@code True} if lock was acquired, {@code false} otherwise. * @throws GridCacheEntryRemovedException If this entry is obsolete. * @throws GridDistributedLockCancelledException If lock has been cancelled. @@ -573,7 +574,7 @@ public interface GridCacheEntryEx { long timeout, @Nullable GridCacheVersion serOrder, @Nullable GridCacheVersion serReadVer, - boolean keepBinary + boolean read ) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException; /** http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/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 aec28bb..31baeda 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 @@ -79,9 +79,11 @@ import org.apache.ignite.lang.IgniteUuid; import org.jetbrains.annotations.Nullable; import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_EXPIRED; +import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_LOCKED; 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.events.EventType.EVT_CACHE_OBJECT_UNLOCKED; import static org.apache.ignite.internal.processors.cache.GridCacheOperation.DELETE; import static org.apache.ignite.internal.processors.dr.GridDrType.DR_NONE; @@ -827,8 +829,6 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme if (readThrough && !cctx.readThrough()) readThrough = false; - GridCacheMvccCandidate owner; - CacheObject ret; GridCacheVersion startVer; @@ -841,10 +841,6 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme synchronized (this) { checkObsolete(); - GridCacheMvcc mvcc = mvccExtras(); - - owner = mvcc == null ? null : mvcc.anyOwner(); - boolean valid = valid(tx != null ? tx.topologyVersion() : cctx.affinity().affinityTopologyVersion()); CacheObject val; @@ -899,11 +895,13 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) { transformClo = EntryProcessorResourceInjectorProxy.unwrap(transformClo); + GridCacheMvcc mvcc = mvccExtras(); + cctx.events().addEvent( partition(), key, tx, - owner, + mvcc != null ? mvcc.anyOwner() : null, EVT_CACHE_OBJECT_READ, ret, ret != null, @@ -1010,11 +1008,13 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme if (evt && cctx.events().isRecordable(EVT_CACHE_OBJECT_READ)) { transformClo = EntryProcessorResourceInjectorProxy.unwrap(transformClo); + GridCacheMvcc mvcc = mvccExtras(); + cctx.events().addEvent( partition(), key, tx, - owner, + mvcc != null ? mvcc.anyOwner() : null, EVT_CACHE_OBJECT_READ, ret, ret != null, @@ -3391,14 +3391,14 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme } /** {@inheritDoc} */ - @Override public synchronized boolean hasValue() { + @Override public final synchronized boolean hasValue() { return hasValueUnlocked(); } /** * @return {@code True} if this entry has value. */ - protected boolean hasValueUnlocked() { + protected final boolean hasValueUnlocked() { assert Thread.holdsLock(this); return val != null || hasOffHeapPointer(); @@ -4318,7 +4318,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme } /** {@inheritDoc} */ - @Override public GridCacheBatchSwapEntry evictInBatchInternal(GridCacheVersion obsoleteVer) + @Override public final GridCacheBatchSwapEntry evictInBatchInternal(GridCacheVersion obsoleteVer) throws IgniteCheckedException { assert Thread.holdsLock(this); assert cctx.isSwapOrOffheapEnabled(); @@ -4385,7 +4385,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme * @param filter Entry filter. * @return {@code True} if entry is visitable. */ - public boolean visitable(CacheEntryPredicate[] filter) { + public final boolean visitable(CacheEntryPredicate[] filter) { boolean rmv = false; try { @@ -4440,7 +4440,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme } /** {@inheritDoc} */ - @Override public boolean deleted() { + @Override public final boolean deleted() { if (!cctx.deferredDelete()) return false; @@ -4450,7 +4450,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme } /** {@inheritDoc} */ - @Override public synchronized boolean obsoleteOrDeleted() { + @Override public final synchronized boolean obsoleteOrDeleted() { return obsoleteVersionExtras() != null || (cctx.deferredDelete() && (deletedUnlocked() || !hasValueUnlocked())); } @@ -4459,7 +4459,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme * @return {@code True} if deleted. */ @SuppressWarnings("SimplifiableIfStatement") - protected boolean deletedUnlocked() { + protected final boolean deletedUnlocked() { assert Thread.holdsLock(this); if (!cctx.deferredDelete()) @@ -4471,7 +4471,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme /** * @param deleted {@code True} if deleted. */ - protected void deletedUnlocked(boolean deleted) { + protected final void deletedUnlocked(boolean deleted) { assert Thread.holdsLock(this); assert cctx.deferredDelete(); @@ -4508,7 +4508,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme /** * @return MVCC. */ - @Nullable protected GridCacheMvcc mvccExtras() { + @Nullable protected final GridCacheMvcc mvccExtras() { return extras != null ? extras.mvcc() : null; } @@ -4516,7 +4516,7 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme * @return All MVCC local and non near candidates. */ @SuppressWarnings("ForLoopReplaceableByForEach") - @Nullable public synchronized List mvccAllLocal() { + @Nullable public final synchronized List mvccAllLocal() { GridCacheMvcc mvcc = extras != null ? extras.mvcc() : null; if (mvcc == null) @@ -4542,21 +4542,22 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme /** * @param mvcc MVCC. */ - protected void mvccExtras(@Nullable GridCacheMvcc mvcc) { + protected final void mvccExtras(@Nullable GridCacheMvcc mvcc) { extras = (extras != null) ? extras.mvcc(mvcc) : mvcc != null ? new GridCacheMvccEntryExtras(mvcc) : null; } /** * @return Obsolete version. */ - @Nullable protected GridCacheVersion obsoleteVersionExtras() { + @Nullable protected final GridCacheVersion obsoleteVersionExtras() { return extras != null ? extras.obsoleteVersion() : null; } /** * @param obsoleteVer Obsolete version. + * @param ext Extras. */ - protected void obsoleteVersionExtras(@Nullable GridCacheVersion obsoleteVer, GridCacheObsoleteEntryExtras ext) { + private void obsoleteVersionExtras(@Nullable GridCacheVersion obsoleteVer, GridCacheObsoleteEntryExtras ext) { extras = (extras != null) ? extras.obsoleteVersion(obsoleteVer) : obsoleteVer != null ? @@ -4565,6 +4566,80 @@ public abstract class GridCacheMapEntry extends GridMetadataAwareAdapter impleme } /** + * @param prevOwners Previous owners. + * @param owners Current owners. + * @param val Entry value. + */ + protected final void checkOwnerChanged(@Nullable CacheLockCandidates prevOwners, + @Nullable CacheLockCandidates owners, + CacheObject val) { + assert !Thread.holdsLock(this); + + if (prevOwners != null && owners == null) { + cctx.mvcc().callback().onOwnerChanged(this, null); + + if (cctx.events().isRecordable(EVT_CACHE_OBJECT_UNLOCKED)) { + boolean hasVal = hasValue(); + + GridCacheMvccCandidate cand = prevOwners.candidate(0); + + cctx.events().addEvent(partition(), + key, + cand.nodeId(), + cand, + EVT_CACHE_OBJECT_UNLOCKED, + val, + hasVal, + val, + hasVal, + null, + null, + null, + true); + } + } + + if (owners != null) { + for (int i = 0; i < owners.size(); i++) { + GridCacheMvccCandidate owner = owners.candidate(i); + + boolean locked = prevOwners == null || !prevOwners.hasCandidate(owner.version()); + + if (locked) { + cctx.mvcc().callback().onOwnerChanged(this, owner); + + if (owner.local()) + checkThreadChain(owner); + + if (cctx.events().isRecordable(EVT_CACHE_OBJECT_LOCKED)) { + boolean hasVal = hasValue(); + + // Event notification. + cctx.events().addEvent(partition(), + key, + owner.nodeId(), + owner, + EVT_CACHE_OBJECT_LOCKED, + val, + hasVal, + val, + hasVal, + null, + null, + null, + true); + } + } + } + } + } + + /** + * @param owner Starting candidate in the chain. + */ + protected abstract void checkThreadChain(GridCacheMvccCandidate owner); + + /** * Updates metrics. * * @param op Operation. http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java index 507a2c9..498584c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvcc.java @@ -107,7 +107,7 @@ public final class GridCacheMvcc { /** * @return Any owner. */ - @Nullable public GridCacheMvccCandidate anyOwner() { + @Nullable GridCacheMvccCandidate anyOwner() { GridCacheMvccCandidate owner = localOwner(); if (owner == null) @@ -117,10 +117,22 @@ public final class GridCacheMvcc { } /** + * @return All owners. + */ + @Nullable public CacheLockCandidates allOwners() { + CacheLockCandidates owners = localOwners(); + + if (owners == null) + owners = remoteOwner(); + + return owners; + } + + /** * @return Remote candidate only if it's first in the list and is marked * as 'used'. */ - @Nullable public GridCacheMvccCandidate remoteOwner() { + @Nullable private GridCacheMvccCandidate remoteOwner() { if (rmts != null) { assert !rmts.isEmpty(); @@ -133,10 +145,58 @@ public final class GridCacheMvcc { } /** + * @return All local owners. + */ + @Nullable public CacheLockCandidates localOwners() { + if (locs != null) { + assert !locs.isEmpty(); + + CacheLockCandidates owners = null; + + GridCacheMvccCandidate first = locs.getFirst(); + + if (first.read()) { + for (GridCacheMvccCandidate cand : locs) { + if (cand.owner()) { + assert cand.read() : this; + + if (owners != null) { + CacheLockCandidatesList list; + + if (owners.size() == 1) { + GridCacheMvccCandidate owner = owners.candidate(0); + + owners = list = new CacheLockCandidatesList(); + + ((CacheLockCandidatesList)owners).add(owner); + } + else + list = ((CacheLockCandidatesList)owners); + + list.add(cand); + } + else + owners = cand; + } + + if (!cand.read()) + break; + } + } + else if (first.owner()) + owners = first; + + return owners; + } + + return null; + } + + /** * @return Local candidate only if it's first in the list and is marked * as 'owner'. */ - @Nullable public GridCacheMvccCandidate localOwner() { + @Nullable GridCacheMvccCandidate localOwner() { if (locs != null) { assert !locs.isEmpty(); @@ -186,6 +246,29 @@ public final class GridCacheMvcc { } /** + * @param cand Existing candidate. + * @param newCand New candidate. + * @return {@code False} if new candidate can not be added. + */ + private boolean compareSerializableVersion(GridCacheMvccCandidate cand, GridCacheMvccCandidate newCand) { + assert cand.serializable() && newCand.serializable(); + + GridCacheVersion candOrder = cand.serializableOrder(); + + assert candOrder != null : cand; + + GridCacheVersion newCandOrder = newCand.serializableOrder(); + + assert newCandOrder != null : newCand; + + int cmp = SER_VER_COMPARATOR.compare(candOrder, newCandOrder); + + assert cmp != 0; + + return cmp < 0; + } + + /** * @param cand Candidate to add. * @return {@code False} if failed to add candidate and transaction should be cancelled. */ @@ -200,25 +283,34 @@ public final class GridCacheMvcc { if (!cand.nearLocal()) { if (!locs.isEmpty()) { if (cand.serializable()) { - GridCacheMvccCandidate last = locs.getLast(); - - if (!last.serializable()) - return false; - - GridCacheVersion lastOrder = last.serializableOrder(); + Iterator it = locs.descendingIterator(); - assert lastOrder != null : last; + if (cand.read()) { + while (it.hasNext()) { + GridCacheMvccCandidate c = it.next(); - GridCacheVersion candOrder = cand.serializableOrder(); + if (!c.serializable()) + return false; - assert candOrder != null : cand; - - int cmp = SER_VER_COMPARATOR.compare(lastOrder, candOrder); + if (!c.read()) { + if (compareSerializableVersion(c, cand)) + break; + else + return false; + } + } + } + else { + while (it.hasNext()) { + GridCacheMvccCandidate c = it.next(); - assert cmp != 0; + if (!c.serializable() || !compareSerializableVersion(c, cand)) + return false; - if (cmp > 0) - return false; + if (!c.read()) + break; + } + } locs.addLast(cand); @@ -284,12 +376,12 @@ public final class GridCacheMvcc { } // Remote. else { - assert !cand.serializable() : cand; + assert !cand.serializable() && !cand.read() : cand; if (rmts == null) rmts = new LinkedList<>(); - assert !cand.owner() || localOwner() == null : "Cannot have local and remote owners " + + assert !cand.owner() || localOwners() == null : "Cannot have local and remote owners " + "at the same time [cand=" + cand + ", locs=" + locs + ", rmts=" + rmts + ']'; GridCacheMvccCandidate cur = candidate(rmts, cand.version()); @@ -398,9 +490,8 @@ public final class GridCacheMvcc { * @param baseVer Base version. * @param committedVers Committed versions relative to base. * @param rolledbackVers Rolled back versions relative to base. - * @return Lock owner. */ - @Nullable public GridCacheMvccCandidate orderCompleted(GridCacheVersion baseVer, + public void orderCompleted(GridCacheVersion baseVer, Collection committedVers, Collection rolledbackVers) { assert baseVer != null; @@ -415,10 +506,13 @@ public final class GridCacheMvcc { if (!cur.version().equals(baseVer) && committedVers.contains(cur.version())) { cur.setOwner(); - assert localOwner() == null || localOwner().nearLocal(): "Cannot not have local owner and " + + assert localOwners() == null || localOwner().nearLocal(): "Cannot not have local owner and " + "remote completed transactions at the same time [baseVer=" + baseVer + - ", committedVers=" + committedVers + ", rolledbackVers=" + rolledbackVers + - ", localOwner=" + localOwner() + ", locs=" + locs + ", rmts=" + rmts + ']'; + ", committedVers=" + committedVers + + ", rolledbackVers=" + rolledbackVers + + ", localOwner=" + localOwner() + + ", locs=" + locs + + ", rmts=" + rmts + ']'; if (maxIdx < 0) maxIdx = it.nextIndex(); @@ -462,8 +556,6 @@ public final class GridCacheMvcc { rmts = null; } } - - return anyOwner(); } /** @@ -471,11 +563,10 @@ public final class GridCacheMvcc { * * @param baseVer Base version. * @param owned Owned list. - * @return Current owner. */ - @Nullable public GridCacheMvccCandidate markOwned(GridCacheVersion baseVer, GridCacheVersion owned) { + public void markOwned(GridCacheVersion baseVer, GridCacheVersion owned) { if (owned == null) - return anyOwner(); + return; if (rmts != null) { GridCacheMvccCandidate baseCand = candidate(rmts, baseVer); @@ -483,8 +574,6 @@ public final class GridCacheMvcc { if (baseCand != null) baseCand.ownerVersion(owned); } - - return anyOwner(); } /** @@ -495,6 +584,7 @@ public final class GridCacheMvcc { * @param reenter Reentry flag ({@code true} if reentry is allowed). * @param tx Transaction flag. * @param implicitSingle Implicit transaction flag. + * @param read Read lock flag. * @return New lock candidate if lock was added, or current owner if lock was reentered, * or null if lock was owned by another thread and timeout is negative. */ @@ -505,7 +595,8 @@ public final class GridCacheMvcc { long timeout, boolean reenter, boolean tx, - boolean implicitSingle) { + boolean implicitSingle, + boolean read) { return addLocal( parent, /*nearNodeId*/null, @@ -517,7 +608,8 @@ public final class GridCacheMvcc { reenter, tx, implicitSingle, - /*dht-local*/false + /*dht-local*/false, + /*read*/read ); } @@ -533,6 +625,7 @@ public final class GridCacheMvcc { * @param tx Transaction flag. * @param implicitSingle Implicit flag. * @param dhtLoc DHT local flag. + * @param read Read lock flag. * @return New lock candidate if lock was added, or current owner if lock was reentered, * or null if lock was owned by another thread and timeout is negative. */ @@ -547,7 +640,8 @@ public final class GridCacheMvcc { boolean reenter, boolean tx, boolean implicitSingle, - boolean dhtLoc) { + boolean dhtLoc, + boolean read) { if (log.isDebugEnabled()) log.debug("Adding local candidate [mvcc=" + this + ", parent=" + parent + ", threadId=" + threadId + ", ver=" + ver + ", timeout=" + timeout + ", reenter=" + reenter + ", tx=" + tx + "]"); @@ -582,14 +676,14 @@ public final class GridCacheMvcc { nearVer, threadId, ver, - timeout, /*local*/true, /*reenter*/false, tx, implicitSingle, /*near-local*/false, dhtLoc, - serOrder + serOrder, + read ); if (serOrder == null) { @@ -613,7 +707,6 @@ public final class GridCacheMvcc { * @param otherNodeId Other node ID. * @param threadId Thread ID. * @param ver Lock version. - * @param timeout Lock acquire timeout. * @param tx Transaction flag. * @param implicitSingle Implicit flag. * @param nearLoc Near local flag. @@ -625,7 +718,6 @@ public final class GridCacheMvcc { @Nullable UUID otherNodeId, long threadId, GridCacheVersion ver, - long timeout, boolean tx, boolean implicitSingle, boolean nearLoc) { @@ -636,14 +728,14 @@ public final class GridCacheMvcc { null, threadId, ver, - timeout, /*local*/false, /*reentry*/false, tx, implicitSingle, nearLoc, false, - null + null, + /*read*/false ); addRemote(cand); @@ -659,9 +751,9 @@ public final class GridCacheMvcc { * @param otherNodeId Other node ID. * @param threadId Thread ID. * @param ver Lock version. - * @param timeout Lock acquire timeout. * @param tx Transaction flag. * @param implicitSingle Implicit flag. + * @param read Read lock flag. * @return Add remote candidate. */ public GridCacheMvccCandidate addNearLocal(GridCacheEntryEx parent, @@ -669,23 +761,23 @@ public final class GridCacheMvcc { @Nullable UUID otherNodeId, long threadId, GridCacheVersion ver, - long timeout, boolean tx, - boolean implicitSingle) { + boolean implicitSingle, + boolean read) { GridCacheMvccCandidate cand = new GridCacheMvccCandidate(parent, nodeId, otherNodeId, null, threadId, ver, - timeout, /*local*/true, /*reentry*/false, tx, implicitSingle, /*near loc*/true, /*dht loc*/false, - null); + null, + /*read*/read); add0(cand); @@ -695,7 +787,7 @@ public final class GridCacheMvcc { /** * @param cand Remote candidate. */ - public void addRemote(GridCacheMvccCandidate cand) { + private void addRemote(GridCacheMvccCandidate cand) { assert !cand.local(); if (log.isDebugEnabled()) @@ -710,11 +802,11 @@ public final class GridCacheMvcc { * @param ver Lock version to acquire or set to ready. * @return Current owner. */ - @Nullable public GridCacheMvccCandidate readyLocal(GridCacheVersion ver) { + @Nullable public CacheLockCandidates readyLocal(GridCacheVersion ver) { GridCacheMvccCandidate cand = candidate(ver); if (cand == null) - return anyOwner(); + return allOwners(); assert cand.local(); @@ -725,14 +817,14 @@ public final class GridCacheMvcc { * @param cand Local candidate added in any of the {@code addLocal(..)} methods. * @return Current lock owner. */ - @Nullable public GridCacheMvccCandidate readyLocal(GridCacheMvccCandidate cand) { + @Nullable public CacheLockCandidates readyLocal(GridCacheMvccCandidate cand) { assert cand.local(); cand.setReady(); reassign(); - return anyOwner(); + return allOwners(); } /** @@ -751,9 +843,12 @@ public final class GridCacheMvcc { * @param pending Pending dht versions that are not owned and which version is less then mapped. * @return Lock owner after reassignment. */ - @Nullable public GridCacheMvccCandidate readyNearLocal(GridCacheVersion ver, GridCacheVersion mappedVer, - Collection committedVers, Collection rolledBackVers, - Collection pending) { + @Nullable public CacheLockCandidates readyNearLocal(GridCacheVersion ver, + GridCacheVersion mappedVer, + Collection committedVers, + Collection rolledBackVers, + Collection pending) + { GridCacheMvccCandidate cand = candidate(locs, ver); if (cand != null) { @@ -785,7 +880,7 @@ public final class GridCacheMvcc { if (c.owner()) continue; - assert !c.ready() : + assert !c.ready() || (c.read() && cand.read()): "Cannot have more then one ready near-local candidate [c=" + c + ", cand=" + cand + ", mvcc=" + this + ']'; @@ -819,7 +914,7 @@ public final class GridCacheMvcc { reassign(); } - return anyOwner(); + return allOwners(); } /** @@ -831,7 +926,7 @@ public final class GridCacheMvcc { * @param rolledback Rolledback versions. * @return Lock owner. */ - @Nullable public GridCacheMvccCandidate doneRemote( + @Nullable public CacheLockCandidates doneRemote( GridCacheVersion ver, Collection pending, Collection committed, @@ -879,7 +974,7 @@ public final class GridCacheMvcc { } } - return anyOwner(); + return allOwners(); } /** @@ -942,19 +1037,39 @@ public final class GridCacheMvcc { if (locs != null) { boolean first = true; - for (ListIterator it = locs.listIterator(); it.hasNext(); ) { + ListIterator it = locs.listIterator(); + + while (it.hasNext()) { GridCacheMvccCandidate cand = it.next(); - if (first && cand.serializable()) { - if (cand.owner() || !cand.ready()) + if (first) { + if (cand.read()) { + if (cand.ready() && !cand.owner()) + cand.setOwner(); + + while (it.hasNext()) { + cand = it.next(); + + if (!cand.read()) + break; + + if (cand.ready() && !cand.owner()) + cand.setOwner(); + } + return; + } + else if (cand.serializable()) { + if (cand.owner() || !cand.ready()) + return; - cand.setOwner(); + cand.setOwner(); - return; - } + return; + } - first = false; + first = false; + } if (cand.owner()) return; @@ -1036,6 +1151,8 @@ public final class GridCacheMvcc { } if (assigned) { + assert !cand.serializable() : cand; + it.remove(); // Owner must be first in the list. @@ -1066,15 +1183,16 @@ public final class GridCacheMvcc { * * @return Owner. */ - @Nullable public GridCacheMvccCandidate recheck() { + @Nullable public CacheLockCandidates recheck() { reassign(); - return anyOwner(); + return allOwners(); } /** * Local local release. - * @return Removed lock candidate or null if candidate was not removed. + * + * @return Removed candidate. */ @Nullable public GridCacheMvccCandidate releaseLocal() { return releaseLocal(Thread.currentThread().getId()); @@ -1084,32 +1202,45 @@ public final class GridCacheMvcc { * Local release. * * @param threadId ID of the thread. - * @return Current owner. + * @return Removed candidate. */ @Nullable public GridCacheMvccCandidate releaseLocal(long threadId) { - GridCacheMvccCandidate owner = localOwner(); + CacheLockCandidates owners = localOwners(); - if (owner == null || owner.threadId() != threadId) - // Release had no effect. - return owner; + // Release had no effect. + if (owners == null) + return null; - owner.setUsed(); + GridCacheMvccCandidate owner = null; - remove0(owner.version(), true); + for (int i = 0; i < owners.size(); i++) { + GridCacheMvccCandidate owner0 = owners.candidate(i); - return anyOwner(); + if (owner0.threadId() == threadId) { + owner = owner0; + + break; + } + } + + if (owner != null) { + owner.setUsed(); + + remove0(owner.version(), true); + + return owner; + } + else + return null; } /** * Removes lock even if it is not owner. * * @param ver Lock version. - * @return Current owner. */ - @Nullable public GridCacheMvccCandidate remove(GridCacheVersion ver) { + public void remove(GridCacheVersion ver) { remove0(ver, false); - - return anyOwner(); } /** @@ -1118,7 +1249,7 @@ public final class GridCacheMvcc { * @param nodeId Node ID. * @return Current owner. */ - @Nullable public GridCacheMvccCandidate removeExplicitNodeCandidates(UUID nodeId) { + @Nullable public CacheLockCandidates removeExplicitNodeCandidates(UUID nodeId) { if (rmts != null) { for (Iterator it = rmts.iterator(); it.hasNext(); ) { GridCacheMvccCandidate cand = it.next(); @@ -1153,7 +1284,7 @@ public final class GridCacheMvcc { reassign(); - return anyOwner(); + return allOwners(); } /** @@ -1177,7 +1308,7 @@ public final class GridCacheMvcc { * @param threadId Thread ID. * @return Candidate or null if there is no candidate for given ID. */ - @Nullable public GridCacheMvccCandidate localCandidate(long threadId) { + @Nullable GridCacheMvccCandidate localCandidate(long threadId) { // Don't return reentries. return localCandidate(threadId, false); } @@ -1187,7 +1318,7 @@ public final class GridCacheMvcc { * @param threadId Thread ID. * @return Remote candidate. */ - @Nullable public GridCacheMvccCandidate remoteCandidate(UUID nodeId, long threadId) { + @Nullable GridCacheMvccCandidate remoteCandidate(UUID nodeId, long threadId) { if (rmts != null) for (GridCacheMvccCandidate c : rmts) if (c.nodeId().equals(nodeId) && c.threadId() == threadId) @@ -1217,7 +1348,7 @@ public final class GridCacheMvcc { * @param ver Version. * @return {@code True} if candidate with given version exists. */ - public boolean hasCandidate(GridCacheVersion ver) { + boolean hasCandidate(GridCacheVersion ver) { return candidate(ver) != null; } @@ -1284,40 +1415,24 @@ public final class GridCacheMvcc { } /** - * @return {@code True} if lock is owner by current thread. - */ - public boolean isLocallyOwnedByCurrentThread() { - return isLocallyOwnedByThread(Thread.currentThread().getId(), true); - } - - /** * @param threadId Thread ID to check. * @param exclude Versions to ignore. * @return {@code True} if lock is owned by the thread with given ID. */ - public boolean isLocallyOwnedByThread(long threadId, boolean allowDhtLoc, GridCacheVersion... exclude) { - GridCacheMvccCandidate owner = localOwner(); - - return owner != null && owner.threadId() == threadId && owner.nodeId().equals(cctx.nodeId()) && - (allowDhtLoc || !owner.dhtLocal()) && !U.containsObjectArray(exclude, owner.version()); - } + boolean isLocallyOwnedByThread(long threadId, boolean allowDhtLoc, GridCacheVersion... exclude) { + CacheLockCandidates owners = localOwners(); - /** - * @param threadId Thread ID. - * @param nodeId Node ID. - * @return {@code True} if lock is held by given thread and node IDs. - */ - public boolean isLockedByThread(long threadId, UUID nodeId) { - GridCacheMvccCandidate owner = anyOwner(); + if (owners != null) { + for (int i = 0; i < owners.size(); i++) { + GridCacheMvccCandidate owner = owners.candidate(i); - return owner != null && owner.threadId() == threadId && owner.nodeId().equals(nodeId); - } + if (owner.threadId() == threadId && owner.nodeId().equals(cctx.nodeId()) && + (allowDhtLoc || !owner.dhtLocal()) && !U.containsObjectArray(exclude, owner.version())) + return true; + } + } - /** - * @return {@code True} if lock is owned by any thread or node. - */ - public boolean isOwnedByAny() { - return anyOwner() != null; + return false; } /** @@ -1325,10 +1440,10 @@ public final class GridCacheMvcc { * @param lockVer ID of lock candidate. * @return {@code True} if candidate is owner. */ - public boolean isLocallyOwned(GridCacheVersion lockVer) { - GridCacheMvccCandidate owner = localOwner(); + boolean isLocallyOwned(GridCacheVersion lockVer) { + CacheLockCandidates owners = localOwners(); - return owner != null && owner.version().equals(lockVer); + return owners != null && owners.hasCandidate(lockVer); } /** @@ -1336,30 +1451,25 @@ public final class GridCacheMvcc { * @param threadId Thread ID. * @return {@code True} if locked by lock ID or thread ID. */ - public boolean isLocallyOwnedByIdOrThread(GridCacheVersion lockVer, long threadId) { - GridCacheMvccCandidate owner = localOwner(); + boolean isLocallyOwnedByIdOrThread(GridCacheVersion lockVer, long threadId) { + CacheLockCandidates owners = localOwners(); - return owner != null && (owner.version().equals(lockVer) || owner.threadId() == threadId); - } + if (owners != null) { + for (int i = 0; i < owners.size(); i++) { + GridCacheMvccCandidate owner = owners.candidate(i); - /** - * @return First remote entry or null. - */ - @Nullable public GridCacheMvccCandidate firstRemote() { - return rmts == null ? null : rmts.getFirst(); - } + if ((owner.version().equals(lockVer) || owner.threadId() == threadId)) + return true; + } + } - /** - * @return First local entry or null. - */ - @Nullable public GridCacheMvccCandidate firstLocal() { - return locs == null ? null : locs.getFirst(); + return false; } /** * @return Local MVCC candidates. */ - @Nullable public List allLocal() { + @Nullable List allLocal() { return locs; } @@ -1367,10 +1477,10 @@ public final class GridCacheMvcc { * @param ver Version to check for ownership. * @return {@code True} if lock is owned by the specified version. */ - public boolean isOwnedBy(GridCacheVersion ver) { - GridCacheMvccCandidate cand = anyOwner(); + boolean isOwnedBy(GridCacheVersion ver) { + CacheLockCandidates owners = allOwners(); - return cand != null && cand.version().equals(ver); + return owners != null && owners.hasCandidate(ver); } /** {@inheritDoc} */ http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCallback.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCallback.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCallback.java index fc1faf7..2ba41f7 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCallback.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCallback.java @@ -37,11 +37,9 @@ public interface GridCacheMvccCallback { * can be made from this call. * * @param entry Entry. - * @param prev Previous candidate. * @param owner Current owner. */ - public void onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate prev, - GridCacheMvccCandidate owner); + public void onOwnerChanged(GridCacheEntryEx entry, GridCacheMvccCandidate owner); /** * Called when entry has no more candidates. This call happens http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java index f1c1b83..e9dd455 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccCandidate.java @@ -43,6 +43,7 @@ import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.LOCAL; import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.NEAR_LOCAL; import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.OWNER; +import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.READ; import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.READY; import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.REENTRY; import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate.Mask.REMOVED; @@ -54,7 +55,7 @@ import static org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate * Lock candidate. */ public class GridCacheMvccCandidate implements Externalizable, - Comparable { + Comparable, CacheLockCandidates { /** */ private static final long serialVersionUID = 0L; @@ -69,14 +70,6 @@ public class GridCacheMvccCandidate implements Externalizable, @GridToStringInclude private GridCacheVersion ver; - /** Maximum wait time. */ - @GridToStringInclude - private long timeout; - - /** Candidate timestamp. */ - @GridToStringInclude - private long ts; - /** Thread ID. */ @GridToStringInclude private long threadId; @@ -143,7 +136,6 @@ public class GridCacheMvccCandidate implements Externalizable, * @param otherVer Other version. * @param threadId Requesting thread ID. * @param ver Cache version. - * @param timeout Maximum wait time. * @param loc {@code True} if the lock is local. * @param reentry {@code True} if candidate is for reentry. * @param tx Transaction flag. @@ -151,6 +143,7 @@ public class GridCacheMvccCandidate implements Externalizable, * @param nearLoc Near-local flag. * @param dhtLoc DHT local flag. * @param serOrder Version for serializable transactions ordering. + * @param read Read lock flag. */ public GridCacheMvccCandidate( GridCacheEntryEx parent, @@ -159,14 +152,14 @@ public class GridCacheMvccCandidate implements Externalizable, @Nullable GridCacheVersion otherVer, long threadId, GridCacheVersion ver, - long timeout, boolean loc, boolean reentry, boolean tx, boolean singleImplicit, boolean nearLoc, boolean dhtLoc, - @Nullable GridCacheVersion serOrder + @Nullable GridCacheVersion serOrder, + boolean read ) { assert nodeId != null; assert ver != null; @@ -178,7 +171,6 @@ public class GridCacheMvccCandidate implements Externalizable, this.otherVer = otherVer; this.threadId = threadId; this.ver = ver; - this.timeout = timeout; this.serOrder = serOrder; mask(LOCAL, loc); @@ -187,8 +179,7 @@ public class GridCacheMvccCandidate implements Externalizable, mask(SINGLE_IMPLICIT, singleImplicit); mask(NEAR_LOCAL, nearLoc); mask(DHT_LOCAL, dhtLoc); - - ts = U.currentTimeMillis(); + mask(READ, read); id = IDGEN.incrementAndGet(); } @@ -245,14 +236,14 @@ public class GridCacheMvccCandidate implements Externalizable, otherVer, threadId, ver, - timeout, local(), /*reentry*/true, tx(), singleImplicit(), nearLocal(), dhtLocal(), - serializableOrder()); + serializableOrder(), + read()); reentry.topVer = topVer; @@ -411,20 +402,6 @@ public class GridCacheMvccCandidate implements Externalizable, } /** - * @return Maximum wait time. - */ - public long timeout() { - return timeout; - } - - /** - * @return Timestamp at the time of entering pending set. - */ - public long timestamp() { - return ts; - } - - /** * @return {@code True} if lock is local. */ public boolean local() { @@ -474,6 +451,13 @@ public class GridCacheMvccCandidate implements Externalizable, } /** + * @return Read lock flag. + */ + public boolean read() { + return READ.get(flags()); + } + + /** * @return {@code True} if this candidate is a reentry. */ public boolean reentry() { @@ -586,16 +570,21 @@ public class GridCacheMvccCandidate implements Externalizable, return parent0.txKey(); } - /** - * Checks if this candidate matches version or thread-nodeId combination. - * - * @param nodeId Node ID to check. - * @param ver Version to check. - * @param threadId Thread ID to check. - * @return {@code True} if matched. - */ - public boolean matches(GridCacheVersion ver, UUID nodeId, long threadId) { - return ver.equals(this.ver) || (nodeId.equals(this.nodeId) && threadId == this.threadId); + /** {@inheritDoc} */ + @Override public GridCacheMvccCandidate candidate(int idx) { + assert idx == 0 : idx; + + return this; + } + + /** {@inheritDoc} */ + @Override public int size() { + return 1; + } + + /** {@inheritDoc} */ + @Override public boolean hasCandidate(GridCacheVersion ver) { + return this.ver.equals(ver); } /** {@inheritDoc} */ @@ -610,7 +599,6 @@ public class GridCacheMvccCandidate implements Externalizable, ver.writeExternal(out); } - out.writeLong(timeout); out.writeLong(threadId); out.writeLong(id); out.writeShort(flags()); @@ -626,7 +614,6 @@ public class GridCacheMvccCandidate implements Externalizable, ver.readExternal(in); } - timeout = in.readLong(); threadId = in.readLong(); id = in.readLong(); @@ -635,8 +622,6 @@ public class GridCacheMvccCandidate implements Externalizable, mask(OWNER, OWNER.get(flags)); mask(USED, USED.get(flags)); mask(TX, TX.get(flags)); - - ts = U.currentTimeMillis(); } /** {@inheritDoc} */ @@ -719,7 +704,10 @@ public class GridCacheMvccCandidate implements Externalizable, NEAR_LOCAL(0x200), /** */ - REMOVED(0x400); + REMOVED(0x400), + + /** */ + READ(0x800); /** All mask values. */ private static final Mask[] MASKS = values(); http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java index c57e17c..0d0e9ee 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/GridCacheMvccManager.java @@ -140,15 +140,14 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter { private final GridCacheMvccCallback cb = new GridCacheMvccCallback() { /** {@inheritDoc} */ @SuppressWarnings({"unchecked"}) - @Override public void onOwnerChanged(final GridCacheEntryEx entry, final GridCacheMvccCandidate prev, - final GridCacheMvccCandidate owner) { + @Override public void onOwnerChanged(final GridCacheEntryEx entry, final GridCacheMvccCandidate owner) { int nested = nestedLsnrCalls.get(); if (nested < MAX_NESTED_LSNR_CALLS) { nestedLsnrCalls.set(nested + 1); try { - notifyOwnerChanged(entry, prev, owner); + notifyOwnerChanged(entry, owner); } finally { nestedLsnrCalls.set(nested); @@ -157,7 +156,7 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter { else { cctx.kernalContext().closure().runLocalSafe(new GridPlainRunnable() { @Override public void run() { - notifyOwnerChanged(entry, prev, owner); + notifyOwnerChanged(entry, owner); } }, true); } @@ -182,19 +181,13 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter { /** * @param entry Entry to notify callback for. - * @param prev Previous lock owner. * @param owner Current lock owner. */ - private void notifyOwnerChanged(final GridCacheEntryEx entry, final GridCacheMvccCandidate prev, - final GridCacheMvccCandidate owner) { + private void notifyOwnerChanged(final GridCacheEntryEx entry, final GridCacheMvccCandidate owner) { assert entry != null; - assert owner != prev : "New and previous owner are identical instances: " + owner; - assert owner == null || prev == null || !owner.version().equals(prev.version()) : - "New and previous owners have identical versions [owner=" + owner + ", prev=" + prev + ']'; if (log.isDebugEnabled()) - log.debug("Received owner changed callback [" + entry.key() + ", owner=" + owner + ", prev=" + - prev + ']'); + log.debug("Received owner changed callback [" + entry.key() + ", owner=" + owner + ']'); if (owner != null && (owner.local() || owner.nearLocal())) { Collection> futCol = mvccFuts.get(owner.version()); @@ -226,7 +219,7 @@ public class GridCacheMvccManager extends GridCacheSharedManagerAdapter { if (log.isDebugEnabled()) log.debug("Lock future not found for owner change callback (will try transaction futures) [owner=" + - owner + ", prev=" + prev + ", entry=" + entry + ']'); + owner + ", entry=" + entry + ']'); // If no future was found, delegate to transaction manager. if (cctx.tm().onOwnerChanged(entry, owner)) { http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java index 2d1b02e..3d55f31 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/GridDistributedCacheEntry.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.List; import java.util.UUID; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheLockCandidates; import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; @@ -66,7 +67,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { /** * */ - protected void refreshRemotes() { + private void refreshRemotes() { GridCacheMvcc mvcc = mvccExtras(); rmts = mvcc == null ? Collections.emptyList() : mvcc.remoteCandidates(); @@ -82,6 +83,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * @param reenter Reentry flag. * @param tx Transaction flag. * @param implicitSingle Implicit flag. + * @param read Read lock flag. * @return New candidate. * @throws GridCacheEntryRemovedException If entry has been removed. */ @@ -92,10 +94,11 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { long timeout, boolean reenter, boolean tx, - boolean implicitSingle) throws GridCacheEntryRemovedException { + boolean implicitSingle, + boolean read) throws GridCacheEntryRemovedException { GridCacheMvccCandidate cand; - GridCacheMvccCandidate prev; - GridCacheMvccCandidate owner; + CacheLockCandidates prev; + CacheLockCandidates owner; CacheObject val; @@ -110,16 +113,23 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { mvccExtras(mvcc); } - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); - cand = mvcc.addLocal(this, threadId, ver, timeout, reenter, tx, implicitSingle); + cand = mvcc.addLocal(this, + threadId, + ver, + timeout, + reenter, + tx, + implicitSingle, + read); if (cand != null) cand.topologyVersion(topVer); - owner = mvcc.anyOwner(); + owner = mvcc.allOwners(); boolean emptyAfter = mvcc.isEmpty(); @@ -168,7 +178,6 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * @param otherNodeId Other node ID. * @param threadId Thread ID. * @param ver Lock version. - * @param timeout Lock acquire timeout. * @param tx Transaction flag. * @param implicitSingle Implicit flag. * @param owned Owned candidate version. @@ -180,13 +189,12 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { @Nullable UUID otherNodeId, long threadId, GridCacheVersion ver, - long timeout, boolean tx, boolean implicitSingle, @Nullable GridCacheVersion owned ) throws GridDistributedLockCancelledException, GridCacheEntryRemovedException { - GridCacheMvccCandidate prev; - GridCacheMvccCandidate owner; + CacheLockCandidates prev; + CacheLockCandidates owner; CacheObject val; @@ -204,7 +212,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { mvccExtras(mvcc); } - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); @@ -214,7 +222,6 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { otherNodeId, threadId, ver, - timeout, tx, implicitSingle, /*near-local*/false @@ -223,62 +230,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { if (owned != null) mvcc.markOwned(ver, owned); - owner = mvcc.anyOwner(); - - boolean emptyAfter = mvcc.isEmpty(); - - checkCallbacks(emptyBefore, emptyAfter); - - val = this.val; - - refreshRemotes(); - - if (emptyAfter) - mvccExtras(null); - } - - // This call must be outside of synchronization. - checkOwnerChanged(prev, owner, val); - } - - /** - * Adds new lock candidate. - * - * @param cand Remote lock candidate. - * @throws GridDistributedLockCancelledException If lock has been canceled. - * @throws GridCacheEntryRemovedException If this entry is obsolete. - */ - public void addRemote(GridCacheMvccCandidate cand) throws GridDistributedLockCancelledException, - GridCacheEntryRemovedException { - - CacheObject val; - - GridCacheMvccCandidate prev; - GridCacheMvccCandidate owner; - - synchronized (this) { - cand.parent(this); - - // Check removed locks prior to obsolete flag. - checkRemoved(cand.version()); - - checkObsolete(); - - GridCacheMvcc mvcc = mvccExtras(); - - if (mvcc == null) { - mvcc = new GridCacheMvcc(cctx); - - mvccExtras(mvcc); - } - - boolean emptyBefore = mvcc.isEmpty(); - - prev = mvcc.anyOwner(); - - mvcc.addRemote(cand); - - owner = mvcc.anyOwner(); + owner = mvcc.allOwners(); boolean emptyAfter = mvcc.isEmpty(); @@ -303,8 +255,8 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * @throws GridCacheEntryRemovedException If entry was removed. */ public void removeExplicitNodeLocks(UUID nodeId) throws GridCacheEntryRemovedException { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; CacheObject val = null; @@ -314,7 +266,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { GridCacheMvcc mvcc = mvccExtras(); if (mvcc != null) { - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); @@ -346,8 +298,9 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * @return Removed candidate, or null if thread still holds the lock. */ @Nullable public GridCacheMvccCandidate removeLock() { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + GridCacheMvccCandidate rmvd = null; + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; CacheObject val; @@ -355,11 +308,11 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { GridCacheMvcc mvcc = mvccExtras(); if (mvcc != null) { - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); - owner = mvcc.releaseLocal(); + rmvd = mvcc.releaseLocal(); boolean emptyAfter = mvcc.isEmpty(); @@ -367,28 +320,38 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { if (emptyAfter) mvccExtras(null); + else + owner = mvcc.allOwners(); } val = this.val; } - if (log.isDebugEnabled()) - log.debug("Released local candidate from entry [owner=" + owner + ", prev=" + prev + + if (log.isDebugEnabled()) { + log.debug("Released local candidate from entry [owner=" + owner + + ", prev=" + prev + + ", rmvd=" + rmvd + ", entry=" + this + ']'); + } + + if (prev != null) { + for (int i = 0; i < prev.size(); i++) { + GridCacheMvccCandidate cand = prev.candidate(i); - if (prev != null && owner != prev) - checkThreadChain(prev); + checkThreadChain(cand); + } + } // This call must be outside of synchronization. checkOwnerChanged(prev, owner, val); - return owner != prev ? prev : null; + return rmvd; } /** {@inheritDoc} */ @Override public boolean removeLock(GridCacheVersion ver) throws GridCacheEntryRemovedException { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; GridCacheMvccCandidate doomed; @@ -408,13 +371,11 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { checkObsolete(); if (doomed != null) { - assert mvcc != null; - - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); - owner = mvcc.remove(doomed.version()); + mvcc.remove(doomed.version()); boolean emptyAfter = mvcc.isEmpty(); @@ -425,6 +386,8 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { if (emptyAfter) mvccExtras(null); + else + owner = mvcc.allOwners(); } val = this.val; @@ -477,10 +440,10 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * @return Owner. * @throws GridCacheEntryRemovedException If entry is removed. */ - @Nullable public GridCacheMvccCandidate readyLock(GridCacheVersion ver) + @Nullable public CacheLockCandidates readyLock(GridCacheVersion ver) throws GridCacheEntryRemovedException { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; CacheObject val; @@ -490,13 +453,13 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { GridCacheMvcc mvcc = mvccExtras(); if (mvcc != null) { - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); owner = mvcc.readyLocal(ver); - assert owner == null || owner.owner() : "Owner flag not set for owner: " + owner; + assert owner == null || owner.candidate(0).owner() : "Owner flag not set for owner: " + owner; boolean emptyAfter = mvcc.isEmpty(); @@ -523,16 +486,16 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * @param committed Committed versions. * @param rolledBack Rolled back versions. * @param pending Pending locks on dht node with version less then mapped. - * @return Current lock owner. * * @throws GridCacheEntryRemovedException If entry is removed. */ - @Nullable public GridCacheMvccCandidate readyNearLock(GridCacheVersion ver, GridCacheVersion mapped, + public void readyNearLock(GridCacheVersion ver, GridCacheVersion mapped, Collection committed, Collection rolledBack, - Collection pending) throws GridCacheEntryRemovedException { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + Collection pending) throws GridCacheEntryRemovedException + { + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; CacheObject val; @@ -542,13 +505,13 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { GridCacheMvcc mvcc = mvccExtras(); if (mvcc != null) { - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); owner = mvcc.readyNearLocal(ver, mapped, committed, rolledBack, pending); - assert owner == null || owner.owner() : "Owner flag is not set for owner: " + owner; + assert owner == null || owner.candidate(0).owner() : "Owner flag is not set for owner: " + owner; boolean emptyAfter = mvcc.isEmpty(); @@ -563,75 +526,6 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { // This call must be made outside of synchronization. checkOwnerChanged(prev, owner, val); - - return owner; - } - - /** - * Reorders completed versions. - * - * @param baseVer Base version for reordering. - * @param committedVers Completed versions. - * @param rolledbackVers Rolled back versions. - * @throws GridCacheEntryRemovedException If entry has been removed. - */ - public void orderCompleted(GridCacheVersion baseVer, Collection committedVers, - Collection rolledbackVers) - throws GridCacheEntryRemovedException { - if (!F.isEmpty(committedVers) || !F.isEmpty(rolledbackVers)) { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; - - CacheObject val; - - synchronized (this) { - checkObsolete(); - - GridCacheMvcc mvcc = mvccExtras(); - - if (mvcc != null) { - prev = mvcc.anyOwner(); - - boolean emptyBefore = mvcc.isEmpty(); - - owner = mvcc.orderCompleted(baseVer, committedVers, rolledbackVers); - - boolean emptyAfter = mvcc.isEmpty(); - - checkCallbacks(emptyBefore, emptyAfter); - - if (emptyAfter) - mvccExtras(null); - } - - val = this.val; - } - - // This call must be made outside of synchronization. - checkOwnerChanged(prev, owner, val); - } - } - - /** - * - * @param lockVer Done version. - * @param baseVer Base version. - * @param committedVers Completed versions for reordering. - * @param rolledbackVers Rolled back versions for reordering. - * @param sysInvalidate Flag indicating if this entry is done from invalidated transaction (in case of tx - * salvage). In this case all locks before salvaged lock will marked as used and corresponding - * transactions will be invalidated. - * @throws GridCacheEntryRemovedException If entry has been removed. - * @return Owner. - */ - @Nullable public GridCacheMvccCandidate doneRemote( - GridCacheVersion lockVer, - GridCacheVersion baseVer, - Collection committedVers, - Collection rolledbackVers, - boolean sysInvalidate) throws GridCacheEntryRemovedException { - return doneRemote(lockVer, baseVer, Collections.emptySet(), committedVers, - rolledbackVers, sysInvalidate); } /** @@ -645,17 +539,16 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { * salvage). In this case all locks before salvaged lock will marked as used and corresponding * transactions will be invalidated. * @throws GridCacheEntryRemovedException If entry has been removed. - * @return Owner. */ - @Nullable public GridCacheMvccCandidate doneRemote( + public void doneRemote( GridCacheVersion lockVer, GridCacheVersion baseVer, @Nullable Collection pendingVers, Collection committedVers, Collection rolledbackVers, boolean sysInvalidate) throws GridCacheEntryRemovedException { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; CacheObject val; @@ -665,7 +558,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { GridCacheMvcc mvcc = mvccExtras(); if (mvcc != null) { - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); @@ -680,7 +573,9 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { if (sysInvalidate && baseVer != null) mvcc.salvageRemote(baseVer); - owner = mvcc.doneRemote(lockVer, maskNull(pendingVers), maskNull(committedVers), + owner = mvcc.doneRemote(lockVer, + maskNull(pendingVers), + maskNull(committedVers), maskNull(rolledbackVers)); boolean emptyAfter = mvcc.isEmpty(); @@ -696,18 +591,14 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { // This call must be made outside of synchronization. checkOwnerChanged(prev, owner, val); - - return owner; } /** * Rechecks if lock should be reassigned. - * - * @return Current owner. */ - @Nullable public GridCacheMvccCandidate recheck() { - GridCacheMvccCandidate prev = null; - GridCacheMvccCandidate owner = null; + public void recheck() { + CacheLockCandidates prev = null; + CacheLockCandidates owner = null; CacheObject val; @@ -715,7 +606,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { GridCacheMvcc mvcc = mvccExtras(); if (mvcc != null) { - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); @@ -734,8 +625,6 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { // This call must be made outside of synchronization. checkOwnerChanged(prev, owner, val); - - return owner; } /** {@inheritDoc} */ @@ -743,7 +632,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { long timeout, @Nullable GridCacheVersion serOrder, GridCacheVersion serReadVer, - boolean keepBinary + boolean read ) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException { if (tx.local()) // Null is returned if timeout is negative and there is other lock owner. @@ -754,7 +643,8 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { timeout, /*reenter*/false, /*tx*/true, - tx.implicitSingle()) != null; + tx.implicitSingle(), + read) != null; try { addRemote( @@ -762,7 +652,6 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { tx.otherNodeId(), tx.threadId(), tx.xidVersion(), - tx.timeout(), /*tx*/true, tx.implicitSingle(), tx.ownedVersion(txKey()) @@ -779,7 +668,7 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { } /** {@inheritDoc} */ - @Override public void txUnlock(IgniteInternalTx tx) throws GridCacheEntryRemovedException { + @Override public final void txUnlock(IgniteInternalTx tx) throws GridCacheEntryRemovedException { removeLock(tx.xidVersion()); } @@ -799,42 +688,8 @@ public class GridDistributedCacheEntry extends GridCacheMapEntry { } } - /** - * @param prev Previous owner. - * @param owner Current owner. - * @param val Entry value. - */ - protected void checkOwnerChanged(GridCacheMvccCandidate prev, GridCacheMvccCandidate owner, CacheObject val) { - assert !Thread.holdsLock(this); - - if (owner != prev) { - cctx.mvcc().callback().onOwnerChanged(this, prev, owner); - - if (owner != null && owner.local()) - checkThreadChain(owner); - - if (prev != null && cctx.events().isRecordable(EVT_CACHE_OBJECT_UNLOCKED)) { - boolean hasVal = hasValue(); - - // Event notification. - cctx.events().addEvent(partition(), key, prev.nodeId(), prev, EVT_CACHE_OBJECT_UNLOCKED, val, hasVal, - val, hasVal, null, null, null, true); - } - - if (owner != null && cctx.events().isRecordable(EVT_CACHE_OBJECT_LOCKED)) { - boolean hasVal = hasValue(); - - // Event notification. - cctx.events().addEvent(partition(), key, owner.nodeId(), owner, EVT_CACHE_OBJECT_LOCKED, val, hasVal, - val, hasVal, null, null, null, true); - } - } - } - - /** - * @param owner Starting candidate in the chain. - */ - protected void checkThreadChain(GridCacheMvccCandidate owner) { + /** {@inheritDoc} */ + @Override final protected void checkThreadChain(GridCacheMvccCandidate owner) { assert !Thread.holdsLock(this); assert owner != null; http://git-wip-us.apache.org/repos/asf/ignite/blob/33dda460/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java index b0b0a7e..cf4085b 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/distributed/dht/GridDhtCacheEntry.java @@ -27,6 +27,7 @@ import org.apache.ignite.IgniteCheckedException; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.internal.IgniteInternalFuture; import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion; +import org.apache.ignite.internal.processors.cache.CacheLockCandidates; import org.apache.ignite.internal.processors.cache.CacheObject; import org.apache.ignite.internal.processors.cache.GridCacheContext; import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException; @@ -135,7 +136,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { * @return Local candidate by near version. * @throws GridCacheEntryRemovedException If removed. */ - @Nullable public synchronized GridCacheMvccCandidate localCandidateByNearVersion(GridCacheVersion nearVer, + @Nullable synchronized GridCacheMvccCandidate localCandidateByNearVersion(GridCacheVersion nearVer, boolean rmv) throws GridCacheEntryRemovedException { checkObsolete(); @@ -165,34 +166,33 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { * @param threadId Owning thread ID. * @param ver Lock version. * @param serOrder Version for serializable transactions ordering. - * @param serReadVer Optional read entry version for optimistic serializable transaction. * @param timeout Timeout to acquire lock. * @param reenter Reentry flag. * @param tx Tx flag. * @param implicitSingle Implicit flag. + * @param read Read lock flag. * @return New candidate. * @throws GridCacheEntryRemovedException If entry has been removed. * @throws GridDistributedLockCancelledException If lock was cancelled. */ - @Nullable public GridCacheMvccCandidate addDhtLocal( + @Nullable GridCacheMvccCandidate addDhtLocal( UUID nearNodeId, GridCacheVersion nearVer, AffinityTopologyVersion topVer, long threadId, GridCacheVersion ver, @Nullable GridCacheVersion serOrder, - @Nullable GridCacheVersion serReadVer, long timeout, boolean reenter, boolean tx, - boolean implicitSingle) + boolean implicitSingle, + boolean read) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException { - assert serReadVer == null || serOrder != null; assert !reenter || serOrder == null; GridCacheMvccCandidate cand; - GridCacheMvccCandidate prev; - GridCacheMvccCandidate owner; + CacheLockCandidates prev; + CacheLockCandidates owner; CacheObject val; @@ -211,7 +211,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { mvccExtras(mvcc); } - prev = mvcc.anyOwner(); + prev = mvcc.allOwners(); boolean emptyBefore = mvcc.isEmpty(); @@ -226,7 +226,8 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { reenter, tx, implicitSingle, - /*dht-local*/true + /*dht-local*/true, + read ); if (cand == null) @@ -234,10 +235,10 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { cand.topologyVersion(topVer); - owner = mvcc.anyOwner(); + owner = mvcc.allOwners(); if (owner != null) - cand.ownerVersion(owner.version()); + cand.ownerVersion(owner.candidate(0).version()); boolean emptyAfter = mvcc.isEmpty(); @@ -264,7 +265,7 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { long timeout, @Nullable GridCacheVersion serOrder, GridCacheVersion serReadVer, - boolean keepBinary + boolean read ) throws GridCacheEntryRemovedException, GridDistributedLockCancelledException { if (tx.local()) { GridDhtTxLocalAdapter dhtTx = (GridDhtTxLocalAdapter)tx; @@ -277,11 +278,11 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { tx.threadId(), tx.xidVersion(), serOrder, - serReadVer, timeout, /*reenter*/false, /*tx*/true, - tx.implicitSingle()) != null; + tx.implicitSingle(), + read) != null; } try { @@ -290,7 +291,6 @@ public class GridDhtCacheEntry extends GridDistributedCacheEntry { tx.otherNodeId(), tx.threadId(), tx.xidVersion(), - tx.timeout(), /*tx*/true, tx.implicit(), null);