All Downloads are FREE. Search and download functionalities are using the official Maven repository.

water.rapids.ASTAssign Maven / Gradle / Ivy

There is a newer version: 3.8.2.9
Show newest version
package water.rapids;

import hex.Model;
import water.*;
import water.fvec.Chunk;
import water.fvec.Frame;
import water.fvec.NewChunk;
import water.fvec.Vec;

/** Assign a whole frame over a global.  Copy-On-Write optimizations make this cheap. */
class ASTAssign extends ASTPrim {
  @Override public String[] args() { return new String[]{"id", "frame"}; }
  @Override int nargs() { return 1+2; } // (assign id frame)
  @Override public String str() { return "assign" ; }
  @Override
  public ValFrame apply(Env env, Env.StackHelp stk, AST asts[]) {
    Key id = Key.make( asts[1].str() );
    Frame src = stk.track(asts[2].exec(env)).getFrame();
    return new ValFrame(env._ses.assign(id,src)); // New global Frame over shared Vecs
  }
}

/** Rectangular assign into a row and column slice.  The destination must
 *  already exist.  The output is conceptually a new copy of the data, with a
 *  fresh Frame.  Copy-On-Write optimizations lower the cost to be proportional
 *  to the over-written sections.  */
class ASTRectangleAssign extends ASTPrim {
  @Override public String[] args() { return new String[]{"dst", "src", "col_expr", "row_expr"}; }
  @Override int nargs() { return 5; } // (:= dst src col_expr row_expr)
  @Override public String str() { return ":=" ; }
  @Override
  public Val apply(Env env, Env.StackHelp stk, AST asts[]) {
    Frame dst = stk.track(asts[1].exec(env)).getFrame();
    Val vsrc  = stk.track(asts[2].exec(env));
    // Column selection
    ASTNumList cols_numlist = new ASTNumList(asts[3].columns(dst.names()));
    // Special for ASTAssign: "empty" really means "all"
    if( cols_numlist.isEmpty() ) cols_numlist = new ASTNumList(0,dst.numCols());
    // Allow R-like number list expansion: negative column numbers mean exclusion
    int[] cols = ASTColSlice.col_select(dst.names(),cols_numlist);

    // Any COW optimized path changes Vecs in dst._vecs, and so needs a
    // defensive copy.  Any update-in-place path updates Chunks instead of
    // dst._vecs, and does not need a defensive copy.  To make life easier,
    // just make the copy now.
    dst = new Frame(dst._names,dst.vecs().clone());

    // Assign over the column slice
    if( asts[4] instanceof ASTNum || asts[4] instanceof ASTNumList ) { // Explictly named row assignment
      ASTNumList rows = asts[4] instanceof ASTNum ? new ASTNumList(((ASTNum)asts[4])._v.getNum()) : ((ASTNumList)asts[4]);
      if( rows.isEmpty() ) rows = new ASTNumList(0,dst.numRows()); // Empty rows is really: all rows
      switch( vsrc.type() ) {
      case Val.NUM:  assign_frame_scalar(dst,cols,rows,vsrc.getNum()  ,env._ses);  break;
      case Val.STR:  assign_frame_scalar(dst,cols,rows,vsrc.getStr()  ,env._ses);  break;
      case Val.FRM:  assign_frame_frame (dst,cols,rows,vsrc.getFrame(),env._ses);  break;
      default:       throw new IllegalArgumentException("Source must be a Frame or Number, but found a "+vsrc.getClass());
      }
    } else {                    // Boolean assignment selection?
      Frame rows = stk.track(asts[4].exec(env)).getFrame();
      switch( vsrc.type() ) {
      case Val.NUM:  assign_frame_scalar(dst,cols,rows,vsrc.getNum()  ,env._ses);  break;
      case Val.STR:  throw H2O.unimpl();
      case Val.FRM:  throw H2O.unimpl();
      default:       throw new IllegalArgumentException("Source must be a Frame or Number, but found a "+vsrc.getClass());
      }
    }
    return new ValFrame(dst);
  }

  // Rectangular array copy from src into dst
  private void assign_frame_frame(Frame dst, int[] cols, ASTNumList rows, Frame src, Session ses) {
    // Sanity check
    if( cols.length != src.numCols() )
      throw new IllegalArgumentException("Source and destination frames must have the same count of columns");
    long nrows = rows.cnt();
    if( src.numRows() != nrows )
      throw new IllegalArgumentException("Requires same count of rows in the number-list ("+nrows+") as in the source ("+src.numRows()+")");

    // Whole-column assignment?  Directly reuse columns: Copy-On-Write
    // optimization happens here on the apply() exit.
    if( dst.numRows() == nrows && rows.isDense() ) {
      for( int i=0; i end
        //3 [ rows ]                    rows run left:  rows.min() < start && rows.max() <= end
        //4          [ rows ]           rows run in  :  start <= rows.min() && rows.max() <= end
        //5                   [ rows ]  rows run rite:  start <= rows.min() && end < rows.max()
        if( !(maxend) ) {   // not situation 1 or 2 above
          int startOffset = (int) (min > start ? min : start);  // situation 4 and 5 => min > start;
          for(int i=(int)(startOffset-start);i end
    //    //3 [ rows ]                    rows run left:  rows.min() < start && rows.max() <= end
    //    //4          [ rows ]           rows run in  :  start <= rows.min() && rows.max() <= end
    //    //5                   [ rows ]  rows run rite:  start <= rows.min() && end < rows.max()
    //    if( !(maxend) ) {   // not situation 1 or 2 above
    //      int startOffset = (int) (min > start ? min : start);  // situation 4 and 5 => min > start;
    //      for(int i=startOffset;iget()); // Remove unshared Vecs
    else                Keyed.remove(id);           // Normal (e.g. Model) remove
    return new ValNum(1);
  }
}

class ASTRename extends ASTPrim {
  @Override public String[] args() { return new String[]{"oldId", "newId"}; }
  @Override int nargs() { return 1+2; } // (rename oldId newId)
  @Override public String str() { return "rename" ; }
  @Override
  public ValNum apply(Env env, Env.StackHelp stk, AST asts[]) {
    Key oldKey = Key.make(asts[1].exec(env).getStr());
    Key newKey = Key.make(asts[2].exec(env).getStr());
    Iced o = DKV.remove(oldKey).get();
    if( o instanceof Frame )     DKV.put(newKey, new Frame(newKey, ((Frame)o)._names, ((Frame)o).vecs()));
    else if( o instanceof Model) {
      ((Model) o)._key = newKey;
      DKV.put(newKey, o);
    }
    else throw new IllegalArgumentException("Trying to rename Value of type " + o.getClass());
    return new ValNum(Double.NaN);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy