com.scudata.cellset.datamodel.PgmCellSet Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of esproc Show documentation
Show all versions of esproc Show documentation
SPL(Structured Process Language) A programming language specially for structured data computing.
package com.scudata.cellset.datamodel;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import com.scudata.cellset.ICellSet;
import com.scudata.cellset.IColCell;
import com.scudata.cellset.INormalCell;
import com.scudata.cellset.IRowCell;
import com.scudata.common.ByteArrayInputRecord;
import com.scudata.common.ByteArrayOutputRecord;
import com.scudata.common.ByteMap;
import com.scudata.common.CellLocation;
import com.scudata.common.DBSession;
import com.scudata.common.Logger;
import com.scudata.common.MD5;
import com.scudata.common.Matrix;
import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.dm.Context;
import com.scudata.dm.DBObject;
import com.scudata.dm.FileObject;
import com.scudata.dm.IQueryable;
import com.scudata.dm.JobSpace;
import com.scudata.dm.KeyWord;
import com.scudata.dm.Machines;
import com.scudata.dm.ParallelCaller;
import com.scudata.dm.Param;
import com.scudata.dm.ParamList;
import com.scudata.dm.RetryException;
import com.scudata.dm.Sequence;
import com.scudata.dm.cursor.ICursor;
import com.scudata.dm.cursor.MultipathCursors;
import com.scudata.dm.op.Channel;
import com.scudata.expression.Expression;
import com.scudata.expression.IParam;
import com.scudata.expression.ParamInfo2;
import com.scudata.expression.ParamParser;
import com.scudata.resources.EngineMessage;
import com.scudata.thread.CursorLooper;
import com.scudata.thread.Job;
import com.scudata.thread.ThreadPool;
import com.scudata.util.Variant;
// ??????
public class PgmCellSet extends CellSet {
private static final long serialVersionUID = 0x02010010;
public static final int PRIVILEGE_FULL = 0; // ??ȫ???ƣ????????κ?????
public static final int PRIVILEGE_EXEC = 1; // ֻ????ִ??
private static final int SIGN_AUTOCALC = 0x00000010; // ?Զ?????
private int sign = 0;
private ByteMap customPropMap; // ?Զ???????
// private String []psws = new String[2]; // 2?????룬??????ǰ
private String pswHash; // ????hashֵ
private int nullPswPrivilege = PRIVILEGE_EXEC; // ???????½ʱ??Ȩ??
transient private int curPrivilege = PRIVILEGE_FULL; // ??ǰ??Ȩ??
transient protected CellLocation curLct; // ??ǰ????ĵ?Ԫ???λ??
transient private Object curDb; // DBObject??this??this??ʾ?ļ???dql
transient private LinkedList stack = new LinkedList(); // ?????ջ
transient private CellLocation parseLct; // ??ǰ???ڽ???????ʽ?ĵ?Ԫ??
transient private Sequence resultValue; // result??䷵??ֵ??????ĻḲ??ǰ???
transient private int resultCurrent;
transient private CellLocation resultLct; // result??????ڵ?Ԫ??
transient private boolean interrupt; // ?Ƿ???ù?interrupt
transient private boolean isInterrupted; // ????ʱʹ?ã???ͣ???????
transient private boolean hasReturn = false;
transient private String name; // ????????DfxManager??ʹ??
// func fn(arg,??)
transient private HashMap fnMap; // [??????, ??????Ϣ]ӳ??
transient private ForkCmdCode forkCmdCode; // ??ǰִ?е?fork?????
private String isvHash; // ?й??ܵ?14??KIT??ʱ??д??dfxʱ??Ҫд????Ȩ?ļ???isv??MD5ֵ
private static class CmdCode {
protected byte type; // Command????
protected int row; // Command???к?
protected int col; // Command???к?
protected int blockEndRow; // Command?Ĵ??????????к?
public CmdCode(byte type, int r, int c, int endRow) {
this.type = type;
this.row = r;
this.col = c;
this.blockEndRow = endRow;
}
}
private static abstract class ForCmdCode extends CmdCode {
protected int seq = 0; // forѭ?????
public ForCmdCode(int r, int c, int endRow) {
super(Command.FOR, r, c, endRow);
}
abstract public boolean hasNextValue();
abstract public Object nextValue();
public Object endValue() {
return null;
}
public int getSeq() {
return seq;
}
public void setSeq(int n) {
this.seq = n;
}
}
private static class ForkCmdCode extends CmdCode {
protected int seq = 0; // fork?߳????
public ForkCmdCode(int r, int c, int endRow, int seq) {
super(Command.FORK, r, c, endRow);
this.seq = seq;
}
}
private static class EndlessForCmdCode extends ForCmdCode {
public EndlessForCmdCode(int r, int c, int endRow) {
super(r, c, endRow);
}
public boolean hasNextValue() {
return true;
}
public Object nextValue() {
return new Integer(++seq);
}
}
private static class SequenceForCmdCode extends ForCmdCode {
private Sequence sequence;
public SequenceForCmdCode(int r, int c, int endRow, Sequence sequence) {
super(r, c, endRow);
this.sequence = sequence;
}
public boolean hasNextValue() {
return seq < sequence.length();
}
public Object nextValue() {
return sequence.get(++seq);
}
}
private static class BoolForCmdCode extends ForCmdCode {
private Expression exp;
private Context ctx;
public BoolForCmdCode(int r, int c, int endRow, Expression exp,
Context ctx) {
super(r, c, endRow);
this.exp = exp;
this.ctx = ctx;
}
public boolean hasNextValue() {
Object value = exp.calculate(ctx);
if (!(value instanceof Boolean)) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("engine.forVarTypeError"));
}
return ((Boolean) value).booleanValue();
}
public Object nextValue() {
++seq;
return Boolean.TRUE;
}
public Object endValue() {
return Boolean.FALSE;
}
}
private static class IntForCmdCode extends ForCmdCode {
private int start;
private int end;
private int step;
public IntForCmdCode(int r, int c, int endRow, int start, int end,
int step) {
super(r, c, endRow);
this.start = start;
this.end = end;
this.step = step;
}
public boolean hasNextValue() {
if (step >= 0) {
return start <= end;
} else {
return start >= end;
}
}
public Object nextValue() {
Object val = new Integer(start);
++seq;
start += step;
return val;
}
public Object endValue() {
return new Integer(start);
}
}
private static class CursorForCmdCode extends ForCmdCode {
private ICursor cursor;
private int count;
private Expression gexp;
private Context ctx;
private Sequence table;
// private boolean bi = false; // ?Ƿ???group@i
public CursorForCmdCode(int r, int c, int endRow, ICursor cursor,
int count, Expression gexp, Context ctx) {
super(r, c, endRow);
this.cursor = cursor;
this.count = count;
this.gexp = gexp;
this.ctx = ctx;
}
public boolean hasNextValue() {
if (gexp == null) {
table = cursor.fetch(count);
} else {
table = cursor.fetchGroup(gexp, ctx);
}
return table != null && table.length() > 0;
}
public Object nextValue() {
++seq;
return table;
}
public void close() {
cursor.close();
}
}
private static class ForkJob extends Job {
PgmCellSet pcs;
int row;
int col;
int endRow;
public ForkJob(PgmCellSet pcs, int row, int col, int endRow) {
this.pcs = pcs;
this.row = row;
this.col = col;
this.endRow = endRow;
}
public void run() {
pcs.executeFork(row, col, endRow);
}
public Object getResult() {
return pcs.getForkResult();
}
}
private class SubForkJob extends Job {
private IParam param;
private int row;
private int col;
private int endRow;
private Context ctx;
public SubForkJob(IParam param, int row, int col, int endRow,
Context ctx) {
this.param = param;
this.row = row;
this.col = col;
this.endRow = endRow;
this.ctx = ctx;
}
public void run() {
runForkCmd(param, row, col, endRow, ctx);
}
}
/**
* ?????ж???ĺ?????Ϣ
* @author RunQian
*
*/
public class FuncInfo {
private PgmNormalCell cell; // ???????ڵ?Ԫ??
private String[] argNames; // ??????
public FuncInfo(PgmNormalCell cell, String[] argNames) {
this.cell = cell;
this.argNames = argNames;
}
/**
* ȡ???????ڵĵ?Ԫ??
* @return
*/
public PgmNormalCell getCell() {
return cell;
}
/**
* ȡ?????IJ?????
* @return
*/
public String[] getArgNames() {
return argNames;
}
}
public PgmCellSet() {
}
/**
* ????һ??ָ?????????????ı???
* @param row int ????
* @param col int ????
*/
public PgmCellSet(int row, int col) {
super(row, col);
}
public NormalCell newCell(int r, int c) {
return new PgmNormalCell(this, r, c);
}
public RowCell newRowCell(int r) {
return new RowCell(r);
}
public ColCell newColCell(int c) {
return new ColCell(c);
}
public PgmNormalCell getPgmNormalCell(int row, int col) {
return (PgmNormalCell) cellMatrix.get(row, col);
}
public INormalCell getCurrent() {
return curLct == null ? null : getNormalCell(curLct.getRow(),
curLct.getCol());
}
public void setCurrent(INormalCell cell) {
if (cell == null) {
curLct = null;
} else {
if (curLct == null) {
curLct = new CellLocation(cell.getRow(), cell.getCol());
} else {
curLct.set(cell.getRow(), cell.getCol());
}
}
}
// ????һ???µ?????????????Դ???ĵ?Ԫ??ӵ???Լ??ļ??㻷??
public PgmCellSet newCalc() {
Matrix m1 = cellMatrix;
int colSize = cellMatrix.getColSize();
int rowSize = cellMatrix.getRowSize();
PgmCellSet pcs = new PgmCellSet();
Matrix m2 = new Matrix(rowSize, colSize);
pcs.cellMatrix = m2;
for (int r = 0; r < rowSize; ++r) {
for (int c = 0; c < colSize; ++c) {
m2.set(r, c, m1.get(r, c));
}
}
pcs.sign = sign;
pcs.pswHash = pswHash;
pcs.nullPswPrivilege = nullPswPrivilege;
Context ctx = getContext();
pcs.setContext(ctx.newComputeContext());
pcs.name = name;
return pcs;
}
// ?????µ?????cursor(c,??)ʹ??
public PgmCellSet newCursorDFX(INormalCell cell, Object[] args) {
int rowCount = getRowCount();
int colCount = getColCount();
PgmCellSet newPcs = new PgmCellSet(rowCount, colCount);
int row = cell.getRow();
int col = cell.getCol();
int endRow = getCodeBlockEndRow(row, col);
// ???????ĸ???ֻ???ø?ֵ???????ñ???ʽ
for (int r = 1; r < row; ++r) {
for (int c = 1; c <= colCount; ++c) {
Object val = getPgmNormalCell(r, c).getValue();
newPcs.getPgmNormalCell(r, c).setValue(val);
}
}
for (int r = endRow + 1; r <= rowCount; ++r) {
for (int c = 1; c <= colCount; ++c) {
Object val = getPgmNormalCell(r, c).getValue();
newPcs.getPgmNormalCell(r, c).setValue(val);
}
}
for (int r = row; r <= endRow; ++r) {
for (int c = 1; c < col; ++c) {
Object val = getPgmNormalCell(r, c).getValue();
newPcs.getPgmNormalCell(r, c).setValue(val);
}
for (int c = col; c <= colCount; ++c) {
INormalCell tmp = getCell(r, c);
INormalCell cellClone = (INormalCell) tmp.deepClone();
cellClone.setCellSet(newPcs);
newPcs.setCell(r, c, cellClone);
}
}
// ?Ѳ???ֵ?赽func??Ԫ???ϼ?????ĸ???
if (args != null) {
int paramRow = row;
int paramCol = col;
for (int i = 0, pcount = args.length; i < pcount; ++i) {
newPcs.getPgmNormalCell(paramRow, paramCol).setValue(args[i]);
if (paramCol < colCount) {
paramCol++;
} else {
break;
// if (paramRow == getRowCount() && i < paramCount - 1) {
// MessageManager mm = EngineMessage.get();
// throw new RQException("call" +
// mm.getMessage("function.paramCountNotMatch"));
// }
// paramRow++;
// paramCol = 1;
}
}
}
newPcs.setContext(getContext());
newPcs.setCurrent(cell);
newPcs.setNext(row, col + 1, false);
newPcs.name = name;
return newPcs;
}
/**
* ??ȿ?¡
* @return ??¡???Ķ???
*/
public Object deepClone() {
PgmCellSet pcs = new PgmCellSet();
int colSize = cellMatrix.getColSize();
int rowSize = cellMatrix.getRowSize();
pcs.cellMatrix = new Matrix(rowSize, colSize);
;
for (int col = 1; col < colSize; col++) {
for (int row = 1; row < rowSize; row++) {
INormalCell cell = getCell(row, col);
INormalCell cellClone = (INormalCell) cell.deepClone();
cellClone.setCellSet(pcs);
pcs.cellMatrix.set(row, col, cellClone);
}
}
// ?????????
for (int col = 1; col < colSize; col++)
pcs.cellMatrix.set(0, col, getColCell(col).deepClone());
for (int row = 1; row < rowSize; row++)
pcs.cellMatrix.set(row, 0, getRowCell(row).deepClone());
ParamList param = getParamList();
if (param != null) {
pcs.setParamList((ParamList) param.deepClone());
}
pcs.sign = sign;
if (customPropMap != null) {
pcs.customPropMap = (ByteMap) customPropMap.deepClone();
}
pcs.pswHash = pswHash;
pcs.nullPswPrivilege = nullPswPrivilege;
pcs.name = name;
return pcs;
}
/**
* д???ݵ???
* @param out ObjectOutput ?????
* @throws IOException
*/
public void writeExternal(ObjectOutput out) throws IOException {
super.writeExternal(out);
out.writeByte(2);
out.writeInt(sign); // ???뱨??4????
out.writeObject(customPropMap);
out.writeObject(pswHash);
out.writeInt(nullPswPrivilege);
out.writeObject(name); // ?汾2д??
}
/**
* ?????ж?????
* @param in ObjectInput ??????
* @throws IOException
* @throws ClassNotFoundException
*/
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
super.readExternal(in);
int v = in.readByte();
sign = in.readInt();
customPropMap = (ByteMap) in.readObject();
pswHash = (String) in.readObject();
nullPswPrivilege = in.readInt();
if (v > 1) {
name = (String)in.readObject();
}
}
public byte[] serialize() throws IOException {
ByteArrayOutputRecord out = new ByteArrayOutputRecord();
// ???л???Ԫ?????
int rowCount = getRowCount();
int colCount = getColCount();
out.writeInt(rowCount);
out.writeInt(colCount);
for (int row = 1; row <= rowCount; ++row) {
IRowCell rc = getRowCell(row);
out.writeRecord(rc);
}
for (int col = 1; col <= colCount; ++col) {
IColCell cc = getColCell(col);
out.writeRecord(cc);
}
for (int row = 1; row <= rowCount; ++row) {
for (int col = 1; col <= colCount; ++col) {
INormalCell nc = getCell(row, col);
out.writeRecord(nc);
}
}
out.writeRecord(paramList);
out.writeInt(sign); // ???뱨??4????
out.writeRecord(customPropMap);
out.writeStrings(null); // Ϊ?˼???psws
out.writeInt(0); // ????֮ǰ?Ļ???
out.writeString(pswHash);
out.writeInt(nullPswPrivilege);
isvHash = null;
out.writeString(isvHash);
return out.toByteArray();
}
/**
* ?????ж?????
* @param buf byte[]
* @throws IOException
* @throws ClassNotFoundException
*/
public void fillRecord(byte[] buf) throws IOException,
ClassNotFoundException {
ByteArrayInputRecord in = new ByteArrayInputRecord(buf);
// ???ɵ?Ԫ?????
int rowCount = in.readInt();
int colCount = in.readInt();
cellMatrix = new Matrix(rowCount + 1, colCount + 1);
for (int row = 1; row <= rowCount; ++row) {
RowCell rc = (RowCell) in.readRecord(newRowCell(row));
cellMatrix.set(row, 0, rc);
}
for (int col = 1; col <= colCount; ++col) {
ColCell cc = (ColCell) in.readRecord(newColCell(col));
cellMatrix.set(0, col, cc);
}
for (int row = 1; row <= rowCount; ++row) {
for (int col = 1; col <= colCount; ++col) {
NormalCell nc = (NormalCell) in.readRecord(newCell(row, col));
cellMatrix.set(row, col, nc);
}
}
paramList = (ParamList) in.readRecord(new ParamList());
sign = in.readInt();
customPropMap = (ByteMap) in.readRecord(new ByteMap());
if (in.available() > 0) {
in.readStrings();
if (in.available() > 0) {
in.readInt(); // ????֮ǰ?Ļ???
if (in.available() > 0) {
pswHash = in.readString();
nullPswPrivilege = in.readInt();
if (in.available() > 0) {
isvHash = in.readString();
}
}
}
}
}
// ????else?????
private void skipCodeBlock() {
int curRow = curLct.getRow();
int curCol = curLct.getCol();
int endBlock = getCodeBlockEndRow(curRow, curCol);
// ??һ??Ҫִ?еĵ?Ԫ???赽??????ĵ?Ԫ??
setNext(endBlock + 1, 1, true);
}
// ????һ??Ҫִ?еĸ??赽if????Ӧ??else??????һ??
// ??ǰ??Ϊif????
private void toElseCmd() {
int curRow = curLct.getRow();
int curCol = curLct.getCol();
int totalCol = getColCount();
int level = 0;
Command command;
// ?ڱ?????Ѱ??else??֧
for (int c = curCol + 1; c <= totalCol; ++c) {
PgmNormalCell cell = getPgmNormalCell(curRow, c);
if ((command = cell.getCommand()) != null) {
byte type = command.getType();
if (type == Command.ELSE) {
if (level == 0) { // ?ҵ???Ӧ??else??֧
setNext(curRow, c + 1, false);
return;
} else {
level--;
}
} else if (type == Command.ELSEIF) {
if (level == 0) { // ?ҵ???Ӧ??elseif??֧
setNext(curRow, c, false);
runIfCmd(cell, command);
return;
}
} else if (type == Command.IF) {
level++;
}
}
}
// ?????????
int endBlock = getCodeBlockEndRow(curRow, curCol);
int nextRow = endBlock + 1;
if (nextRow <= getRowCount()) {
for (int c = 1; c <= totalCol; ++c) {
PgmNormalCell cell = getPgmNormalCell(nextRow, c);
if (!cell.isBlankCell()) {
if (c != curCol) { // û??else??֧
setNext(nextRow, c, true);
} else {
command = cell.getCommand();
if (command == null) {
setNext(nextRow, c, true);
} else {
byte type = command.getType();
if (type == Command.ELSE) { // ?ҵ???Ӧ??else??֧
setNext(nextRow, c + 1, false);
} else if (type == Command.ELSEIF) { // ?ҵ???Ӧ??elseif??֧
setNext(nextRow, c, false);
runIfCmd(cell, command);
} else {
setNext(nextRow, c, true);
}
}
}
return;
}
}
} else {
setNext(nextRow, 1, true); // ??????ѭ????????
}
}
private int getIfBlockEndRow(int prow, int pcol) {
int level = 0;
int totalCol = getColCount();
Command command;
// ?ڱ?????Ѱ??else??֧
for (int c = pcol + 1; c <= totalCol; ++c) {
PgmNormalCell cell = getPgmNormalCell(prow, c);
if ((command = cell.getCommand()) != null) {
byte type = command.getType();
if (type == Command.ELSE) {
if (level == 0) { // ?ҵ???Ӧ??else??֧
return prow;
} else {
level--;
}
} else if (type == Command.ELSEIF) {
if (level == 0) { // ?ҵ???Ӧ??elseif??֧
return prow;
}
} else if (type == Command.IF) {
level++;
}
}
}
// ?????????
int endBlock = getCodeBlockEndRow(prow, pcol);
int totalRow = getRowCount();
if (endBlock < totalRow) {
int nextRow = endBlock + 1;
for (int c = 1; c <= totalCol; ++c) {
PgmNormalCell cell = getPgmNormalCell(nextRow, c);
if (cell.isBlankCell())
continue;
command = cell.getCommand();
if (command == null) {
return endBlock;
} else {
byte type = command.getType();
if (type == Command.ELSE) { // ?ҵ???Ӧ??else??֧
return getCodeBlockEndRow(nextRow, c);
} else if (type == Command.ELSEIF) { // ?ҵ???Ӧ??elseif??֧
return getIfBlockEndRow(nextRow, c);
} else {
return endBlock;
}
}
}
throw new RuntimeException();
} else {
return endBlock;
}
}
// ִ??if?????
private void runIfCmd(NormalCell cell, Command command) {
Context ctx = getContext();
Expression exp = command.getExpression(this, ctx);
if (exp == null) {
MessageManager mm = EngineMessage.get();
throw new RQException("if" + mm.getMessage("function.invalidParam"));
}
Object value = exp.calculate(ctx);
cell.setValue(value);
if (Variant.isTrue(value)) {
setNext(curLct.getRow(), curLct.getCol() + 1, false);
} else {
toElseCmd();
}
}
/**
* ????for??Ԫ??ǰ??ѭ????? #A1
* @param r int for??Ԫ????к?
* @param c int for??Ԫ????к?
* @return int
*/
public int getForCellRepeatSeq(int r, int c) {
for (int i = 0; i < stack.size(); ++i) {
CmdCode cmd = stack.get(i);
if (cmd.row == r && cmd.col == c) {
if (cmd.type == Command.FOR) {
return ((ForCmdCode) cmd).getSeq();
} else {
break;
}
}
}
if (forkCmdCode != null && forkCmdCode.row == r && forkCmdCode.col == c) {
return forkCmdCode.seq;
}
MessageManager mm = EngineMessage.get();
throw new RQException("#" + CellLocation.getCellId(r, c)
+ mm.getMessage("engine.needInFor"));
}
// ִ??for?????
private void runForCmd(NormalCell cell, Command command) {
int row = curLct.getRow();
int col = curLct.getCol();
if (stack.size() > 0) {
CmdCode cmd = stack.getFirst();
if (cmd != null && cmd.row == row && cmd.col == col) {
// ִ????һ??ѭ??
ForCmdCode forCmd = (ForCmdCode) cmd;
if (forCmd.hasNextValue()) {
cell.setValue(forCmd.nextValue());
setNext(row, col + 1, false); // ִ????һ??Ԫ??
} else {
// ????ѭ??
cell.setValue(forCmd.endValue());
stack.removeFirst();
setNext(cmd.blockEndRow + 1, 1, true);
}
return;
}
}
// ?״?ִ??ѭ????????ѭ??????
ForCmdCode cmdCode;
Context ctx = getContext();
int endRow = getCodeBlockEndRow(row, col);
Expression exp = command.getExpression(this, ctx);
if (exp == null) {
cmdCode = new EndlessForCmdCode(row, col, endRow);
} else {
Object value = exp.calculate(ctx);
if (value instanceof Number) {
IParam param = command.getParam(this, ctx);
if (param.isLeaf()) {
cmdCode = new IntForCmdCode(row, col, endRow, 1,
((Number) value).intValue(), 1);
} else {
int size = param.getSubSize();
if (size > 3) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
IParam sub = param.getSub(1);
if (sub == null) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
Object obj = sub.getLeafExpression().calculate(ctx);
if (!(obj instanceof Number)) {
MessageManager mm = EngineMessage.get();
throw new RQException(
mm.getMessage("engine.forVarTypeError"));
}
int start = ((Number) value).intValue();
int end = ((Number) obj).intValue();
int step;
if (size > 2) {
sub = param.getSub(2);
if (sub == null) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
obj = sub.getLeafExpression().calculate(ctx);
if (!(obj instanceof Number)) {
MessageManager mm = EngineMessage.get();
throw new RQException(
mm.getMessage("engine.forVarTypeError"));
}
step = ((Number) obj).intValue();
} else {
if (start <= end) {
step = 1;
} else {
step = -1;
}
}
cmdCode = new IntForCmdCode(row, col, endRow, start, end,
step);
}
} else if (value instanceof Sequence) {
cmdCode = new SequenceForCmdCode(row, col, endRow,
(Sequence) value);
} else if (value instanceof Boolean) {
cell.setValue(value);
if (((Boolean) value).booleanValue()) {
cmdCode = new BoolForCmdCode(row, col, endRow, exp, ctx);
cmdCode.setSeq(1);
stack.addFirst(cmdCode);
setNext(row, col + 1, false);
} else {
setNext(endRow + 1, 1, true); // ????ѭ??
}
return;
} else if (value instanceof ICursor) {
IParam param = command.getParam(this, ctx);
int count = 1;
Expression gexp = null;
if (param.getType() == IParam.Semicolon) {
if (param.getSubSize() != 2) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
IParam sub = param.getSub(1);
if (sub == null) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
} else if (sub.isLeaf()) {
gexp = sub.getLeafExpression();
} else {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
} else if (!param.isLeaf()) {
if (param.getSubSize() != 2) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
IParam sub = param.getSub(1);
if (sub != null) {
Object countObj = sub.getLeafExpression()
.calculate(ctx);
if (!(countObj instanceof Number)) {
MessageManager mm = EngineMessage.get();
throw new RQException(
mm.getMessage("engine.forVarTypeError"));
}
count = ((Number) countObj).intValue();
if (count < 1) {
MessageManager mm = EngineMessage.get();
throw new RQException("for"
+ mm.getMessage("function.invalidParam"));
}
}
}
cmdCode = new CursorForCmdCode(row, col, endRow,
(ICursor) value, count, gexp, ctx);
} else if (value == null) {
cmdCode = null;
} else {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("engine.forVarTypeError"));
}
}
if (cmdCode != null && cmdCode.hasNextValue()) {
cell.setValue(cmdCode.nextValue());
stack.addFirst(cmdCode);
setNext(row, col + 1, false);
} else {
setNext(endRow + 1, 1, true); // ????ѭ??
}
}
private void runContinueCmd(Command command) {
CellLocation forLct = command.getCellLocation(getContext());
int index = -1;
for (int i = 0, size = stack.size(); i < size; ++i) {
CmdCode cmd = stack.get(i);
if (cmd.type == Command.FOR) {
if (forLct == null
|| (forLct.getRow() == cmd.row && forLct.getCol() == cmd.col)) {
index = i;
break;
}
}
}
if (index == -1) {
MessageManager mm = EngineMessage.get();
throw new RQException("next" + mm.getMessage("engine.needInFor"));
}
for (int i = 0; i < index; ++i) {
// ?????ڲ?forѭ??
CmdCode cmd = stack.removeFirst();
if (cmd.type == Command.FOR) {
endForCommand((ForCmdCode) cmd);
}
}
CmdCode cmd = stack.getFirst();
setNext(cmd.row, cmd.col, false);
}
private void runBreakCmd(Command command) {
CellLocation forLct = command.getCellLocation(getContext());
int index = -1;
for (int i = 0, size = stack.size(); i < size; ++i) {
CmdCode cmd = stack.get(i);
if (cmd.type == Command.FOR) {
if (forLct == null
|| (forLct.getRow() == cmd.row && forLct.getCol() == cmd.col)) {
index = i;
break;
}
}
}
if (index == -1) {
MessageManager mm = EngineMessage.get();
throw new RQException("break" + mm.getMessage("engine.needInFor"));
}
for (int i = 0; i < index; ++i) {
// ?????ڲ?forѭ??
CmdCode cmd = stack.removeFirst();
if (cmd.type == Command.FOR) {
endForCommand((ForCmdCode) cmd);
}
}
CmdCode cmd = stack.removeFirst();
endForCommand((ForCmdCode) cmd);
setNext(cmd.blockEndRow + 1, 1, true);
}
private void runGotoCmd(Command command) {
CellLocation lct = command.getCellLocation(getContext());
if (lct == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(command.getLocation()
+ mm.getMessage("cellset.cellNotExist"));
}
int r = lct.getRow();
int c = lct.getCol();
int index = -1;
for (int i = 0, size = stack.size(); i < size; ++i) {
CmdCode cmd = stack.get(i);
if (r > cmd.blockEndRow || r < cmd.row) {
index = i;
} else if (c <= cmd.col) {
if (r == cmd.row) {
index = i;
} else {
// ????????ѭ???ڵ?ǰ??Ŀհ?
MessageManager mm = EngineMessage.get();
throw new RQException(
mm.getMessage("cellset.invalidGotoCell"));
}
} else {
break;
}
}
for (int i = 0; i <= index; ++i) {
// ?????ڲ?forѭ??
CmdCode cmd = stack.removeFirst();
if (cmd.type == Command.FOR) {
endForCommand((ForCmdCode) cmd);
}
}
setNext(r, c, false);
}
// ???????е?ѭ?????
private void endForCommand(ForCmdCode cmd) {
if (cmd instanceof CursorForCmdCode) {
((CursorForCmdCode) cmd).close();
}
}
// ????????ִ??fork?????????
private PgmCellSet newForkPgmCellSet(int row, int col, int endRow,
Context ctx, boolean isLocal) {
int rowCount = getRowCount();
int colCount = getColCount();
PgmCellSet pcs = new PgmCellSet(rowCount, colCount);
if (isLocal) {
for (int r = 1; r <= rowCount; ++r) {
for (int c = 1; c <= colCount; ++c) {
PgmNormalCell cell = getPgmNormalCell(r, c);
PgmNormalCell newCell = pcs.getPgmNormalCell(r, c);
newCell.setExpString(cell.getExpString());
newCell.setValue(cell.getValue());
}
}
pcs.setContext(ctx.newComputeContext());
} else {
// ???????ʱ??????????˱?????fork???????ĸ?????????Щ????????ֵ
ParamList usedParams = new ParamList();
ArrayList usedCells = new ArrayList();
for (int r = row; r <= endRow; ++r) {
for (int c = col + 1; c <= colCount; ++c) {
PgmNormalCell cell = getPgmNormalCell(r, c);
cell.getUsedParamsAndCells(usedParams, usedCells);
PgmNormalCell newCell = pcs.getPgmNormalCell(r, c);
newCell.setExpString(cell.getExpString());
}
}
pcs.setParamList(usedParams);
for (INormalCell cell : usedCells) {
int r = cell.getRow();
int c = cell.getCol();
if (r < row || r > endRow || c < col) {
pcs.getPgmNormalCell(r, c).setValue(cell.getValue());
}
}
}
pcs.name = name;
return pcs;
}
private void executeFork(int row, int col, int endRow) {
curLct = new CellLocation(row, col);
setNext(row, col + 1, false);
CellLocation lct = curLct;
if (lct == null || lct.getRow() > endRow)
return;
do {
lct = runNext2();
} while (lct != null && lct.getRow() <= endRow && resultValue == null);
if (resultValue == null) {
// δ????result??endȱʡ???ش????????һ???????ֵ
int colCount = getColCount();
for (int r = endRow; r >= row; --r) {
for (int c = colCount; c > col; --c) {
PgmNormalCell cell = getPgmNormalCell(r, c);
if (cell.isCalculableCell() || cell.isCalculableBlock()) {
Object val = cell.getValue();
resultValue = new Sequence(1);
resultValue.add(val);
return;
}
}
}
}
}
private Object getForkResult() {
if (resultValue != null) {
if (resultValue.length() == 0) {
return null;
} else if (resultValue.length() == 1) {
return resultValue.get(1);
} else {
return resultValue;
}
} else {
return null;
}
}
// ?ж?fork???Ƿ??????fork????????fork????ִ??
private boolean isNextCommandBlock(int prevEndRow, int col, byte cmdType) {
int totalRowCount = getRowCount();
if (prevEndRow == totalRowCount) {
return false;
}
int nextRow = prevEndRow + 1;
PgmNormalCell cell = getPgmNormalCell(nextRow, col);
Command nextCommand = cell.getCommand();
if (nextCommand == null || nextCommand.getType() != cmdType) {
return false;
}
for (int c = 1; c < col; ++c) {
cell = getPgmNormalCell(nextRow, c);
if (!cell.isBlankCell()) {
return false;
}
}
return true;
}
private void runForkCmd(Command command, Context ctx) {
int row = curLct.getRow();
int col = curLct.getCol();
int endRow = getCodeBlockEndRow(row, col);
IParam param = command.getParam(this, ctx);
// ֻ?е???fork
if (!isNextCommandBlock(endRow, col, Command.FORK)) {
runForkCmd(param, row, col, endRow, ctx);
} else {
// ?????????fork????ִ??
ArrayList list = new ArrayList();
while (true) {
SubForkJob job = new SubForkJob(param, row, col, endRow, ctx);
list.add(job);
if (isNextCommandBlock(endRow, col, Command.FORK)) {
row = endRow + 1;
endRow = getCodeBlockEndRow(row, col);
PgmNormalCell cell = getPgmNormalCell(row, col);
command = cell.getCommand();
param = command.getParam(this, ctx);
} else {
break;
}
}
ThreadPool pool = ThreadPool.newInstance(list.size());
try {
for (SubForkJob job : list) {
pool.submit(job);
}
for (SubForkJob job : list) {
job.join();
}
} finally {
pool.shutdown();
}
}
setNext(endRow + 1, 1, true);
}
// fork ??.;h,s
private void runForkxCmd(IParam param, int row, int col, int endRow,
Context ctx) {
if (param.getSubSize() != 2) {
MessageManager mm = EngineMessage.get();
throw new RQException("fork"
+ mm.getMessage("function.invalidParam"));
}
IParam leftParam = param.getSub(0);
IParam rightParam = param.getSub(1);
Object hostObj;
if (rightParam == null || !rightParam.isLeaf()) {
MessageManager mm = EngineMessage.get();
throw new RQException("fork"
+ mm.getMessage("function.invalidParam"));
} else {
hostObj = rightParam.getLeafExpression().calculate(ctx);
}
Machines mc = new Machines();
if (!mc.set(hostObj)) {
MessageManager mm = EngineMessage.get();
throw new RQException("callx"
+ mm.getMessage("function.invalidParam"));
}
String[] hosts = mc.getHosts();
int[] ports = mc.getPorts();
int mcount = -1; // ??????
Object[] args = null; // ????
if (leftParam == null) {
} else if (leftParam.isLeaf()) {
Object val = leftParam.getLeafExpression().calculate(ctx);
if (val instanceof Sequence) {
int len = ((Sequence) val).length();
if (len == 0) {
MessageManager mm = EngineMessage.get();
throw new RQException("fork"
+ mm.getMessage("function.invalidParam"));
}
mcount = len;
}
args = new Object[] { val };
} else {
int pcount = leftParam.getSubSize();
args = new Object[pcount];
for (int p = 0; p < pcount; ++p) {
IParam sub = leftParam.getSub(p);
if (sub != null) {
args[p] = sub.getLeafExpression().calculate(ctx);
if (args[p] instanceof Sequence) {
int len = ((Sequence) args[p]).length();
if (len == 0) {
MessageManager mm = EngineMessage.get();
throw new RQException("fork"
+ mm.getMessage("function.invalidParam"));
}
if (mcount == -1) {
mcount = len;
} else if (mcount != len) {
MessageManager mm = EngineMessage.get();
throw new RQException(
"fork"
+ mm.getMessage("function.paramCountNotMatch"));
}
}
}
}
}
// ????fork?????????????ڵ??
PgmCellSet pcs = newForkPgmCellSet(row, col, endRow, ctx, false);
ParallelCaller caller = new ParallelCaller(pcs, hosts, ports);
caller.setContext(ctx);
// if (mcount > 0 && mcount < hosts.length) {
// caller.setOptions("a");
// }
// ??????û?ж?Ӧ??reduce
int nextRow = endRow + 1;
if (nextRow <= getRowCount()) {
Command command = getPgmNormalCell(nextRow, col).getCommand();
if (command != null && command.getType() == Command.REDUCE) {
int reduceEndRow = getCodeBlockEndRow(nextRow, col);
PgmCellSet reduce = newForkPgmCellSet(nextRow, col,
reduceEndRow, ctx, false);
caller.setReduce(reduce, new CellLocation(row, col),
new CellLocation(nextRow, col));
}
}
if (args != null) {
// ͨ????????????ݲ?????Ȼ??????fork???ڸ?ı???ʽΪ=????
final String pname = "tmp_fork_param";
ParamList pl = pcs.getParamList();
if (pl == null) {
pl = new ParamList();
pcs.setParamList(pl);
}
pl.add(0, new Param(pname, Param.VAR, null));
pcs.getPgmNormalCell(row, col).setExpString("=" + pname);
if (mcount == -1) {
mcount = 1;
}
int pcount = args.length;
for (int i = 1; i <= mcount; ++i) {
ArrayList
© 2015 - 2024 Weber Informatics LLC | Privacy Policy