/* * 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.ArrayList; import java.util.Collection; import java.util.Random; import org.apache.ignite.Ignite; import org.apache.ignite.cache.affinity.Affinity; import org.apache.ignite.cache.affinity.AffinityFunction; import org.apache.ignite.cache.affinity.rendezvous.RendezvousAffinityFunction; import org.apache.ignite.cluster.ClusterNode; import org.apache.ignite.configuration.CacheConfiguration; import org.apache.ignite.configuration.IgniteConfiguration; import org.apache.ignite.internal.util.GridTimer; import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; import org.apache.ignite.spi.discovery.tcp.ipfinder.TcpDiscoveryIpFinder; import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest; import static org.apache.ignite.cache.CacheMode.PARTITIONED; import static org.apache.ignite.cache.CacheRebalanceMode.NONE; /** * Partitioned affinity test. */ @SuppressWarnings({"PointlessArithmeticExpression"}) public class GridCachePartitionedAffinityExcludeNeighborsPerformanceTest extends GridCommonAbstractTest { /** Grid count. */ private static final int GRIDS = 3; /** Random number generator. */ private static final Random RAND = new Random(); /** */ private boolean excNeighbores; /** */ private TcpDiscoveryIpFinder ipFinder = new TcpDiscoveryVmIpFinder(true); /** */ private static Collection<String> msgs = new ArrayList<>(); /** {@inheritDoc} */ @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception { IgniteConfiguration c = super.getConfiguration(igniteInstanceName); TcpDiscoverySpi spi = new TcpDiscoverySpi(); spi.setIpFinder(ipFinder); c.setDiscoverySpi(spi); CacheConfiguration cc = defaultCacheConfiguration(); cc.setCacheMode(PARTITIONED); cc.setBackups(2); AffinityFunction aff = new RendezvousAffinityFunction(excNeighbores); cc.setAffinity(aff); cc.setRebalanceMode(NONE); c.setCacheConfiguration(cc); return c; } /** {@inheritDoc} */ @Override protected void beforeTest() throws Exception { msgs.clear(); } /** * @param ignite Grid. * @return Affinity. */ static Affinity<Object> affinity(Ignite ignite) { return ignite.affinity(DEFAULT_CACHE_NAME); } /** * @param aff Affinity. * @param key Key. * @return Nodes. */ private static Collection<? extends ClusterNode> nodes(Affinity<Object> aff, Object key) { return aff.mapKeyToPrimaryAndBackups(key); } /** * @throws Exception If failed. */ public void testCountPerformance() throws Exception { excNeighbores = false; int cnt = 1000000; long t1 = checkCountPerformance(cnt, "includeNeighbors"); System.gc(); excNeighbores = true; long t2 = checkCountPerformance(cnt, "excludeNeighbors"); for (String msg : msgs) info(msg); info(">>> t2/t1: " + (t2/t1)); } /** * @param cnt Count. * @param testName Test name. * @return Duration. * @throws Exception If failed. */ private long checkCountPerformance(int cnt, String testName) throws Exception { startGridsMultiThreaded(GRIDS); try { Ignite g = grid(0); // Warmup. checkCountPerformance0(g, 10000); info(">>> Starting count based test [testName=" + testName + ", cnt=" + cnt + ']'); long dur = checkCountPerformance0(g, cnt); String msg = ">>> Performance [testName=" + testName + ", cnt=" + cnt + ", duration=" + dur + "ms]"; info(">>> "); info(msg); info(">>> "); msgs.add(msg); return dur; } finally { stopAllGrids(); } } /** * * @param g Grid. * @param cnt Count. * @return Result. * @throws Exception If failed. */ private long checkCountPerformance0(Ignite g, int cnt) throws Exception { Affinity<Object> aff = affinity(g); GridTimer timer = new GridTimer("test"); for (int i = 0; i < cnt; i++) { Object key = RAND.nextInt(Integer.MAX_VALUE); Collection<? extends ClusterNode> affNodes = nodes(aff, key); assert excNeighbores ? affNodes.size() == 1 : affNodes.size() == GRIDS; } timer.stop(); return timer.duration(); } /** * @throws Exception If failed. */ public void testTimedPerformance() throws Exception { excNeighbores = false; long dur = 15000; int cnt1 = checkTimedPerformance(dur, "includeNeighbors"); System.gc(); excNeighbores = true; int cnt2 = checkTimedPerformance(dur, "excludeNeighbors"); for (String msg : msgs) info(msg); info(">>> cnt1/cnt2=" + (cnt1/cnt2)); } /** * @param dur Duration. * @param testName Test name. * @return Number of operations. * @throws Exception If failed. */ private int checkTimedPerformance(long dur, String testName) throws Exception { startGridsMultiThreaded(GRIDS); try { Ignite g = grid(0); Affinity<Object> aff = affinity(g); // Warmup. checkCountPerformance0(g, 10000); info(">>> Starting timed based test [testName=" + testName + ", duration=" + dur + ']'); int cnt = 0; for (long t = System.currentTimeMillis(); cnt % 1000 != 0 || System.currentTimeMillis() - t < dur;) { Object key = RAND.nextInt(Integer.MAX_VALUE); Collection<? extends ClusterNode> affNodes = nodes(aff, key); assert excNeighbores ? affNodes.size() == 1 : affNodes.size() == GRIDS; cnt++; } String msg = ">>> Performance [testName=" + testName + ", duration=" + dur + "ms, cnt=" + cnt + ']'; info(">>> "); info(msg); info(">>> "); msgs.add(msg); return cnt; } finally { stopAllGrids(); } } }