package org.corfudb.runtime.collections; import com.google.common.reflect.TypeToken; import lombok.Getter; import org.corfudb.runtime.exceptions.TransactionAbortedException; import org.corfudb.runtime.view.AbstractViewTest; import org.junit.Test; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import static org.assertj.core.api.Assertions.assertThat; /** * Created by mwei on 3/29/16. */ public class FGMapTest extends AbstractViewTest { @Getter final String defaultConfigurationString = getDefaultEndpoint(); @Test @SuppressWarnings("unchecked") public void canReadWriteToSingle() throws Exception { Map<String, String> testMap = getDefaultRuntime() .getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); testMap.clear(); assertThat(testMap.put("a", "a")) .isNull(); assertThat(testMap.put("a", "b")) .isEqualTo("a"); assertThat(testMap.get("a")) .isEqualTo("b"); } /* @Test @SuppressWarnings("unchecked") public void createOnlyThrowsException() throws Exception { Map<String,String> testMap = getDefaultRuntime().getObjectsView().build() .setType(FGMap.class) .setStreamName("map") .addOption(ObjectOpenOptions.CREATE_ONLY) .open(); assertThatThrownBy(() -> getDefaultRuntime().getObjectsView().build() .setType(FGMap.class) .setStreamName("map") .addOption(ObjectOpenOptions.CREATE_ONLY) .open()) .isInstanceOf(ObjectExistsException.class); } */ @Test @SuppressWarnings("unchecked") public void sizeIsCorrect() throws Exception { Map<String, String> testMap = getDefaultRuntime() .getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); testMap.clear(); assertThat(testMap) .isEmpty(); for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) { testMap.put(Integer.toString(i), Integer.toString(i)); } assertThat(testMap) .hasSize(PARAMETERS.NUM_ITERATIONS_LOW); } @Test @SuppressWarnings("unchecked") public void canNestTX() throws Exception { Map<String, String> testMap = getDefaultRuntime() .getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); testMap.clear(); assertThat(testMap) .isEmpty(); for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) { testMap.put(Integer.toString(i), Integer.toString(i)); } getRuntime().getObjectsView().TXBegin(); int size = testMap.size(); testMap.put("size", Integer.toString(size)); getRuntime().getObjectsView().TXEnd(); assertThat(testMap.size()) .isEqualTo(PARAMETERS.NUM_ITERATIONS_LOW + 1); assertThat(testMap.get("size")) .isEqualTo(Integer.toString(PARAMETERS.NUM_ITERATIONS_LOW)); } @Test @SuppressWarnings("unchecked") public void canClear() throws Exception { Map<String, String> testMap = getDefaultRuntime() .getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); testMap.clear(); assertThat(testMap) .isEmpty(); for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) { testMap.put(Integer.toString(i), Integer.toString(i)); } assertThat(testMap) .hasSize(PARAMETERS.NUM_ITERATIONS_LOW); testMap.put("a", "b"); testMap.clear(); assertThat(testMap) .isEmpty(); } @Test @SuppressWarnings("unchecked") public void canClearInTX() throws Exception { getDefaultRuntime(); Map<String, String> testMap = getRuntime().getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); testMap.clear(); assertThat(testMap) .isEmpty(); getRuntime().getObjectsView().TXBegin(); for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) { testMap.put(Integer.toString(i), Integer.toString(i)); } testMap.clear(); assertThat(testMap) .isEmpty(); // .hasSize(0); getRuntime().getObjectsView().TXEnd(); assertThat(testMap) .hasSize(0); } /* Test disabled until constructor persistence is enabled for compiled objects. */ /* @Test public void canVaryBucketCount() throws Exception { <<<<<<< HEAD FGMap<String, String> testMap = getDefaultRuntime().getObjectsView() .build() .setArguments(101) .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); ======= FGMap<String, String> testMap = getDefaultRuntime().getObjectsView().open("hello", FGMap.class, PARAMETERS.NUM_ITERATIONS_LOW + 1); >>>>>>> master testMap.clear(); assertThat(testMap) .isEmpty(); for (int i = 0; i < PARAMETERS.NUM_ITERATIONS_LOW; i++) { testMap.put(Integer.toString(i), Integer.toString(i)); } FGMap<String, String> testMap2 = getRuntime().getObjectsView() .build() .addOption(ObjectOpenOptions.NO_CACHE) .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); assertThat(testMap2) .hasSize(PARAMETERS.NUM_ITERATIONS_LOW); assertThat(testMap2.getNumBuckets()) .isEqualTo(PARAMETERS.NUM_ITERATIONS_LOW + 1); } */ @Test @SuppressWarnings("unchecked") public void loadsFollowedByGetsConcurrent() throws Exception { getDefaultRuntime(); Map<String, String> testMap = getRuntime().getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); final int num_threads = PARAMETERS.CONCURRENCY_SOME; final int num_records = PARAMETERS.NUM_ITERATIONS_LOW; testMap.clear(); scheduleConcurrently(num_threads, threadNumber -> { int base = threadNumber * num_records; for (int i = base; i < base + num_records; i++) { assertThat(testMap.put(Integer.toString(i), Integer.toString(i))) .isEqualTo(null); } }); long startTime = System.currentTimeMillis(); executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG); calculateRequestsPerSecond("WPS", num_records * num_threads, startTime); scheduleConcurrently(num_threads, threadNumber -> { int base = threadNumber * num_records; for (int i = base; i < base + num_records; i++) { assertThat(testMap.get(Integer.toString(i))) .isEqualTo(Integer.toString(i)); } }); startTime = System.currentTimeMillis(); executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG); calculateRequestsPerSecond("RPS", num_records * num_threads, startTime); } @Test @SuppressWarnings("unchecked") public void abortRateIsLowForSimpleTX() throws Exception { getDefaultRuntime(); Map<String, String> testMap = getRuntime().getObjectsView() .build() .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); final int num_threads = PARAMETERS.CONCURRENCY_SOME; final int num_records = PARAMETERS.NUM_ITERATIONS_LOW; AtomicInteger aborts = new AtomicInteger(); testMap.clear(); scheduleConcurrently(num_threads, threadNumber -> { int base = threadNumber * num_records; for (int i = base; i < base + num_records; i++) { try { getRuntime().getObjectsView().TXBegin(); assertThat(testMap.put(Integer.toString(i), Integer.toString(i))) .isEqualTo(null); getRuntime().getObjectsView().TXEnd(); } catch (TransactionAbortedException tae) { aborts.incrementAndGet(); } } }); long startTime = System.currentTimeMillis(); executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG); calculateRequestsPerSecond("TPS", num_records * num_threads, startTime); calculateAbortRate(aborts.get(), num_records * num_threads); } @Test @SuppressWarnings("unchecked") public void checkClearCalls() throws Exception { getDefaultRuntime(); final int NUM_BUCKETS = 20; Map<String, String> testMap = getRuntime().getObjectsView() .build() .setArguments(NUM_BUCKETS) .setStreamName("test") .setTypeToken(new TypeToken<FGMap<String, String>>() {}) .open(); final int num_threads = PARAMETERS.CONCURRENCY_SOME; final int num_records = PARAMETERS.NUM_ITERATIONS_LOW; scheduleConcurrently(num_threads, threadNumber -> { int base = threadNumber * num_records; for (int i = base; i < base + num_records; i++) { testMap.clear(); assertThat(testMap) .isEmpty(); } }); long startTime = System.currentTimeMillis(); executeScheduled(num_threads, PARAMETERS.TIMEOUT_LONG); calculateRequestsPerSecond("OPS", num_records * num_threads, startTime); } }