Skip to content

Commit

Permalink
Merge branch 'master' of github.com:0xdata/h2o
Browse files Browse the repository at this point in the history
  • Loading branch information
mmalohlava committed Oct 12, 2013
2 parents 97aa69e + ea0749a commit 35cc0a5
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 43 deletions.
13 changes: 7 additions & 6 deletions lib/resources/h2o/console.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,19 @@
%HELP
startPrompt();
} else if( input ) {
$.get('Exec',
{ expression: input, destination_key : 'Result_'+(resultNumber++)+'.hex', escape_nan : true },
function (data, status, jqXHR) {
$.get('Exec2',
// name 'str' matches the Java field name 'water/api/Exec2.str'
{ str: input },
function (data) {
if( data.error ) {
jqconsole.Write(data.error, 'jqconsole-error');
} else if( data.type == 'parsed' ) {
var res = $('<a href="Inspect.html?key='+data.key+'" target="_blank"/>');
} else if( data.cols ) {
var res = $('<a href="Inspect2.html?src_key='+data.key+'" target="_blank"/>');
res.append(data.key);
jqconsole.Append(res);
jqconsole.Write(': ');
if( data.num_rows == 1 && data.num_cols == 1 ) {
jqconsole.Write(data.rows[0][0], 'jqconsole-output');
jqconsole.Write(data.scalar, 'jqconsole-output');
} else if( data.num_cols == 1 ) {
var msg = formatColumn(data.cols[0], data.num_rows)
jqconsole.Write(msg, 'jqconsole-output');
Expand Down
33 changes: 3 additions & 30 deletions src/main/java/water/api/Console.java
Original file line number Diff line number Diff line change
@@ -1,51 +1,24 @@
package water.api;


import java.io.*;

import water.Boot;
import water.exec.Function;
import water.util.Log;
import water.util.RString;

import com.google.common.io.CharStreams;
import com.google.common.io.Closeables;


public class Console extends HTMLOnlyRequest {

@Override
protected String build(Response response) {
RString rs = new RString(loadContent("/h2o/console.html"));
@Override protected String build(Response response) {
RString rs = new RString(Boot._init.loadContent("/h2o/console.html"));
rs.replace("HELP", getHelp());
return rs.toString();
}

private String getHelp() {
StringBuilder sb = new StringBuilder();
sb.append("jqconsole.Write(");

sb.append("'Access keys directly by name (for example `iris.hex`).\\n' +");
sb.append("'Available functions are:'+");
for(String s : Function.FUNCTIONS.keySet()) {
for(String s : Function.FUNCTIONS.keySet())
sb.append("'\\n\\t").append(s).append("' +");
}
sb.append("'\\n', 'jqconsole-output');");
return sb.toString();
}

private String loadContent(String fromFile) {
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
InputStream is = Boot._init.getResource2(fromFile);
reader = new BufferedReader(new InputStreamReader(is));
CharStreams.copy(reader, sb);
} catch( IOException e ){
Log.err(e);
} finally {
Closeables.closeQuietly(reader);
}
return sb.toString();
}
}
44 changes: 44 additions & 0 deletions src/main/java/water/api/Exec2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package water.api;

import water.exec.PositionedException;
import water.util.Log;
import water.*;
import water.fvec.*;

public class Exec2 extends Request2 {
static final int API_WEAVER=1; // This file has auto-gen'd doc & json fields
static public DocGen.FieldDoc[] DOC_FIELDS; // Initialized from Auto-Gen code.
// This Request supports the HTML 'GET' command, and this is the help text for GET.
static final String DOC_GET = "Executes a string.";
@API(help="String to execute", required=true, filter=Default.class)
String str;

@API(help="Parsing error, if any") String error;
@API(help="Result key" ) Key key;
@API(help="Rows in result" ) long num_rows;
@API(help="Columns in result" ) int num_cols;
@API(help="Scalar result" ) double scalar;

@API(help="Array of Column Summaries.") Inspect2.ColSummary cols[];

@Override protected Response serve() {
if( str == null ) return RequestServer._http404.serve();
Exception e;
try {
Frame fr = water.exec.Exec2.exec(str);
key = Key.make(".Last.value");
UKV.remove(key);
UKV.put(key,fr);
num_rows = fr.numRows();
num_cols = fr.numCols();
cols = new Inspect2.ColSummary[num_cols];
for( int i=0; i<num_cols; i++ )
cols[i] = new Inspect2.ColSummary(fr._names[i],fr.vecs()[i]);
if( num_rows==1 && num_cols==1 ) scalar=fr.vecs()[0].at(0);
return new Response(Response.Status.done, this, -1, -1, null);
}
catch( PositionedException pe ) { e=pe;} // No logging user typo's
catch( Exception e2 ) { Log.err(e=e2); }
return Response.error(e.getMessage());
}
}
2 changes: 1 addition & 1 deletion src/main/java/water/api/Inspect2.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class Inspect2 extends Request2 {

// An internal JSON-output-only class
@SuppressWarnings("unused")
private static class ColSummary extends Iced {
static class ColSummary extends Iced {
static final int API_WEAVER=1; // This file has auto-gen'd doc & json fields
static public DocGen.FieldDoc[] DOC_FIELDS; // Initialized from Auto-Gen code.
public ColSummary( String name, Vec vec ) {
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/water/api/RequestServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ public static HashMap<String,Request> requests() {
Request.addToNavbar(registerRequest(new GBM()), "GBM (Beta)", "Model");
Request.addToNavbar(registerRequest(new GLM2()), "GLM2 (Beta)", "Model");
Request.addToNavbar(registerRequest(new NeuralNet()), "Neural Network (Beta)", "Model");
Request.addToNavbar(registerRequest(new Console()), "Console", "Model");

Request.addToNavbar(registerRequest(new RFScore()), "Random Forest", "Score");
Request.addToNavbar(registerRequest(new GLMScore()), "GLM", "Score");
Expand Down Expand Up @@ -113,7 +112,8 @@ public static HashMap<String,Request> requests() {
Request.addToNavbar(registerRequest(new KMeans2()), "KMeans2", "Beta (FluidVecs!)");
Request.addToNavbar(registerRequest(new hex.gbm.DRF()), "DRF2", "Beta (FluidVecs!)");
Request.addToNavbar(registerRequest(new hex.LR2()), "Linear Regression2", "Beta (FluidVecs!)");
Request.addToNavbar(registerRequest(new SummaryPage2()), "Summary2", "Beta (FluidVecs!)");
Request.addToNavbar(registerRequest(new SummaryPage2()), "Summary2", "Beta (FluidVecs!)");
Request.addToNavbar(registerRequest(new Console()), "Console", "Beta (FluidVecs!)");
}

// internal handlers
Expand All @@ -122,22 +122,23 @@ public static HashMap<String,Request> requests() {
registerRequest(new DRFModelView());
registerRequest(new DRFProgressPage());
registerRequest(new DownloadDataset());
registerRequest(new Exec());
registerRequest(new DataManip());
registerRequest(new Exec2());
registerRequest(new Exec()); // Will be replaced by Exec2
registerRequest(new DataManip()); // Will be replaced by Exec2
registerRequest(new ExportS3Progress());
registerRequest(new GBMModelView());
registerRequest(new GBMProgressPage());
registerRequest(new GLMGridProgress());
registerRequest(new GLMProgressPage());
registerRequest(new GetVector());
registerRequest(new GetVector()); // Will be replaced by Exec2
registerRequest(new GridSearchProgress());
registerRequest(new LogView.LogDownload());
registerRequest(new NeuralNetProgress());
registerRequest(new PostFile());
registerRequest(new Progress());
registerRequest(new Progress2());
registerRequest(new PutValue());
registerRequest(new PutVector());
registerRequest(new PutVector()); // Will be replaced by Exec2
registerRequest(new RFTreeView());
registerRequest(new RFView());
registerRequest(new RPackage());
Expand Down
79 changes: 79 additions & 0 deletions src/main/java/water/exec/Exec2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package water.exec;

import water.fvec.*;
import water.*;

/** Execute a generic R string, in the context of an H2O Cloud
* @author [email protected]
*/
public class Exec2 {
byte _buf[];
int _x;

// Parse a string, execute it & return a Frame.
// Grammer:
// expr := ( expr )
// ( op_pre expr expr ... )
// key = expr
// key/num
// key/num op_in expr
// val := key | num
// key := any Key mapping to a Frame.
// op_in:= + - * / % & | ...etc...
// op_pre := min max ...etc...

public static Frame exec( String str ) throws ParserException, EvaluationException {
AST ast = new Exec2().parse(str);
System.out.println(ast);
return null;
}
private AST parse(String str) {
_buf = str.getBytes();
return AST.parseExpr(this);
}

private void skipWS() {
while( _x < _buf.length && _buf[_x] <= ' ' ) _x++;
}
// Skip whitespace.
// If c is the next char, eat it & return true
// Else return false.
private boolean peek(char c) {
if( _x ==_buf.length ) return false;
while( _buf[_x] <= ' ' )
if( ++_x ==_buf.length ) return false;
if( _buf[_x]!=c ) return false;
_x++;
return true;
}

abstract static private class AST {
abstract String opStr();
static AST parseExpr(Exec2 E ) {
if( E.peek('(') ) { throw H2O.unimpl(); } // op_pre or expr
AST ast = ASTKey.parse(E);
if( ast != null && E.peek('=') ) { throw H2O.unimpl(); } // assignment
if( ast == null ) // Key parse optionally returns
ast = ASTNum.parse(E); // Number parse either throws or valid returns
return ASTInfix.parse(E,ast); // Infix op, or not?
}
}
static private class ASTKey extends AST {
Key _key;
@Override String opStr() { return _key.toString(); }
// Parse a valid H2O Frame Key, or return null;
static ASTKey parse(Exec2 E) { throw H2O.unimpl(); }
}
static private class ASTNum extends AST {
double _d;
@Override String opStr() { return Double.toString(_d); }
// Parse a number, or throw a parse error
static ASTNum parse(Exec2 E) { throw H2O.unimpl(); }
}
static private class ASTInfix extends AST {
@Override String opStr() { return "+"; }
// Parse an infix operator, or return the original AST
static ASTInfix parse(Exec2 E, AST ast) { throw H2O.unimpl(); }
}

}

0 comments on commit 35cc0a5

Please sign in to comment.