/* * Copyright 2016 higherfrequencytrading.com * * Licensed 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 net.openhft.chronicle.engine; import net.openhft.chronicle.bytes.Bytes; import net.openhft.chronicle.core.io.Closeable; import net.openhft.chronicle.engine.api.map.MapView; import net.openhft.chronicle.engine.api.tree.AssetTree; import net.openhft.chronicle.engine.map.MapClientTest.RemoteMapSupplier; import net.openhft.chronicle.engine.tree.VanillaAssetTree; import net.openhft.chronicle.wire.WireType; import org.jetbrains.annotations.NotNull; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestName; import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentMap; import java.util.stream.IntStream; import static net.openhft.chronicle.engine.Utils.methodName; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; public class RemoteTcpClientTest extends ThreadMonitoringTest { @NotNull @Rule public TestName name = new TestName(); @NotNull private AssetTree assetTree = new VanillaAssetTree().forTesting(); @Before public void before() { methodName(name.getMethodName()); } @Test(timeout = 100000) @Ignore("performance test") public void testLargeStringTextWire() throws IOException { final int MB = 1 << 20; testStrings(50, 2 * MB, WireType.TEXT); } @Test(timeout = 100000) @Ignore("performance test") public void testLargeStringBinaryWire() throws IOException { final int MB = 1 << 20; testStrings(50, 2 * MB, WireType.BINARY); } private void testStrings(int noPutsAndGets, int valueLength, @NotNull WireType wireType) throws IOException { try (@NotNull final RemoteMapSupplier<CharSequence, CharSequence> remote = new RemoteMapSupplier<>("testStrings.host.port", CharSequence.class, CharSequence.class, wireType, assetTree, "test")) { @NotNull ConcurrentMap test = remote.get(); @NotNull Bytes bytes = Bytes.allocateElasticDirect(valueLength); while (bytes.readPosition() < valueLength) bytes.append('x'); // warm up for (int j = -1; j < 30; j++) { long start1 = System.currentTimeMillis(); // TODO adding .parallel() should work. IntStream.range(0, noPutsAndGets).parallel().forEach(i -> { // IntStream.range(0, noPutsAndGets).forEach(i -> { test.put("key" + i, bytes); if (i % 10 == 5) System.out.println("put key" + i); }); long duration1 = System.currentTimeMillis() - start1; /* if (j >= 0)*/ { System.out.printf("Took %.3f seconds to perform %,d puts%n", duration1 / 1e3, noPutsAndGets); // Assert.assertTrue("This should take 1 second but took " + duration1 / 1e3 + " seconds. ", duration1 < 1000); } /* long start2 = System.currentTimeMillis(); // IntStream.range(0, noPutsAndGets).parallel().forEach(i -> { IntStream.range(0, noPutsAndGets).forEach(i -> { test.getUsing("key" + i, Wires.acquireStringBuilder()); if (i % 10 == 5) System.out.println("get key" + i); }); long duration2 = System.currentTimeMillis() - start2; if (j >= 0) { System.out.printf("Took %.3f seconds to perform %,d puts%n", duration2 / 1e3, noPutsAndGets); Assert.assertTrue("This should take 1 second but took " + duration2 / 1e3 + " seconds. ", duration2 < 1000); }*/ } } } @Test @Ignore("Takes 407s (~0.2s/iteration) so best to only run it on demand") public void test2MBEntries() throws IOException { // server try (@NotNull final RemoteMapSupplier<String, String> remote = new RemoteMapSupplier<>("test2MBEntries.host.port", String.class, String.class, WireType.BINARY, assetTree, "test")) { @NotNull StringBuilder sb = new StringBuilder(); for (int i = 0; i < 50_000; i++) { sb.append('x'); } @NotNull String value = sb.toString(); long time = System.currentTimeMillis(); @NotNull final ConcurrentMap<String, String> map = remote.get(); for (int i = 0; i < 2_000; i++) { System.out.println(i); map.put("largeEntry", value); } System.out.format("Time for 100MB %,dms%n", (System.currentTimeMillis() - time)); } } @Test @Ignore("Will be very slow, of course") public void testLargeUpdates() throws IOException, InterruptedException { @NotNull char[] chars = new char[1024 * 1024]; Arrays.fill(chars, 'X'); @NotNull String value = new String(chars); try (@NotNull final RemoteMapSupplier<String, String> remote = new RemoteMapSupplier<>("testLargeUpdates.host.port", String.class, String.class, WireType.BINARY, assetTree, "test")) { @NotNull List<Closeable> closeables = new ArrayList<>(); @NotNull List<Map<String, String>> maps = new ArrayList<>(); @NotNull final ConcurrentMap<String, String> map = remote.get(); maps.add(map); for (int i = 1; i < Runtime.getRuntime().availableProcessors(); i++) { @NotNull AssetTree assetTree2 = new VanillaAssetTree().forRemoteAccess("testLargeUpdates.host.port", WireType.BINARY); @NotNull Map<String, String> map2 = assetTree2.acquireMap("test", String.class, String.class); maps.add(map2); closeables.add(assetTree2); } final long time = System.currentTimeMillis(); for (int j = 0; j <= 30 * 1000; j += maps.size() * 100) { System.out.println(j); maps.parallelStream().forEach(m -> IntStream.range(0, 100).forEach(i -> m.put("key" + i, value))); } System.out.format("Time for 100MB %,dms%n", (System.currentTimeMillis() - time)); closeables.forEach(Closeable::close); } } @Test @Ignore("Works stand a lone but not when running all tests in IDEA") public void testValuesCollection() throws IOException { // server try (@NotNull final RemoteMapSupplier<String, String> remote = new RemoteMapSupplier<>("testValuesCollection.host.port", String.class, String.class, WireType.BINARY, assetTree, "test")) { @NotNull final MapView<String, String> map = remote.get(); @NotNull Map<String, String> data = new HashMap<String, String>(); data.put("test1", "value1"); data.put("test2", "value2"); map.putAll(data); Utils.waitFor(() -> data.size() == map.size()); assertEquals(data.size(), map.size()); assertEquals(data.size(), map.values().size()); @NotNull Iterator<String> it = map.values().iterator(); @NotNull ArrayList<String> values = new ArrayList<String>(); while (it.hasNext()) { values.add(it.next()); } Collections.sort(values); @NotNull Object[] dataValues = data.values().toArray(); Arrays.sort(dataValues); assertArrayEquals(dataValues, values.toArray()); /* MapView<String, ?, String> map = acquireMap("my-map", String.class, String.class); Set<String> set =... Map<String, String> subset = map.applyTo(m -> { Map<String, String> ret = new HashMap<String, String>(); for (String key : set) { ret.put(key, m.get(key)); } return ret; });*/ } } }