<commit_before>/*
 * 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.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
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.GridCacheEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
import org.apache.ignite.internal.processors.cache.GridCacheMvcc;
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheOperation;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.database.CacheDataRow;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteBiTuple;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;

/**
 * Near cache entry.
 */
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "TooBroadScope"})
public class GridNearCacheEntry extends GridDistributedCacheEntry {
    /** */
    private static final int NEAR_SIZE_OVERHEAD = 36 + 16;

    /** Topology version at the moment when value was initialized from primary node. */
    private volatile AffinityTopologyVersion topVer = AffinityTopologyVersion.NONE;

    /** DHT version which caused the last update. */
    @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
    private GridCacheVersion dhtVer;

    /** Partition. */
    private int part;

    /** */
    private short evictReservations;

    /**
     * @param ctx Cache context.
     * @param key Cache key.
     * @param hash Key hash value.
     * @param val Entry value.
     */
    public GridNearCacheEntry(
        GridCacheContext ctx,
        KeyCacheObject key,
        int hash,
        CacheObject val
    ) {
        super(ctx, key, hash, val);

        part = ctx.affinity().partition(key);
    }

    /** {@inheritDoc} */
    @Override public int memorySize() throws IgniteCheckedException {
        return super.memorySize() + NEAR_SIZE_OVERHEAD;
    }

    /** {@inheritDoc} */
    @Override public int partition() {
        return part;
    }

    /** {@inheritDoc} */
    @Override public boolean isNear() {
        return true;
    }

    /** {@inheritDoc} */
    @Override public boolean valid(AffinityTopologyVersion topVer) {
        assert topVer.topologyVersion() > 0 : "Topology version is invalid: " + topVer;

        AffinityTopologyVersion topVer0 = this.topVer;

        if (topVer0.equals(topVer))
            return true;

        if (topVer0.equals(AffinityTopologyVersion.NONE) || topVer.compareTo(topVer0) < 0)
            return false;

        try {
            if (cctx.affinity().primaryChanged(partition(), topVer0, topVer)) {
                this.topVer = AffinityTopologyVersion.NONE;

                return false;
            }

            if (cctx.affinity().backupByPartition(cctx.localNode(), part, topVer)) {
                this.topVer = AffinityTopologyVersion.NONE;

                return false;
            }

            this.topVer = topVer;

            return true;
        }
        catch (IllegalStateException ignore) {
            // Do not have affinity history.
            this.topVer = AffinityTopologyVersion.NONE;

            return false;
        }
    }

    /**
     * @param topVer Topology version.
     * @throws GridCacheEntryRemovedException If this entry is obsolete.
     */
    public void initializeFromDht(AffinityTopologyVersion topVer) throws GridCacheEntryRemovedException {
        GridDhtCacheEntry entry = cctx.near().dht().peekExx(key);

        if (entry != null) {
            GridCacheEntryInfo e = entry.info();

            if (e != null) {
                GridCacheVersion enqueueVer = null;

                try {
                    synchronized (this) {
                        checkObsolete();

                        if (isNew() || !valid(topVer)) {
                            // Version does not change for load ops.
                            update(e.value(), e.expireTime(), e.ttl(), e.isNew() ? ver : e.version(), true);

                            if (cctx.deferredDelete() && !isNew() && !isInternal()) {
                                boolean deleted = val == null;

                                if (deleted != deletedUnlocked()) {
                                    deletedUnlocked(deleted);

                                    if (deleted)
                                        enqueueVer = e.version();
                                }
                            }

                            ClusterNode primaryNode = cctx.affinity().primaryByKey(key, topVer);

                            if (primaryNode == null)
                                this.topVer = AffinityTopologyVersion.NONE;
                            else
                                recordNodeId(primaryNode.id(), topVer);

                            dhtVer = e.isNew() || e.isDeleted() ? null : e.version();
                        }
                    }
                }
                finally {
                    if (enqueueVer != null)
                        cctx.onDeferredDelete(this, enqueueVer);<commit_msg>ignite-2.0 - Do not call primaryByKey() in cache entry synchronized block - Fixes #1824<commit_after>/*
 * 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.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.cluster.ClusterNode;
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.GridCacheEntryInfo;
import org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException;
import org.apache.ignite.internal.processors.cache.GridCacheMvcc;
import org.apache.ignite.internal.processors.cache.GridCacheMvccCandidate;
import org.apache.ignite.internal.processors.cache.GridCacheOperation;
import org.apache.ignite.internal.processors.cache.KeyCacheObject;
import org.apache.ignite.internal.processors.cache.database.CacheDataRow;
import org.apache.ignite.internal.processors.cache.distributed.GridDistributedCacheEntry;
import org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtCacheEntry;
import org.apache.ignite.internal.processors.cache.transactions.IgniteInternalTx;
import org.apache.ignite.internal.processors.cache.version.GridCacheVersion;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.lang.IgniteBiTuple;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.events.EventType.EVT_CACHE_OBJECT_READ;

/**
 * Near cache entry.
 */
@SuppressWarnings({"NonPrivateFieldAccessedInSynchronizedContext", "TooBroadScope"})
public class GridNearCacheEntry extends GridDistributedCacheEntry {
    /** */
    private static final int NEAR_SIZE_OVERHEAD = 36 + 16;

    /** Topology version at the moment when value was initialized from primary node. */
    private volatile AffinityTopologyVersion topVer = AffinityTopologyVersion.NONE;

    /** DHT version which caused the last update. */
    @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
    private GridCacheVersion dhtVer;

    /** Partition. */
    private int part;

    /** */
    private short evictReservations;

    /**
     * @param ctx Cache context.
     * @param key Cache key.
     * @param hash Key hash value.
     * @param val Entry value.
     */
    public GridNearCacheEntry(
        GridCacheContext ctx,
        KeyCacheObject key,
        int hash,
        CacheObject val
    ) {
        super(ctx, key, hash, val);

        part = ctx.affinity().partition(key);
    }

    /** {@inheritDoc} */
    @Override public int memorySize() throws IgniteCheckedException {
        return super.memorySize() + NEAR_SIZE_OVERHEAD;
    }

    /** {@inheritDoc} */
    @Override public int partition() {
        return part;
    }

    /** {@inheritDoc} */
    @Override public boolean isNear() {
        return true;
    }

    /** {@inheritDoc} */
    @Override public boolean valid(AffinityTopologyVersion topVer) {
        assert topVer.topologyVersion() > 0 : "Topology version is invalid: " + topVer;

        AffinityTopologyVersion topVer0 = this.topVer;

        if (topVer0.equals(topVer))
            return true;

        if (topVer0.equals(AffinityTopologyVersion.NONE) || topVer.compareTo(topVer0) < 0)
            return false;

        try {
            if (cctx.affinity().primaryChanged(partition(), topVer0, topVer)) {
                this.topVer = AffinityTopologyVersion.NONE;

                return false;
            }

            if (cctx.affinity().backupByPartition(cctx.localNode(), part, topVer)) {
                this.topVer = AffinityTopologyVersion.NONE;

                return false;
            }

            this.topVer = topVer;

            return true;
        }
        catch (IllegalStateException ignore) {
            // Do not have affinity history.
            this.topVer = AffinityTopologyVersion.NONE;

            return false;
        }
    }

    /**
     * @param topVer Topology version.
     * @throws GridCacheEntryRemovedException If this entry is obsolete.
     */
    public void initializeFromDht(AffinityTopologyVersion topVer) throws GridCacheEntryRemovedException {
        GridDhtCacheEntry entry = cctx.near().dht().peekExx(key);

        if (entry != null) {
            GridCacheEntryInfo e = entry.info();

            if (e != null) {
                GridCacheVersion enqueueVer = null;

                try {
                    ClusterNode primaryNode = cctx.affinity().primaryByKey(key, topVer);

                    synchronized (this) {
                        checkObsolete();

                        if (isNew() || !valid(topVer)) {
                            // Version does not change for load ops.
                            update(e.value(), e.expireTime(), e.ttl(), e.isNew() ? ver : e.version(), true);

                            if (cctx.deferredDelete() && !isNew() && !isInternal()) {
                                boolean deleted = val == null;

                                if (deleted != deletedUnlocked()) {
                                    deletedUnlocked(deleted);

                                    if (deleted)
                                        enqueueVer = e.version();
                                }
                            }

                            if (primaryNode == null)
                                this.topVer = AffinityTopologyVersion.NONE;
                            else
                                recordNodeId(primaryNode.id(), topVer);

                            dhtVer = e.isNew() || e.isDeleted() ? null : e.version();
                        }
                    }
                }
                finally {
                    if (enqueueVer != null)
                        cctx.onDeferredDelete(this, enqueueVer);
{'fraction_non_alphanumeric': 0.0935891780620497, 'fraction_numerical': 0.002646669607410675, 'mean_word_length': 2.2621103117505994, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6993365', 'n_tokens_mistral': 3663, 'n_tokens_neox': 3513, 'n_words': 856}