com.scudata.dm.op.Groups1Result 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.dm.op;
import com.scudata.array.IArray;
import com.scudata.array.IntArray;
import com.scudata.array.ObjectArray;
import com.scudata.common.MessageManager;
import com.scudata.common.ObjectCache;
import com.scudata.common.RQException;
import com.scudata.dm.BaseRecord;
import com.scudata.dm.ComputeStack;
import com.scudata.dm.Context;
import com.scudata.dm.Current;
import com.scudata.dm.DataStruct;
import com.scudata.dm.Env;
import com.scudata.dm.GroupsSyncReader;
import com.scudata.dm.ListBase1;
import com.scudata.dm.Sequence;
import com.scudata.dm.Table;
import com.scudata.dm.cursor.ICursor;
import com.scudata.expression.Expression;
import com.scudata.expression.Gather;
import com.scudata.expression.Node;
import com.scudata.resources.EngineMessage;
import com.scudata.util.HashUtil;
import com.scudata.util.Variant;
/**
* ???ڶ?????????????ִ?а????ֶν????ڴ???????????
* @author RunQian
*
*/
public class Groups1Result extends IGroupsResult {
private Expression gexp; // ?????ֶ?
private String gname; // ?????ֶ???
private Expression []calcExps; // ???ܱ???ʽ
private String []calcNames; // ?????ֶ???
private String opt; // ????ѡ??
private Context ctx; // ??????????
private HashUtil hashUtil; // ?ṩ??ϣ????Ĺ?ϣ??
private ListBase1 []groups; // ????????ֶεĻ???????ÿ???ֶζ?Ӧһ??λ?ã?ͨ????ϣ?????Ӧ??λ??
private Node[] gathers = null; // ͳ?Ʊ???ʽ?е?ͳ?ƺ???
private DataStruct ds; // ????????ݽṹ
private int valCount; // ?????ֶ???
private Table result; // ??????ܽ??
private BaseRecord prevRecord; // ??һ?????????¼
private SortedGroupsLink link; // ????hѡ??
private boolean oOpt;
private boolean iOpt;
private boolean nOpt;
private boolean hOpt;
private boolean eOpt;
/**
* ??ʼ??????
* @param gexp ???????ʽ
* @param gname ???????ʽ??
* @param calcExps ͳ?Ʊ???ʽ
* @param calcNames ͳ?Ʊ???ʽ??
* @param opt ????ѡ??
* @param ctx ?????ı???
*/
public Groups1Result(Expression gexp, String gname, Expression[] calcExps,
String[] calcNames, String opt, Context ctx) {
this(gexp, gname, calcExps, calcNames, opt, ctx, Env.getDefaultHashCapacity());
}
/**
* ??ʼ??????
* @param gexp ???????ʽ
* @param gname ???????ʽ??
* @param calcExps ͳ?Ʊ???ʽ
* @param calcNames ͳ?Ʊ???ʽ??
* @param opt ????ѡ??
* @param ctx ?????ı???
* @param capacity ?????ϣ????С
*/
public Groups1Result(Expression gexp, String gname, Expression[] calcExps,
String[] calcNames, String opt, Context ctx, int capacity) {
this.gexp = gexp;
this.gname = gname;
this.calcExps = calcExps;
this.calcNames = calcNames;
this.opt = opt;
this.ctx = ctx;
if (calcExps != null) {
gathers = Sequence.prepareGatherMethods(this.calcExps, ctx);
valCount = gathers.length;
}
// ?ϲ???????????ͳ???????????ɽ??????????
String[] colNames = new String[1 + valCount];
colNames[0] = gname;
if (calcNames != null) {
System.arraycopy(calcNames, 0, colNames, 1, valCount);
}
// ???ɽ???????ݽṹ
ds = new DataStruct(colNames);
ds.setPrimary(new String[]{gname});
// ???ú???ѡ??????ݺ???ѡ??ж??Ƿ???Ҫ??ϣ??
if (opt != null) {
if (opt.indexOf('o') != -1) {
oOpt = true;
} else if (opt.indexOf('i') != -1) {
iOpt = true;
} else if (opt.indexOf('n') != -1) {
nOpt = true;
} else if (opt.indexOf('h') != -1) {
hOpt = true;
}
if (valCount == 1 && opt.indexOf('e') != -1) eOpt = true;
}
if (hOpt) {
link = new SortedGroupsLink();
} else if (!oOpt && !iOpt && !nOpt) {
hashUtil = new HashUtil(capacity);
groups = new ListBase1[hashUtil.getCapacity()];
}
result = new Table(ds, 1024);
}
/**
* ȡ????????ݽṹ
* @return DataStruct
*/
public DataStruct getResultDataStruct() {
return ds;
}
/**
* ȡ???λ??ܺ????ڼ??????ս???ı???ʽ??avg???ܱ??ֳ?sum??count???н??м???
* @return
*/
public Expression[] getResultExpressions() {
return null;
}
/**
* ȡ???????ʽ
* @return ????ʽ????
*/
public Expression[] getExps() {
return new Expression[]{gexp};
}
/**
* ȡ?????ֶ???
* @return ?ֶ???????
*/
public String[] getNames() {
return new String[]{gname};
}
/**
* ȡ???ܱ???ʽ
* @return ????ʽ????
*/
public Expression[] getCalcExps() {
return calcExps;
}
/**
* ȡ?????ֶ???
* @return ?ֶ???????
*/
public String[] getCalcNames() {
return calcNames;
}
/**
* ȡѡ??
* @return
*/
public String getOption() {
return opt;
}
/**
* ȡ?Ƿ??????????
* @return true???ǣ????ݰ??????ֶ?????false??????
*/
public boolean isSortedGroup() {
return oOpt;
}
/**
* ȡ???λ??ܱ???ʽ?????ڶ??̷߳???
* @return
*/
public Expression[] getRegatherExpressions() {
if (valCount > 0) {
Expression []valExps = new Expression[valCount];
for (int i = 0, q = 2; i < valCount; ++i, ++q) {
Node gather = calcExps[i].getHome();
gather.prepare(ctx);
valExps[i] = gather.getRegatherExpression(q);
}
return valExps;
} else {
return null;
}
}
/**
* ȡ???λ??????ݽṹ
* @return DataStruct
*/
public DataStruct getRegatherDataStruct() {
return ds;
}
/**
* ????????ʱ??ȡ??ÿ???̵߳??м????????????Ҫ???ж??λ???
* @return Table
*/
public Table getTempResult() {
if (hashUtil != null) {
this.hashUtil = null;
this.groups = null;
} else if (nOpt) {
result.deleteNullFieldRecord(0);
} else if (hOpt) {
if (opt == null || opt.indexOf('u') == -1) {
result = link.toTable(ds);
}
link = null;
}
Table table = result;
prevRecord = null;
result = null;
if (table.length() > 0) {
if (valCount > 0) {
table.finishGather1(gathers);
}
return table;
} else {
return null;
}
}
/**
* ȡ??????ܽ??
* @return Table
*/
public Table getResultTable() {
if (hashUtil != null) {
if (opt == null || opt.indexOf('u') == -1) {
int []fields = new int[]{0};
result.sortFields(fields);
}
this.hashUtil = null;
this.groups = null;
} else if (nOpt) {
if (opt.indexOf('0') != -1) {
result.deleteNullFieldRecord(0);
} else {
int len = result.length();
IArray mems = result.getMems();
for (int i = 1; i <= len; ++i) {
BaseRecord r = (BaseRecord)mems.get(i);
if (r.getNormalFieldValue(0) == null) {
r.setNormalFieldValue(0, ObjectCache.getInteger(i));;
}
}
}
} else if (hOpt) {
if (opt == null || opt.indexOf('u') == -1) {
result = link.toTable(ds);
}
link = null;
}
Table table = result;
prevRecord = null;
result = null;
if (table.length() > 0) {
if (valCount > 0) {
table.finishGather(gathers);
}
if (!nOpt && opt != null && opt.indexOf('0') != -1) {
table.deleteNullFieldRecord(0);
}
if (eOpt) {
table = table.fieldValues(ds.getFieldCount() - 1).derive("o");
}
//table.trimToSize();
} else if (opt == null || opt.indexOf('t') == -1) {
table = null;
}
return table;
}
/**
* ???????ͽ???ʱ????
* @param ctx ??????????
*/
public void finish(Context ctx) {
}
/**
* ???????ͽ?????ȡ???յļ?????
* @return
*/
public Object result() {
return getResultTable();
}
/**
* ???????????????ݣ??ۻ??????յĽ????
* @param seq ????
* @param ctx ??????????
*/
public void push(Sequence table, Context ctx) {
if (table == null || table.length() == 0) return;
if (hashUtil != null) {
addGroups(table, ctx);
} else if (oOpt) {
addGroups_o(table, ctx);
} else if (iOpt) {
addGroups_i(table, ctx);
} else if (nOpt) {
addGroups_n(table, ctx);
} else if (hOpt) {
addGroups_h(table, ctx);
} else {
addGroups_1(table, ctx);
}
}
/**
* ?????????????α????ݣ??ۻ??????յĽ????
* @param cursor ?α?????
*/
public void push(ICursor cursor) {
Context ctx = this.ctx;
if (hashUtil != null) {
while (true) {
// ???α???ȡ??һ?????ݡ?
Sequence src = cursor.fuzzyFetch(ICursor.FETCHCOUNT);
if (src == null || src.length() == 0) break;
// ?????????ӵ????????࣬??ִ??ͳ?ƺ?????
addGroups(src, ctx);
}
} else if (oOpt) {
while (true) {
Sequence src = cursor.fuzzyFetch(ICursor.FETCHCOUNT);
if (src == null || src.length() == 0) break;
addGroups_o(src, ctx);
}
} else if (iOpt) {
while (true) {
Sequence src = cursor.fuzzyFetch(ICursor.FETCHCOUNT);
if (src == null || src.length() == 0) break;
addGroups_i(src, ctx);
}
} else if (nOpt) {
while (true) {
Sequence src = cursor.fuzzyFetch(ICursor.FETCHCOUNT);
if (src == null || src.length() == 0) break;
addGroups_n(src, ctx);
}
} else if (hOpt) {
while (true) {
Sequence src = cursor.fuzzyFetch(ICursor.FETCHCOUNT);
if (src == null || src.length() == 0) break;
addGroups_h(src, ctx);
}
} else {
while (true) {
Sequence src = cursor.fuzzyFetch(ICursor.FETCHCOUNT);
if (src == null || src.length() == 0) break;
addGroups_1(src, ctx);
}
}
}
// ??ϣ??????
private void addGroups(Sequence table, Context ctx) {
final int INIT_GROUPSIZE = HashUtil.getInitGroupSize();
HashUtil hashUtil = this.hashUtil;
ListBase1 []groups = this.groups;
Expression gexp = this.gexp;
int valCount = null == gathers ? 0 : gathers.length;
Node []gathers = this.gathers;
Table result = this.result;
Object key;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
key = gexp.calculate(ctx);
BaseRecord r;
int hash = hashUtil.hashCode(key);
if (groups[hash] == null) {
groups[hash] = new ListBase1(INIT_GROUPSIZE);
r = result.newLast();
r.setNormalFieldValue(0, key);
groups[hash].add(r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
int index = HashUtil.bsearch_r(groups[hash], key);
if (index < 1) {
r = result.newLast();
r.setNormalFieldValue(0, key);
groups[hash].add(-index, r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
r = (BaseRecord)groups[hash].get(index);
for (int f = 1; f <= valCount; ++f) {
Object val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
}
} finally {
stack.pop();
}
}
private void addGroups_1(Sequence table, Context ctx) {
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
int i = 1;
BaseRecord r = prevRecord;
int valCount = this.valCount;
Node []gathers = this.gathers;
try {
if (r == null) {
r = prevRecord = result.newLast();
current.setCurrent(1);
i++;
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v, val);
}
}
for (int len = table.length(); i <= len; ++i) {
current.setCurrent(i);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(r.getNormalFieldValue(v), ctx);
r.setNormalFieldValue(v, val);
}
}
} finally {
stack.pop();
}
}
private void addGroups_o(Sequence table, Context ctx) {
Table result = this.result;
BaseRecord r = prevRecord;
Expression gexp = this.gexp;
int valCount = this.valCount;
Node []gathers = this.gathers;
Object key;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
key = gexp.calculate(ctx);
if (r == null || Variant.compare(r.getNormalFieldValue(0), key, true) != 0) {
r = result.newLast();
r.setNormalFieldValue(0, key);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
for (int f = 1; f <= valCount; ++f) {
Object val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
} finally {
stack.pop();
}
prevRecord = r;
}
private void addGroups_i(Sequence table, Context ctx) {
Table result = this.result;
BaseRecord r = prevRecord;
Expression gexp = this.gexp;
int valCount = this.valCount;
Node []gathers = this.gathers;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
Object val = gexp.calculate(ctx);
if (Variant.isTrue(val) || r == null) {
r = result.newLast();
r.setNormalFieldValue(0, val);
for (int v = 0; v < valCount; ++v) {
val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
for (int f = 1; f <= valCount; ++f) {
val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
} finally {
stack.pop();
}
prevRecord = r;
}
/**
* ???÷???????@nѡ??ʹ??
* @param groupCount
*/
public void setGroupCount(int groupCount) {
result.insert(groupCount);
}
private void addGroups_n(Sequence table, Context ctx) {
Table result = this.result;
Expression gexp = this.gexp;
int valCount = this.valCount;
Node []gathers = this.gathers;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
Object obj = gexp.calculate(ctx);
if (!(obj instanceof Number)) {
MessageManager mm = EngineMessage.get();
throw new RQException("groups: " + mm.getMessage("engine.needIntExp"));
}
int index = ((Number)obj).intValue();
if (index < 1) {
// ????С??1?ķŹ???Ҫ?ˣ????ٱ????????ֵ??κ?һ????
continue;
}
BaseRecord r = result.getRecord(index);
if (r.getNormalFieldValue(0) == null) {
r.setNormalFieldValue(0, obj);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
for (int f = 1; f <= valCount; ++f) {
Object val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
} finally {
stack.pop();
}
}
private void addGroups_h(Sequence table, Context ctx) {
Expression gexp = this.gexp;
int valCount = this.valCount;
Node []gathers = this.gathers;
Table result = this.result;
SortedGroupsLink link = this.link;
Object key;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
key = gexp.calculate(ctx);
SortedGroupsLink.Node node = link.put(key);
BaseRecord r = node.getRecord();
if (r == null) {
r = result.newLast();
r.setNormalFieldValue(0, key);
node.setReocrd(r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
for (int f = 1; f <= valCount; ++f) {
Object val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
} finally {
stack.pop();
}
}
/**
* ??·????ʱ??????·?????????ϲ????ж??η?????ܣ??õ????յĻ??ܽ??
* @param results ????·?ķ????????ɵ?????
* @return ???յĻ??ܽ??
*/
public Object combineResult(Object []results) {
int count = results.length;
Sequence result = new Sequence();
for (int i = 0; i < count; ++i) {
if (results[i] instanceof Sequence) {
result.addAll((Sequence)results[i]);
}
}
// ??·?α갴?????ֶβ?ֵ?
if (opt != null && opt.indexOf('o') != -1) {
return result.derive("o");
}
int mcount = calcExps == null ? 0 : calcExps.length;
Expression []exps2 = new Expression[1];
exps2[0] = new Expression(ctx, "#1");
Expression []calcExps2 = null;
if (mcount > 0) {
calcExps2 = new Expression[mcount];
for (int i = 0, q = 2; i < mcount; ++i, ++q) {
Gather gather = (Gather)calcExps[i].getHome();
gather.prepare(ctx);
calcExps2[i] = gather.getRegatherExpression(q);
}
}
return result.groups(exps2, new String[]{gname}, calcExps2, calcNames, opt, ctx);
}
//????ʵ??@z
public void push(GroupsSyncReader reader, int hashStart, int hashEnd) {
Context ctx = this.ctx;
int index = 1;
while (true) {
Object[] objs = reader.getData(index++);
if (objs == null) {
break;
}
addGroups_z((Sequence)objs[0], objs[1], (IntArray)objs[2], hashStart, hashEnd, ctx);
}
}
//????ʵ??@z
public void push(Sequence table, Object key, IntArray hashValue, int hashStart, int hashEnd) {
addGroups_z(table, key, hashStart, hashEnd, ctx);
}
// ??ϣ??????
private void addGroups_z(Sequence table, Object obj, IntArray hashValue, int hashStart, int hashEnd, Context ctx) {
final int INIT_GROUPSIZE = HashUtil.getInitGroupSize();
//HashUtil hashUtil = (HashUtil) obj;
ObjectArray keyArray = (ObjectArray) obj;
ListBase1 []groups = this.groups;
//Expression gexp = this.gexp;
int valCount = null == gathers ? 0 : gathers.length;
Node []gathers = this.gathers;
Table result = this.result;
Object key;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
//key = gexp.calculate(ctx);
key = keyArray.get(i);
int hash = hashValue.getInt(i);
BaseRecord r;
if ((hash % hashEnd) != hashStart) continue;
if (groups[hash] == null) {
groups[hash] = new ListBase1(INIT_GROUPSIZE);
r = result.newLast();
r.setNormalFieldValue(0, key);
groups[hash].add(r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
int index = HashUtil.bsearch_r(groups[hash], key);
if (index < 1) {
r = result.newLast();
r.setNormalFieldValue(0, key);
groups[hash].add(-index, r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
r = (BaseRecord)groups[hash].get(index);
for (int f = 1; f <= valCount; ++f) {
Object val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
}
} finally {
stack.pop();
}
}
// ??ϣ??????
private void addGroups_z(Sequence table, Object obj, int hashStart, int hashEnd, Context ctx) {
final int INIT_GROUPSIZE = HashUtil.getInitGroupSize();
HashUtil hashUtil = (HashUtil) obj;
ListBase1 []groups = this.groups;
Expression gexp = this.gexp;
int valCount = null == gathers ? 0 : gathers.length;
Node []gathers = this.gathers;
Table result = this.result;
Object key;
ComputeStack stack = ctx.getComputeStack();
Current current = new Current(table);
stack.push(current);
try {
for (int i = 1, len = table.length(); i <= len; ++i) {
current.setCurrent(i);
key = gexp.calculate(ctx);
BaseRecord r;
int hash = hashUtil.hashCode(key);
if ((hash % hashEnd) != hashStart) continue;
if (groups[hash] == null) {
groups[hash] = new ListBase1(INIT_GROUPSIZE);
r = result.newLast();
r.setNormalFieldValue(0, key);
groups[hash].add(r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
int index = HashUtil.bsearch_r(groups[hash], key);
if (index < 1) {
r = result.newLast();
r.setNormalFieldValue(0, key);
groups[hash].add(-index, r);
for (int v = 0; v < valCount; ++v) {
Object val = gathers[v].gather(ctx);
r.setNormalFieldValue(v + 1, val);
}
} else {
r = (BaseRecord)groups[hash].get(index);
for (int f = 1; f <= valCount; ++f) {
Object val = gathers[f - 1].gather(r.getNormalFieldValue(f), ctx);
r.setNormalFieldValue(f, val);
}
}
}
}
} finally {
stack.pop();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy