
com.scudata.dw.JoinCursor2 Maven / Gradle / Ivy
package com.scudata.dw;
import java.util.ArrayList;
import com.scudata.array.IArray;
import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.dm.BaseRecord;
import com.scudata.dm.Context;
import com.scudata.dm.DataStruct;
import com.scudata.dm.Record;
import com.scudata.dm.Sequence;
import com.scudata.dm.Table;
import com.scudata.dm.cursor.ICursor;
import com.scudata.dm.cursor.MultipathCursors;
import com.scudata.dm.op.Switch;
import com.scudata.expression.Expression;
import com.scudata.expression.FieldRef;
import com.scudata.expression.Function;
import com.scudata.expression.IParam;
import com.scudata.expression.Moves;
import com.scudata.expression.Node;
import com.scudata.expression.ParamInfo2;
import com.scudata.expression.UnknownSymbol;
import com.scudata.expression.mfn.sequence.Avg;
import com.scudata.expression.mfn.sequence.Count;
import com.scudata.expression.mfn.sequence.Max;
import com.scudata.expression.mfn.sequence.Min;
import com.scudata.expression.mfn.sequence.New;
import com.scudata.expression.mfn.sequence.Sum;
import com.scudata.parallel.ClusterPhyTable;
import com.scudata.resources.EngineMessage;
import com.scudata.util.Variant;
/**
* ????T.new T.derive T.news?Ľ?????α? (T???д桢?в?????????ʱ)
* @author runqian
*
*/
public class JoinCursor2 extends ICursor {
private boolean isClosed;
private boolean isNew;
private boolean isNews;
private DataStruct ds;
private ICursor cursor1;//T???α?
private Sequence cache1;
private ICursor cursor2;//A/cs
//private String[] csNames;//A/cs:K??K??????ָ??A/cs???????ӵ??ֶ?
private Sequence cache2;
private int cur1 = -1;
private int cur2 = -1;
private int keyCount;
private int csFieldsCount;//A/cs???ֶθ???
private int []keyIndex2;//A/cs???????±?
private int []fieldIndex2;//A/csȡ???ֶε??±?
private int []fieldIndex1;//Tȡ???ֶε??±?
private boolean hasExps;//
private Node nodes[];
private boolean hasR;
/**
*
* @param table
* @param exps
* @param fields
* @param cursor2
* @param opt 0:derive; 1:new; 2:news
* @param ctx
*/
public JoinCursor2(Object table, Expression []exps, String []fields, ICursor cursor2, String[] csNames, Expression filter,
String []fkNames, Sequence []codes, String[] opts, int opt, String option, Context ctx) {
this.isNew = opt == 1;
this.isNews = opt == 2;
this.ctx = ctx;
if (ctx != null) {
ctx.addResource(this);
}
hasR = option != null && option.indexOf("r") != -1;
String []keyNames;
if (table instanceof IPhyTable) {
keyNames = ((IPhyTable) table).getAllSortedColNames();
} else {
keyNames = ((ClusterPhyTable) table).getAllSortedColNames();
}
this.cursor2 = cursor2;
//this.csNames = csNames;
Sequence seq = cursor2.peek(1);
if (seq == null) {
isClosed = true;
return;
}
DataStruct ds2 = ((Record) seq.get(1)).dataStruct();
String []joinNames = keyNames;//join?ֶΣ?Ĭ??ȡT??????
if (isNew) {
//newʱ????T??????
if (joinNames == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("ds.lessKey"));
}
keyCount = joinNames.length;
keyIndex2 = new int[keyCount];
if (csNames == null) {
for (int i = 0; i < keyCount; i++) {
keyIndex2[i] = i;
}
} else {
if (csNames.length > keyCount) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("ds.lessKey"));
}
for (int i = 0; i < keyCount; i++) {
keyIndex2[i] = ds2.getFieldIndex(csNames[i]);
}
}
} else {
//newsʱȡcs??????
//1.?õ?cs???????±?
if (csNames == null) {
keyIndex2 = ds2.getPKIndex();
} else {
int csNamesLen = csNames.length;
keyIndex2 = new int[csNamesLen];
for (int i = 0; i < csNamesLen; i++) {
keyIndex2[i] = ds2.getFieldIndex(csNames[i]);
}
}
if (keyIndex2 == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("ds.lessKey"));
}
keyCount = keyIndex2.length;
//2.ȡTǰ????ֶ?
joinNames = new String[keyCount];//??ʱ????T??????
String[] allNames;
if (table instanceof IPhyTable) {
allNames = ((IPhyTable) table).getAllColNames();
} else {
allNames = ((ClusterPhyTable) table).getAllColNames();
}
for (int i = 0; i < keyCount; i++) {
joinNames[i] = allNames[i];
}
}
ArrayList keyList = new ArrayList();//??ʱʹ??
for (int i = 0; i < keyCount; i++) {
keyList.add(keyNames[i]);
}
//????????ʽ??exps???????{????}
ArrayList fetchExps = new ArrayList();
for (int i = 0, len = exps.length; i < len; i++) {
Expression exp = exps[i];
if (exp == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("Expression.missingParam"));
}
if (fields[i] == null) {
fields[i] = exps[i].getFieldName();
}
Node home = exp.getHome();
if (home instanceof UnknownSymbol) {
String f = exp.getFieldName();
if (!keyList.contains(f) && ds2.getFieldIndex(f) < 0)
fetchExps.add(exp);
} else {
hasExps = true;
if (home instanceof Moves) {
IParam fieldParam = ((Moves) exp.getHome()).getParam();
ParamInfo2 pi = ParamInfo2.parse(fieldParam, "cursor", false, false);
String []subFields = pi.getExpressionStrs1();
for (String f : subFields) {
if (!keyList.contains(f))
fetchExps.add(new Expression(f));
}
} else if (home instanceof com.scudata.expression.fn.gather.Top) {
IParam fieldParam = ((com.scudata.expression.fn.gather.Top) exp.getHome()).getParam();
if (fieldParam != null) {
if (!fieldParam.isLeaf()) {
IParam sub1 = fieldParam.getSub(1);
if (!keyList.contains(sub1.getLeafExpression().getFieldName()))
fetchExps.add(sub1.getLeafExpression());
}
}
} else {
String field = ((Function)home).getParamString();
if (!keyList.contains(field) && ds2.getFieldIndex(field) < 0)
fetchExps.add(new Expression(field));
}
}
}
Expression []allExps;
allExps = new Expression[keyCount + fetchExps.size()];
int i = 0;
for (; i < keyCount; i++) {
allExps[i] = new Expression(keyNames[i]);
}
for (Expression exp : fetchExps) {
allExps[i++] = exp;
}
if (hasExps) {
int len = exps.length;
nodes = new Node[len];
for (i = 0; i < len; i++) {
nodes[i] = parseNode(exps[i], ctx);
}
}
if (table instanceof IPhyTable) {
this.cursor1 = ((IPhyTable) table).cursor(allExps, null, filter, null, null, null, null, ctx);
}
if (isNew || isNews) {
ds = new DataStruct(fields);
} else {
csFieldsCount = ds2.getFieldCount();
String[] fieldNames = new String[csFieldsCount + fields.length];
System.arraycopy(ds2.getFieldNames(), 0, fieldNames, 0, csFieldsCount);
System.arraycopy(fields, 0, fieldNames, csFieldsCount, fields.length);
ds = new DataStruct(fieldNames);
}
int len = exps.length;
fieldIndex1 = new int[len];
fieldIndex2 = new int[len];
DataStruct ds1 = cursor1.getDataStruct();
for (i = 0; i < len; i++) {
fieldIndex1[i] = ds1.getFieldIndex(exps[i].getIdentifierName());
fieldIndex2[i] = ds2.getFieldIndex(exps[i].getIdentifierName());
}
init();
if (fkNames != null) {
int fkCount = fkNames.length;
for (int j = 0; j < fkCount; j++) {
String[] fkn = new String[] {fkNames[j]};
Sequence[] code = new Sequence[] {codes[j]};
String _opt = null;
Expression _exps[] = null;
if (opts[j] != null && opts[j].indexOf("#") != -1) {
_exps = new Expression[] {new Expression("#")};
} else if (opts[j] != null && opts[j].indexOf("null") != -1) {
_opt = "d";
} else {
_opt = "i";
}
Switch op = new Switch(fkn, code, _exps, _opt);
addOperation(op, ctx);
}
}
}
public JoinCursor2(ICursor cursor1, ICursor cursor2, Context ctx) {
this.cursor1 = cursor1;
this.cursor2 = cursor2;
this.ctx = ctx;
}
void init() {
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
return;
}
cur1 = 1;
}
public static MultipathCursors makeMultiJoinCursor(Object table, Expression []exps, String []fields, MultipathCursors cursor2,
String[] csNames, Expression filter, String []fkNames, Sequence []codes, String[] opts, int opt, String option, Context ctx) {
boolean isNew = opt == 1;
boolean isNews = opt == 2;
boolean hasExps = false;
int csFieldsCount = 0;
DataStruct ds;
int []fieldIndex1 = null;
String []keyNames;
if (table instanceof IPhyTable) {
keyNames = ((IPhyTable) table).getAllSortedColNames();
} else {
keyNames = ((ClusterPhyTable) table).getAllSortedColNames();
}
DataStruct ds2 = (cursor2.getCursors()[0]).getDataStruct();
int []keyIndex2;
int keyCount;
String []joinNames = keyNames;//join?ֶΣ?Ĭ??ȡT??????
if (isNew) {
//newʱ????T??????
if (joinNames == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("ds.lessKey"));
}
keyCount = joinNames.length;
keyIndex2 = new int[keyCount];
if (csNames == null) {
for (int i = 0; i < keyCount; i++) {
keyIndex2[i] = i;
}
} else {
if (csNames.length > keyCount) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("ds.lessKey"));
}
for (int i = 0; i < keyCount; i++) {
keyIndex2[i] = ds2.getFieldIndex(csNames[i]);
}
}
} else {
//newsʱȡcs??????
//1.?õ?cs???????±?
if (csNames == null) {
keyIndex2 = ds2.getPKIndex();
} else {
int csNamesLen = csNames.length;
keyIndex2 = new int[csNamesLen];
for (int i = 0; i < csNamesLen; i++) {
keyIndex2[i] = ds2.getFieldIndex(csNames[i]);
}
}
if (keyIndex2 == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("ds.lessKey"));
}
keyCount = keyIndex2.length;
//2.ȡTǰ????ֶ?
joinNames = new String[keyCount];//??ʱ????T??????
String[] allNames;
if (table instanceof IPhyTable) {
allNames = ((IPhyTable) table).getAllColNames();
} else {
allNames = ((ClusterPhyTable) table).getAllColNames();
}
for (int i = 0; i < keyCount; i++) {
joinNames[i] = allNames[i];
}
}
ArrayList keyList = new ArrayList();//??ʱʹ??
for (int i = 0; i < keyCount; i++) {
keyList.add(keyNames[i]);
}
//????????ʽ??exps???????{????}
ArrayList fetchExps = new ArrayList();
for (int i = 0, len = exps.length; i < len; i++) {
Expression exp = exps[i];
if (exp == null) {
MessageManager mm = EngineMessage.get();
throw new RQException(mm.getMessage("Expression.missingParam"));
}
if (fields[i] == null) {
fields[i] = exps[i].getFieldName();
}
Node home = exp.getHome();
if (home instanceof UnknownSymbol) {
if (!keyList.contains(exp.getFieldName()))
fetchExps.add(exp);
} else {
hasExps = true;
isNews = false;//?б???ʽʱ??????news
if (home instanceof Moves) {
IParam fieldParam = ((Moves) exp.getHome()).getParam();
ParamInfo2 pi = ParamInfo2.parse(fieldParam, "cursor", false, false);
String []subFields = pi.getExpressionStrs1();
for (String f : subFields) {
if (!keyList.contains(f))
fetchExps.add(new Expression(f));
}
} else if (home instanceof com.scudata.expression.fn.gather.Top) {
IParam fieldParam = ((com.scudata.expression.fn.gather.Top) exp.getHome()).getParam();
if (fieldParam != null) {
if (!fieldParam.isLeaf()) {
IParam sub1 = fieldParam.getSub(1);
if (!keyList.contains(sub1.getLeafExpression().getFieldName()))
fetchExps.add(sub1.getLeafExpression());
}
}
} else {
String field = ((Function)home).getParamString();
if (!keyList.contains(field))
fetchExps.add(new Expression(field));
}
}
}
Expression []allExps;
allExps = new Expression[keyCount + fetchExps.size()];
int i = 0;
for (; i < keyCount; i++) {
allExps[i] = new Expression(keyNames[i]);
}
for (Expression exp : fetchExps) {
allExps[i++] = exp;
}
Node nodes[] = null;
if (hasExps) {
int len = exps.length;
nodes = new Node[len];
for (i = 0; i < len; i++) {
nodes[i] = parseNode(exps[i], ctx);
}
}
String[] allExpNames = new String[allExps.length];
for (i = 0; i < allExpNames.length; i++) {
allExpNames[i] = allExps[i].toString();
}
ICursor cursor1 = null;
if (table instanceof IPhyTable) {
Expression w = null;
if (filter != null) {
w = filter.newExpression(ctx); // ?ֶβ??ж?ȡʱ??Ҫ???Ʊ???ʽ??ͬһ??????ʽ??֧?ֲ???????
}
cursor1 = ((IPhyTable) table).cursor(null, allExpNames, w, null, null, null, cursor2, null, ctx);
}
if (isNew || isNews) {
ds = new DataStruct(fields);
} else {
csFieldsCount = ds2.getFieldCount();
String[] fieldNames = new String[csFieldsCount + fields.length];
System.arraycopy(ds2.getFieldNames(), 0, fieldNames, 0, csFieldsCount);
System.arraycopy(fields, 0, fieldNames, csFieldsCount, fields.length);
ds = new DataStruct(fieldNames);
}
if (!hasExps) {
int len = exps.length;
fieldIndex1 = new int[len];
for (i = 0; i < len; i++) {
fieldIndex1[i] = cursor1.getDataStruct().getFieldIndex(fields[i]);
}
}
int len = cursor2.getPathCount();
ICursor cursors1[] = ((MultipathCursors) cursor1).getParallelCursors();
ICursor cursors2[] = cursor2.getParallelCursors();
ICursor cursors[] = new ICursor[len];
boolean hasR = option != null && option.indexOf("r") != -1;
for (i = 0; i < len; i++) {
JoinCursor2 cs = new JoinCursor2(cursors1[i], cursors2[i], ctx);
cs.ds = ds;
cs.isNew = opt == 1;
cs.isNews = opt == 2;
cs.hasExps = hasExps;
cs.csFieldsCount = csFieldsCount;
cs.fieldIndex1 = fieldIndex1;
cs.keyIndex2 = keyIndex2;
cs.keyCount = keyCount;
cs.nodes = nodes;
cs.hasR = hasR;
cs.init();
if (fkNames != null) {
int fkCount = fkNames.length;
for (int j = 0; j < fkCount; j++) {
String[] fkn = new String[] {fkNames[j]};
Sequence[] code = new Sequence[] {codes[j]};
String _opt = null;
Expression _exps[] = null;
if (opts[j] != null && opts[j].indexOf("#") != -1) {
_exps = new Expression[] {new Expression("#")};
} else if (opts[j] != null && opts[j].indexOf("null") != -1) {
_opt = "d";
} else {
_opt = "i";
}
Switch op = new Switch(fkn, code, _exps, _opt);
cs.addOperation(op, ctx);
}
}
cursors[i] = cs;
}
return new MultipathCursors(cursors, ctx);
}
protected Sequence get(int n) {
if (isClosed || n < 1) {
return null;
}
if (isNews) {
return getDataForNews(n);
}
if (hasExps) {
return getDataForNew(n);
}
int keyCount = this.keyCount;
int csFieldsCount = this.csFieldsCount;
int len = isNew ? ds.getFieldCount() : ds.getFieldCount() - csFieldsCount;
if (cache2 == null || cache2.length() == 0) {
cache2 = cursor2.fetch(n);
cur2 = 1;
}
int cur1 = this.cur1;
int cur2 = this.cur2;
Sequence cache1 = this.cache1;
Sequence cache2 = this.cache2;
IArray mems1 = cache1.getMems();
IArray mems2 = cache2.getMems();
int len1 = cache1.length();
int len2 = cache2.length();
int []fieldIndex1 = this.fieldIndex1;
int []fieldIndex2 = this.fieldIndex2;
int []keyIndex2 = this.keyIndex2;
boolean isNew = this.isNew;
boolean isNews = this.isNews;
ICursor cursor1 = this.cursor1;
ICursor cursor2 = this.cursor2;
Table newTable;
if (n > INITSIZE) {
newTable = new Table(ds, INITSIZE);
} else {
newTable = new Table(ds, n);
}
Object []keys2 = new Object[keyCount];
while (true) {
Record record1 = (Record) mems1.get(cur1);
Record record2 = (Record) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
Object []keys1 = record1.getFieldValues();
int cmp = Variant.compareArrays(keys2, keys1);
if (cmp == 0) {
cur1++;
if (!isNews) {
cur2++;
}
BaseRecord record = newTable.newLast();
Object [] objs2 = record2.getFieldValues();
if (isNew || isNews) {
for (int i = 0; i < len; i++) {
int idx = fieldIndex1[i];
if (idx >= 0) {
record.setNormalFieldValue(i, keys1[idx]);
}
else {
idx = fieldIndex2[i];
record.setNormalFieldValue(i, objs2[idx]);
}
}
} else {
Object []vals = record2.getFieldValues();
System.arraycopy(vals, 0, record.getFieldValues(), 0, csFieldsCount);
for (int i = 0; i < len; i++) {
record.setNormalFieldValue(i + csFieldsCount, keys1[fieldIndex1[i]]);
}
}
} else if (cmp > 0) {
cur1++;
} else if (cmp < 0) {
cur2++;
}
if (cur1 > len1) {
cur1 = 1;
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
break;
}
mems1 = cache1.getMems();
len1 = cache1.length();
}
if (cur2 > len2) {
cur2 = 1;
cache2 = cursor2.fetch(n - newTable.length());
if (cache2 == null || cache2.length() == 0) {
isClosed = true;
break;
}
mems2 = cache2.getMems();
len2 = cache2.length();
}
if (newTable.length() == n) {
break;
}
}
this.cache1 = cache1;
this.cache2 = cache2;
this.cur1 = cur1;
this.cur2 = cur2;
if (newTable.length() > 0) {
return newTable;
} else {
return null;
}
}
protected long skipOver(long n) {
Sequence data;
long rest = n;
long count = 0;
while (rest != 0) {
if (rest > FETCHCOUNT) {
data = get(FETCHCOUNT);
} else {
data = get((int)rest);
}
if (data == null) {
break;
} else {
count += data.length();
}
rest -= data.length();
}
return count;
}
public void close() {
super.close();
isClosed = true;
cache1 = null;
cache2 = null;
cursor1.close();
cursor2.close();
}
public boolean reset() {
close();
if (!cursor1.reset() || !cursor2.reset()) {
return false;
} else {
isClosed = false;
cur1 = -1;
cur2 = -1;
return true;
}
}
/**
* ?б???ʽʱȡ????
* @param n
* @return
*/
protected Sequence getData(int n) {
if (isClosed || n < 1) {
return null;
}
Node nodes[] = this.nodes;
int keyCount = this.keyCount;
int csFieldsCount = this.csFieldsCount;
int len = isNew ? ds.getFieldCount() : ds.getFieldCount() - csFieldsCount;
if (cache2 == null || cache2.length() == 0) {
cache2 = cursor2.fetch(n);
cur2 = 1;
}
int cur2 = this.cur2;
Sequence cache2 = this.cache2;
Table newTable;
if (n > INITSIZE) {
newTable = new Table(ds, INITSIZE);
} else {
newTable = new Table(ds, n);
}
int keysIndex[] = new int[keyCount];
for (int i = 0; i < keyCount; i++) {
keysIndex[i] = i;
}
while (true) {
Sequence seq1 = cursor1.fetchGroup(keysIndex);
if (seq1 == null || seq1.length() == 0) {
isClosed = true;
break;
}
Record record1 = (Record) seq1.get(1);
Record record2 = (Record) cache2.get(cur2);
Object []keys2 = new Object[keyCount];
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
Object []keys1 = record1.getFieldValues();
int cmp = Variant.compareArrays(keys2, keys1);
if (cmp == 0) {
cur2++;
BaseRecord record = newTable.newLast();
if (isNew) {
for (int i = 0; i < len; i++) {
//record.setNormalFieldValue(i, keys1[i + keyCount]);
Node node = nodes[i];
if (node instanceof FieldRef) {
node.setDotLeftObject(seq1.get(1));
} else {
node.setDotLeftObject(seq1);
}
record.setNormalFieldValue(i, node.calculate(ctx));
}
} else {
Object []vals = record2.getFieldValues();
System.arraycopy(vals, 0, record.getFieldValues(), 0, csFieldsCount);
for (int i = 0; i < len; i++) {
Node node = nodes[i];
if (node instanceof FieldRef) {
node.setDotLeftObject(seq1.get(1));
} else {
node.setDotLeftObject(seq1);
}
record.setNormalFieldValue(i + csFieldsCount, node.calculate(ctx));
}
}
} else if (cmp > 0) {
} else if (cmp < 0) {
cur2++;
}
if (cur2 > cache2.length()) {
cur2 = 1;
cache2 = cursor2.fetch(n - newTable.length());
if (cache2 == null || cache2.length() == 0) {
isClosed = true;
break;
}
}
if (newTable.length() == n) {
break;
}
}
this.cache2 = cache2;
this.cur2 = cur2;
if (newTable.length() > 0) {
return newTable;
} else {
return null;
}
}
//?б???ʽ
private Sequence getDataForNew(int n) {
if (isClosed || n < 1) {
return null;
}
int keyCount = this.keyCount;
int len = ds.getFieldCount();
Object []keys2 = new Object[keyCount];
//ȡ????һ??cs??????
if (cache2 == null || cache2.length() == 0) {
cache2 = cursor2.fetch(ICursor.FETCHCOUNT);
cur2 = 1;
BaseRecord record2 = (BaseRecord) cache2.get(1);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
}
int cur1 = this.cur1;
Sequence cache1 = this.cache1;
int len1 = this.cache1.length();
IArray mems1 = cache1.getMems();
int cur2 = this.cur2;
Sequence cache2 = this.cache2;
IArray mems2 = cache2.getMems();
int len2 = cache2.length();
int []keyIndex2 = this.keyIndex2;
ICursor cursor2 = this.cursor2;
Table newTable;
if (n > INITSIZE) {
newTable = new Table(ds, INITSIZE);
} else {
newTable = new Table(ds, n);
}
Table tempTable = new Table(cache2.dataStruct());//???ڻ???
while (true) {
BaseRecord record1 = (BaseRecord) mems1.get(cur1);
BaseRecord record2 = (BaseRecord) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
Object []keys1 = record1.getFieldValues();
int cmp = Variant.compareArrays(keys2, keys1);
if (cmp == 0) {
//????һ????????ʱ????table
tempTable.add(record2);
cur2++;
if (cur2 > len2) {
cur2 = 1;
cache2 = cursor2.fetch(ICursor.FETCHCOUNT);
if (cache2 == null || cache2.length() == 0) {
isClosed = true;
break;
}
mems2 = cache2.getMems();
len2 = cache2.length();
}
record2 = (BaseRecord) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
if (0 != Variant.compareArrays(keys2, keys1)) {
//???????ȣ???ʾ??һ??ȡ???ˣ???????ʱ????????
BaseRecord record = newTable.newLast();
calcExpsForNew(record, tempTable, record1, len);
//ȡ????һ????????????
cur1++;
if (cur1 > len1) {
cur1 = 1;
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
break;
}
mems1 = cache1.getMems();
len1 = cache1.length();
}
}
} else if (cmp > 0) {
//ȡ????һ????????????
cur1++;
if (cur1 > len1) {
cur1 = 1;
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
break;
}
mems1 = cache1.getMems();
len1 = cache1.length();
}
} else if (cmp < 0) {
cur2++;
if (cur2 > len2) {
cur2 = 1;
cache2 = cursor2.fetch(ICursor.FETCHCOUNT);
if (cache2 == null || cache2.length() == 0) {
isClosed = true;
break;
}
mems2 = cache2.getMems();
len2 = cache2.length();
}
record2 = (BaseRecord) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
}
if (newTable.length() == n) {
break;
}
}
BaseRecord record1 = (BaseRecord) mems1.get(cur1);
if (isClosed && tempTable != null && tempTable.length() != 0) {
//???????ȣ???ʾ??һ??ȡ???ˣ???????ʱ????????
BaseRecord record = newTable.newLast();
calcExpsForNew(record, tempTable, record1, len);
}
this.cache1 = cache1;
this.cache2 = cache2;
this.cur1 = cur1;
this.cur2 = cur2;
if (newTable.length() > 0) {
return newTable;
} else {
return null;
}
}
/**
* T.news??ȡ??
* @param n
* @return
*/
private Sequence getDataForNews(int n) {
if (isClosed || n < 1) {
return null;
}
int keyCount = this.keyCount;
int len = ds.getFieldCount();
Object []keys2 = new Object[keyCount];
//Object []keys1 = this.keys1;
if (cache2 == null || cache2.length() == 0) {
cache2 = cursor2.fetch(ICursor.FETCHCOUNT);
cur2 = 1;
BaseRecord record2 = (BaseRecord) cache2.get(1);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
}
int cur1 = this.cur1;
Sequence cache1 = this.cache1;
int len1 = this.cache1.length();
IArray mems1 = cache1.getMems();
int cur2 = this.cur2;
Sequence cache2 = this.cache2;
IArray mems2 = cache2.getMems();
int len2 = cache2.length();
int []fieldIndex1 = this.fieldIndex1;
int []fieldIndex2 = this.fieldIndex2;
int []keyIndex2 = this.keyIndex2;
boolean hasR = this.hasR;
boolean hasExps = this.hasExps;
ICursor cursor2 = this.cursor2;
Table newTable;
if (n > INITSIZE) {
newTable = new Table(ds, INITSIZE);
} else {
newTable = new Table(ds, n);
}
Table tempTable = new Table(cache1.dataStruct());//???ڻ???
BaseRecord record1 = (BaseRecord) mems1.get(cur1);
BaseRecord record2 = (BaseRecord) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
Object []keys1 = record1.getFieldValues();
while (true) {
int cmp = Variant.compareArrays(keys2, keys1);
if (cmp == 0) {
BaseRecord record = newTable.newLast();
if (hasExps) {
tempTable.newLast(keys1);//???ӵ???ʱ????
} else {
for (int i = 0; i < len; i++) {
int idx = fieldIndex1[i];
if (idx < 0)
record.setNormalFieldValue(i, record2.getFieldValue(fieldIndex2[i]));
else
record.setNormalFieldValue(i, keys1[idx]);
}
}
cur1++;
if (cur1 > len1) {
cur1 = 1;
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
break;
}
mems1 = cache1.getMems();
len1 = cache1.length();
}
record1 = (BaseRecord) mems1.get(cur1);
keys1 = record1.getFieldValues();
if (hasR) {
if (hasExps) {
//????һ??ȡ??
while(Variant.compareArrays(keys2, keys1) == 0) {
record1 = (BaseRecord) mems1.get(cur1);
keys1 = record1.getFieldValues();
tempTable.newLast(keys1);//???ӵ???ʱ????
cur1++;
if (cur1 > len1) {
cur1 = 1;
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
break;
}
mems1 = cache1.getMems();
len1 = cache1.length();
}
record1 = (BaseRecord) mems1.get(cur1);
keys1 = record1.getFieldValues();
}
calcExpsForNews(record, tempTable, record2, len);
}
//????cs????
cur2++;
if (cur2 > len2) {
cur2 = 1;
cache2 = cursor2.fetch(ICursor.FETCHCOUNT);
if (cache2 == null || cache2.length() == 0) {
isClosed = true;
break;
}
mems2 = cache2.getMems();
len2 = cache2.length();
}
record2 = (BaseRecord) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
}
} else if (cmp > 0) {
cur1++;
if (cur1 > len1) {
cur1 = 1;
cache1 = cursor1.fetch(FETCHCOUNT);
if (cache1 == null || cache1.length() == 0) {
isClosed = true;
break;
}
mems1 = cache1.getMems();
len1 = cache1.length();
}
record1 = (BaseRecord) mems1.get(cur1);
keys1 = record1.getFieldValues();
} else if (cmp < 0) {
cur2++;
if (cur2 > len2) {
cur2 = 1;
cache2 = cursor2.fetch(ICursor.FETCHCOUNT);
if (cache2 == null || cache2.length() == 0) {
isClosed = true;
break;
}
mems2 = cache2.getMems();
len2 = cache2.length();
}
record2 = (BaseRecord) mems2.get(cur2);
for (int i = 0; i < keyCount; i++) {
keys2[i] = record2.getFieldValue(keyIndex2[i]);
}
}
if (newTable.length() >= n) {
break;
}
}
this.cache1 = cache1;
this.cache2 = cache2;
this.cur1 = cur1;
this.cur2 = cur2;
if (newTable.length() > 0) {
return newTable;
} else {
return null;
}
}
/**
* ??????????¼???Լ?ͬ?????ݣ????????ʽ
* @param record
* @param tempTable ??????ͬ??һ??????
* @param r
* @param len
*/
private void calcExpsForNew(BaseRecord record, Table tempTable, BaseRecord r, int len) {
Node nodes[] = this.nodes;
int fieldIndex2[] = this.fieldIndex2;
for (int i = 0; i < len; i++) {
Node node = nodes[i];
if (node instanceof FieldRef) {
if (fieldIndex2[i] < 0) {
node.setDotLeftObject(r);
} else {
node.setDotLeftObject(tempTable.get(1));
}
} else {
node.setDotLeftObject(tempTable);
}
record.setNormalFieldValue(i, node.calculate(ctx));
}
tempTable.clear();
}
private void calcExpsForNews(BaseRecord record, Table tempTable, BaseRecord r, int len) {
Node nodes[] = this.nodes;
for (int i = 0; i < len; i++) {
Node node = nodes[i];
if (node instanceof FieldRef) {
node.setDotLeftObject(r);
} else {
node.setDotLeftObject(tempTable);
}
record.setNormalFieldValue(i, node.calculate(ctx));
}
tempTable.clear();
}
private static Node parseNode(Expression exp, Context ctx) {
Node home = exp.getHome();
Node node = null;
if (home instanceof Moves) {
node = new New();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
} else if (home instanceof UnknownSymbol) {
node = new FieldRef(exp.getFieldName());
} else if (home instanceof Function) {
String fname = ((Function)home).getFunctionName();
if (fname.equals("sum")) {
node = new Sum();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
} else if (fname.equals("count")) {
node = new Count();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
} else if (fname.equals("min")) {
node = new Min();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
} else if (fname.equals("max")) {
node = new Max();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
} else if (fname.equals("avg")) {
node = new Avg();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
} else if (fname.equals("top")) {
node = new com.scudata.expression.mfn.sequence.Top();
((Function) node).setParameter(null, ctx, ((Function)exp.getHome()).getParamString());
}
}
return node;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy