package water.fvec;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import water.*;
import water.fvec.Vec;
import static water.fvec.Vec.makeConSeq;
import static water.fvec.Vec.makeSeq;
import java.util.ArrayList;
import java.util.Arrays;
/** This test tests stability of Vec API. */
public class VecTest extends TestUtil {
final int CHUNK_SZ = 1 << H2O.LOG_CHK;
/** Test toEnum call to return correct domain. */
@Test public void testToEnum() {
testToEnumDomainMatch(vec(0,1,0,1), ar("0", "1") );
testToEnumDomainMatch(vec(1,2,3,4,5,6,7), ar("1", "2", "3", "4", "5", "6", "7") );
testToEnumDomainMatch(vec(-1,0,1,2,3,4,5,6), ar("-1", "0", "1", "2", "3", "4", "5", "6") );
}
private void testToEnumDomainMatch(Vec f, String[] expectedDomain) {
Vec ef = null;
try {
ef = f.toEnum();
String[] actualDomain = ef.domain();
assertArrayEquals("toEnum call returns wrong domain!", expectedDomain, actualDomain);
} finally {
if (f!=null) UKV.remove(f._key);
if (ef!=null) UKV.remove(ef._key);
}
}
// want this to be test but avoid serialization of outer class (due to use of anonymous mr2s)
private static final void testChangeDomainImpl(){
ArrayList<Key> madeKeys = new ArrayList<Key>();
try {
final String [] oldDomain = {"a", "b", "c"};
Vec v = Vec.makeNewCons(1000, 1, 0, new String[][]{oldDomain})[0];
madeKeys.add(v._key);
Vec.Writer vw = v.open();
for (long i = 0; i < v.length(); ++i)
vw.set(i, i % 3);
vw.close();
// now rebalance to ensure multiple chunks (and distribution to multiple nodes)
Key reblancedKey = Key.make("reblanced");
madeKeys.add(reblancedKey);
RebalanceDataSet rbd = new RebalanceDataSet(new Frame(v), reblancedKey, 100);
H2O.submitTask(rbd);
rbd.join();
Frame rebalancedFrame = DKV.get(reblancedKey).get();
new MRTask2() {
@Override public void map(Chunk c){
assertTrue(Arrays.deepEquals(c._vec.domain(), oldDomain));
}
}.doAll(rebalancedFrame);
madeKeys.add(rebalancedFrame.lastVec()._key);
final String [] newDomain = new String[]{"x", "y", "z"};
rebalancedFrame.lastVec().changeDomain(newDomain);
new MRTask2() {
@Override public void map(Chunk c){
assertTrue(Arrays.deepEquals(c._vec.domain(), newDomain));
}
}.doAll(rebalancedFrame);
} finally { for(Key k:madeKeys) UKV.remove(k);}
}
@Test public void testChangeDomain(){testChangeDomainImpl();}
// Test HEX-1819
@Test public void testMakeConSeq() {
Vec v;
v = makeConSeq(0xCAFE,CHUNK_SZ);
assertTrue(v.at(234) == 0xCAFE);
assertTrue(v._espc.length == 2);
assertTrue(
v._espc[0] == 0 &&
v._espc[1] == CHUNK_SZ
);
v.remove(new Futures()).blockForPending();
v = makeConSeq(0xCAFE,2*CHUNK_SZ);
assertTrue(v.at(234) == 0xCAFE);
assertTrue(v.at(2*CHUNK_SZ-1) == 0xCAFE);
assertTrue(v._espc.length == 3);
assertTrue(
v._espc[0] == 0 &&
v._espc[1] == CHUNK_SZ &&
v._espc[2] == CHUNK_SZ*2
);
v.remove(new Futures()).blockForPending();
v = makeConSeq(0xCAFE,2*CHUNK_SZ+1);
assertTrue(v.at(234) == 0xCAFE);
assertTrue(v.at(2*CHUNK_SZ) == 0xCAFE);
assertTrue(v._espc.length == 4);
assertTrue(
v._espc[0] == 0 &&
v._espc[1] == CHUNK_SZ &&
v._espc[2] == CHUNK_SZ*2 &&
v._espc[3] == CHUNK_SZ*2+1
);
v.remove(new Futures()).blockForPending();
v = makeConSeq(0xCAFE,3*CHUNK_SZ);
assertTrue(v.at(234) == 0xCAFE);
assertTrue(v.at(3*CHUNK_SZ-1) == 0xCAFE);
assertTrue(v._espc.length == 4);
assertTrue(
v._espc[0] == 0 &&
v._espc[1] == CHUNK_SZ &&
v._espc[2] == CHUNK_SZ*2 &&
v._espc[3] == CHUNK_SZ*3
);
v.remove(new Futures()).blockForPending();
}
// Test HEX-1819
@Test public void testMakeSeq() {
Vec v = makeSeq(3*CHUNK_SZ);
assertTrue(v.at(0) == 1);
assertTrue(v.at(234) == 235);
assertTrue(v.at(2*CHUNK_SZ) == 2*CHUNK_SZ+1);
assertTrue(v._espc.length == 4);
assertTrue(
v._espc[0] == 0 &&
v._espc[1] == CHUNK_SZ &&
v._espc[2] == CHUNK_SZ * 2 &&
v._espc[3] == CHUNK_SZ * 3
);
v.remove(new Futures()).blockForPending();
}
}