package water.fvec; import water.parser.BufferedString; import water.util.PrettyPrint; /** * Created by tomas on 3/8/17. * Base class for using visitor pattern with chunks. */ public abstract class ChunkVisitor { public boolean expandedVals() { return false; } void addValue(BufferedString bs) { throw new UnsupportedOperationException(); } void addValue(long uuid_lo, long uuid_hi) { throw new UnsupportedOperationException(); } void addValue(int val) { throw new UnsupportedOperationException(); } void addValue(double val) { throw new UnsupportedOperationException(); } void addValue(long val) { throw new UnsupportedOperationException(); } void addValue(long m, int e) { addValue((double) m * PrettyPrint.pow10(e)); } void addZeros(int zeros) { throw new UnsupportedOperationException(); } void addNAs(int nas) { throw new UnsupportedOperationException(); } /** * Visitor wrapper around NewChunk. Usefull for extracting rows from chunks. */ public static final class NewChunkVisitor extends ChunkVisitor { final NewChunk _nc; NewChunkVisitor(NewChunk nc){_nc = nc;} @Override public boolean expandedVals(){return true;} @Override void addValue(BufferedString bs){_nc.addStr(bs);} @Override void addValue(long uuid_lo, long uuid_hi){_nc.addUUID(uuid_lo,uuid_hi);} @Override void addValue(int val) {_nc.addNum(val,0);} @Override void addValue(long val) {_nc.addNum(val,0);} @Override void addValue(long val, int exp) {_nc.addNum(val,exp);} @Override void addValue(double val) {_nc.addNum(val);} @Override void addZeros(int zeros) {_nc.addZeros(zeros);} @Override void addNAs(int nas) {_nc.addNAs(nas);} } /** * Simple chunk visitor for extracting rows from chunks into a double array. */ public static final class DoubleAryVisitor extends ChunkVisitor { public final double [] vals; private int _k = 0; private final double _na; DoubleAryVisitor(double [] vals){this(vals,Double.NaN);} DoubleAryVisitor(double [] vals, double NA){ this.vals = vals; _na = NA;} @Override void addValue(int val) { vals[_k++] = val;} @Override void addValue(long val) { vals[_k++] = val;} @Override void addValue(double val) { vals[_k++] = Double.isNaN(val)?_na:val;} @Override void addZeros(int zeros) { int k = _k; int kmax = k +zeros; for(;k < kmax; k++) vals[k] = 0; _k = kmax; } @Override void addNAs(int nas) { int k = _k; int kmax = k + nas; for(;k < kmax; k++) vals[k] = _na; _k = kmax; } } /** * Simple chunk visitor for extracting rows from chunks into a sparse double array. */ public static final class SparseDoubleAryVisitor extends ChunkVisitor { public final boolean naSparse; public final double [] vals; public final int [] ids; private int _sparseLen; private int _len; private final double _na; public int sparseLen(){return _sparseLen;} SparseDoubleAryVisitor(double [] vals, int [] ids){this(vals,ids,false,Double.NaN);} SparseDoubleAryVisitor(double [] vals, int [] ids, boolean naSparse){this(vals, ids, naSparse, Double.NaN);} SparseDoubleAryVisitor(double [] vals, int [] ids, boolean naSparse, double NA){this.vals = vals; this.ids = ids; _na = NA; this.naSparse = naSparse;} @Override void addValue(int val) {ids[_sparseLen] = _len++; vals[_sparseLen++] = val;} @Override void addValue(long val) {ids[_sparseLen] = _len++; vals[_sparseLen++] = val;} @Override void addValue(double val) {ids[_sparseLen] = _len++; vals[_sparseLen++] = Double.isNaN(val)?_na:val;} @Override void addZeros(int zeros) { if(naSparse) { int kmax = _sparseLen + zeros; for (int k = _sparseLen; k < kmax; k++) { ids[k] = _len++; vals[k] = 0; } _sparseLen = kmax; } else _len += zeros; } @Override void addNAs(int nas) { if(!naSparse) { int kmax = _sparseLen + nas; for (int k = _sparseLen; k < kmax; k++) { ids[k] = _len++; vals[k] = _na; } _sparseLen = kmax; } else _len += nas; } } /** * Simple chunk visitor for extracting rows from chunks into a integer array. */ public static final class IntAryVisitor extends ChunkVisitor { public final int [] vals; private int _k = 0; private final int _na; IntAryVisitor(int [] vals){this(vals,(int)C4Chunk._NA);} IntAryVisitor(int [] vals, int NA){this.vals = vals; _na = NA;} @Override public void addValue(int val) {vals[_k++] = val;} @Override public void addValue(long val) { if(Integer.MAX_VALUE < val || val < Integer.MIN_VALUE) throw new RuntimeException(val + " does not fit into int"); vals[_k++] = (int)val; } @Override public void addValue(double val) { int i = (int)val; if( i != val) throw new RuntimeException(val + " does not fit into int"); vals[_k++] = i; } @Override public void addZeros(int zeros) { int k = _k; int kmax = k +zeros; for(;k < kmax; k++)vals[k] = 0; _k = kmax; } @Override public void addNAs(int nas) { int k = _k; int kmax = k + nas; for(;k < kmax; k++)vals[k] = _na; _k = kmax; } } }