Skip to content

Commit

Permalink
Merge pull request #997 from aol/mapTests
Browse files Browse the repository at this point in the history
More unit tests for Maps
  • Loading branch information
johnmcclean authored Dec 16, 2018
2 parents 054c22e + 7d81aca commit 4af579b
Show file tree
Hide file tree
Showing 16 changed files with 280 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

import java.util.Iterator;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.Supplier;


public interface PersistentMap<K,V> extends Iterable<Tuple2<K,V>> {

PersistentMap<K,V> put(K key, V value);
Expand Down Expand Up @@ -37,20 +39,22 @@ default ReactiveSeq<Tuple2<K,V>> stream(){
return ReactiveSeq.fromIterable(this);
}

default boolean allMatch(Predicate<? super Tuple2<K,V>> c){
return !stream().filterNot(c)
.findFirst()
.isPresent();
}
default boolean equalTo(PersistentMap<K,V> map){
if(size()!=map.size())
return false;
Iterator<Tuple2<K,V>> iterator = iterator();
while(iterator.hasNext()){
Tuple2<K, V> t2 = iterator.next();
if(!Objects.equals(map.getOrElse(t2._1(),null),t2._2())){
return false;
}

}
return true;
return allMatch(map::contains);

}


default boolean contains(Tuple2<K, V> t) {
return get(t._1()).filter(v-> Objects.equals(v,t._2())).isPresent();
}
default MapView<K,V> mapView(){
return new MapView.Impl<>(this);
}
Expand Down
2 changes: 1 addition & 1 deletion cyclops/src/main/java/cyclops/control/LazyEither.java
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ public ReactiveSeq<PT> stream() {

@Override
public Maybe<PT> filter(final Predicate<? super PT> test) {
return Maybe.fromIterable(this).filter(test);
return Maybe.fromPublisher(this).filter(test);

}

Expand Down
12 changes: 5 additions & 7 deletions cyclops/src/main/java/cyclops/data/HashMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.oath.cyclops.types.persistent.PersistentMap;
import com.oath.cyclops.hkt.Higher2;
import cyclops.companion.Comparators;
import cyclops.control.Option;
import cyclops.control.Trampoline;
import cyclops.function.Function3;
Expand Down Expand Up @@ -156,7 +157,7 @@ public HashMap<K, V> remove(K key) {
public HashMap<K, V> removeAll(K... keys) {
HAMT.Node<K,V> cur = map;
for(K key : keys){
cur = map.minus(0,key.hashCode(),key);
cur = cur.minus(0,key.hashCode(),key);
}
return new HashMap<>(cur);
}
Expand Down Expand Up @@ -210,7 +211,7 @@ public HashMap<K, V> putAll(PersistentMap<? extends K, ? extends V> map) {
public HashMap<K, V> removeAllKeys(Iterable<? extends K> keys) {
HashMap<K,V> res = this;
for(K e : keys){
res = this.remove(e);
res = res.remove(e);
}
return res;
}
Expand All @@ -230,10 +231,7 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null)
return false;
if(o instanceof HashMap){
HashMap<?, ?> hashMap = (HashMap<?, ?>) o;
return Objects.equals(map, hashMap.map);
}

if(o instanceof PersistentMap){
PersistentMap<K,V> m = (PersistentMap<K,V>)o;
return equalTo(m);
Expand All @@ -244,7 +242,7 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(map);
return map.streamNaturalOrder().foldLeft(0,(acc,t2)-> acc+t2.hashCode());
}

public static <K, V> HashMap<K,V> narrow(HashMap<? extends K, ? extends V> map) {
Expand Down
6 changes: 5 additions & 1 deletion cyclops/src/main/java/cyclops/data/ImmutableMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public interface ImmutableMap<K,V> extends Iterable<Tuple2<K,V>>,
OnEmptySwitch<Tuple2<K, V>,ImmutableMap<K, V>> {


@Override
default boolean allMatch(final Predicate<? super Tuple2<K, V>> c) {
return Folds.super.allMatch(c);
}

ImmutableMap<K,V> put(K key, V value);
ImmutableMap<K,V> put(Tuple2<K, V> keyAndValue);
Expand Down Expand Up @@ -180,7 +184,7 @@ default ImmutableMap<K,V> notNull(){

@Override
default ImmutableMap<K,V> peek(Consumer<? super V> c) {
return (HashMap<K,V>)Transformable.super.peek(c);
return (ImmutableMap<K,V>)Transformable.super.peek(c);
}


Expand Down
9 changes: 6 additions & 3 deletions cyclops/src/main/java/cyclops/data/TreeMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public TreeMap<K, V> remove(K key) {
public TreeMap<K, V> removeAll(K... keys) {
RedBlackTree.Tree<K,V> cur = map;
for(K key : keys){
cur = map.minus(key);
cur = cur.minus(key);
}
return new TreeMap<>(cur, comparator);
}
Expand Down Expand Up @@ -327,10 +327,13 @@ public boolean equals(Object o) {
return equalTo(m);
}
return false;

}

@Override


@Override
public int hashCode() {
return Objects.hash(map);
return map.stream().foldLeft(0,(acc,t2)-> acc+t2.hashCode());
}
}
4 changes: 2 additions & 2 deletions cyclops/src/main/java/cyclops/data/TrieMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public TrieMap<K, V> remove(K key) {
public TrieMap<K, V> removeAll(K[] keys) {
HashedPatriciaTrie.Node<K,V> cur = map;
for(K key : keys){
cur = map.minus(key.hashCode(),key);
cur = cur.minus(key.hashCode(),key);
}
return new TrieMap<>(cur);
}
Expand Down Expand Up @@ -196,6 +196,6 @@ public boolean equals(Object o) {

@Override
public int hashCode() {
return Objects.hash(map);
return map.streamNaturalOrder().foldLeft(0,(acc,t2)-> acc+t2.hashCode());
}
}
8 changes: 8 additions & 0 deletions cyclops/src/main/java/cyclops/data/base/HAMT.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import com.oath.cyclops.matching.Deconstruct.Deconstruct2;
import cyclops.companion.Comparators;
import cyclops.control.Option;
import cyclops.data.ImmutableList;
import cyclops.data.LazySeq;
Expand Down Expand Up @@ -70,6 +71,9 @@ default Node<K, V> minus(K key) {
LazySeq<Tuple2<K, V>> lazyList();

ReactiveSeq<Tuple2<K, V>> stream();
default ReactiveSeq<Tuple2<K, V>> streamNaturalOrder(){
return stream();
}
}


Expand Down Expand Up @@ -286,6 +290,10 @@ public Node<K, V> minus(int bitShiftDepth, int hash, K key) {
}
return this;
}
@Override
public ReactiveSeq<Tuple2<K, V>> streamNaturalOrder() {
return stream().sorted(Comparators.naturalOrderIdentityComparator());
}

@Override
public int size() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.oath.cyclops.matching.Deconstruct.Deconstruct1;
import com.oath.cyclops.matching.Deconstruct.Deconstruct2;
import com.oath.cyclops.matching.Sealed4;
import cyclops.companion.Comparators;
import cyclops.control.Option;

import cyclops.data.LazySeq;
Expand Down Expand Up @@ -55,6 +56,9 @@ interface Node<K, V> extends Sealed4<EmptyNode<K,V>,SingleNode<K,V>,CollisionNod

Node<K, V> minus(int hash, K key);
ReactiveSeq<Tuple2<K,V>> stream();
default ReactiveSeq<Tuple2<K, V>> streamNaturalOrder(){
return stream();
}

}

Expand Down Expand Up @@ -308,6 +312,10 @@ public <R> R fold(Function<? super EmptyNode<K, V>, ? extends R> fn1, Function<?
public Tuple1<LazySeq<Tuple2<K, V>>> unapply() {
return Tuple.tuple(bucket);
}
@Override
public ReactiveSeq<Tuple2<K, V>> streamNaturalOrder() {
return stream().sorted(Comparators.naturalOrderIdentityComparator());
}
}

static final class ArrayNode<K, V> implements Node<K, V>, Deconstruct1<Node<K,V>[]> {
Expand Down
1 change: 1 addition & 0 deletions cyclops/src/main/java/cyclops/data/base/RedBlackTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ else if (compRes==0)

@Override
public Tree<K, V> plus(K key, V value) {

int compRes = comp.compare(this.key,key);
if (compRes>0) {
return balance(isBlack, left.plus(key, value), right, this.key, this.value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public static enum Error {
@Test
public void testFailure() throws MalformedURLException {

for(int i=0;i<10000;i++) {
for(int i=0;i<100;i++) {
System.out.println("*********** " + i);
URLDataFileMetadata failingURL = new URLDataFileMetadata(10l, "url", new URL("http://oath23232.com"));

Expand Down Expand Up @@ -87,7 +87,8 @@ public void testSleepingFilterSwap() throws MalformedURLException {
SleepingURLDataFileMetadata slowUrl = new SleepingURLDataFileMetadata(10l, "url", new URL("https://www.rte.ie/"));

long start = System.currentTimeMillis();
Option<Error> x = proc.processUsersFiles(user, NonEmptyList.of(slowUrl)).swap().filter(i -> true);
Option<Error> x = proc.processUsersFiles(user, NonEmptyList.of(slowUrl))
.swap().filter(i -> true);

System.out.println(System.currentTimeMillis() + " Blocked? ");
System.out.println(System.currentTimeMillis() + " No... ");
Expand Down
50 changes: 41 additions & 9 deletions cyclops/src/test/java/cyclops/data/HashMapTest.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package cyclops.data;

import com.oath.cyclops.types.persistent.PersistentMap;
import cyclops.control.Option;
import cyclops.data.tuple.Tuple2;
import lombok.AllArgsConstructor;
import lombok.ToString;
import org.hamcrest.MatcherAssert;
import org.junit.Test;


import java.util.ArrayList;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.*;

public class HashMapTest {

Expand All @@ -18,34 +22,58 @@ public void plusSize(){
}

@Test
public void add10000(){
public void stream(){

//19742
long start = System.currentTimeMillis();
}


@Test
public void read100_000_00(){

//6247
HashMap<Integer,Integer> v = HashMap.empty();

for(int i=0;i<100_000_00;i++){
v =v.put(i,i);
}
ArrayList<Integer> al = new ArrayList(v.size());
long start = System.currentTimeMillis();
for(int i=0;i<100_000_00;i++){
Integer next = v.getOrElse(i,null);
assertNotNull(next);
al.add(next);
}

System.out.println(System.currentTimeMillis()-start);
System.out.println(v.size());
assertThat(v.size(),equalTo(100_000_00));
assertThat(al.size(),equalTo(100_000_00));
}
@Test
public void read100_000_00(){
public void read100_000_00Stream(){

//6247
HashMap<Integer,Integer> v = HashMap.empty();

for(int i=0;i<100_000_00;i++){
v =v.put(i,i);
}
for(int i =0;i<100_000_00;i=i+2){
v=v.remove(i);
}
for(int i=0;i<100_000_00;i++){
v =v.put(i,i);
}
ArrayList<Integer> al = new ArrayList(v.size());
long start = System.currentTimeMillis();
for(int i=0;i<100_000_00;i++){
al.add(v.getOrElse(i,null));
for(Integer i : v.stream().map(Tuple2::_1)){
Integer next = v.getOrElse(i,null);
assertNotNull(next);
al.add(next);
}

System.out.println(System.currentTimeMillis()-start);
System.out.println(v.size());
assertThat(v.size(),equalTo(100_000_00));
assertThat(al.size(),equalTo(100_000_00));
}
@Test
public void read100_000_00PC(){
Expand Down Expand Up @@ -81,4 +109,8 @@ public void add10000PCol(){
public void removeMissingKey(){
MatcherAssert.assertThat(HashMap.of(1,"a",2,"b").removeAll(0),equalTo(HashMap.of(1,"a",2,"b")));
}



}

Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ protected ImmutableMap<String, Integer> fromMap(Map<String, Integer> map) {
HashMap<String, Integer> x = HashMap.fromStream(s);
return x;
}
}
}
14 changes: 14 additions & 0 deletions cyclops/src/test/java/cyclops/data/ImmutableTreeMapTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.stream.Stream;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;


Expand Down Expand Up @@ -48,4 +49,17 @@ public void add50000Entries(){
putAndCompare(map);
}

@Test
public void insertionOrder() {
ImmutableMap<Integer, Integer> map1 = empty();
ImmutableMap<Integer, Integer> map2 = empty();
for (int i = 0; i <= 1000; i++) {
map1 = map1.put(i, i);
map2 = map2.put(1000 - i, 1000 - i);
}
assertEquals(map1,map2);
assertEquals(map1.hashCode(), map2.hashCode());

}

}
Loading

0 comments on commit 4af579b

Please sign in to comment.