package org.corfudb.runtime.collections;
import lombok.Getter;
import org.corfudb.annotations.Accessor;
import org.corfudb.annotations.CorfuObject;
import org.corfudb.annotations.MutatorAccessor;
import org.corfudb.runtime.view.AbstractViewTest;
import org.junit.Test;
import java.util.HashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Created by mwei on 4/7/16.
*/
public class PutIfAbsentMapTest extends AbstractViewTest {
@Getter
final String defaultConfigurationString = getDefaultEndpoint();
@Test
public void putIfAbsentTest() {
getDefaultRuntime();
PutIfAbsentMap<String, String> stringMap = getRuntime().getObjectsView().build()
.setStreamName("stringMap")
.setType(PutIfAbsentMap.class)
.open();
stringMap.put("a", "b");
assertThat(stringMap.get("a"))
.isEqualTo("b");
assertThat(stringMap.putIfAbsent("a", "c"))
.isFalse();
assertThat(stringMap.get("a"))
.isEqualTo("b");
}
@Test
public void putIfAbsentTestConcurrent()
throws Exception {
getDefaultRuntime();
PutIfAbsentMap<String, String> stringMap = getRuntime().getObjectsView().build()
.setStreamName("stringMap")
.setType(PutIfAbsentMap.class)
.open();
ConcurrentLinkedQueue<Boolean> resultList = new ConcurrentLinkedQueue<>();
scheduleConcurrently(PARAMETERS.NUM_ITERATIONS_LOW, x -> {
resultList.add(stringMap.putIfAbsent("a", Integer.toString(x)));
});
executeScheduled(PARAMETERS.CONCURRENCY_SOME, PARAMETERS.TIMEOUT_LONG);
long trueCount = resultList.stream()
.filter(x -> x)
.count();
assertThat(trueCount)
.isEqualTo(1);
}
@CorfuObject
public static class PutIfAbsentMap<K, V> {
HashMap<K, V> map = new HashMap<>();
@MutatorAccessor(name="put")
public V put(K key, V value) {
return map.put(key, value);
}
@Accessor
public V get(K key) {
return map.get(key);
}
@MutatorAccessor(name="putIfAbsent")
public boolean putIfAbsent(K key, V value) {
if (map.get(key) == null) {
map.put(key, value);
return true;
}
return false;
}
}
}