com.scudata.dm.cursor.JoinxCursor_u 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.cursor;
import com.scudata.dm.ComputeStack;
import com.scudata.dm.Context;
import com.scudata.dm.Current;
import com.scudata.dm.DataStruct;
import com.scudata.dm.ListBase1;
import com.scudata.dm.Sequence;
import com.scudata.dm.Table;
import com.scudata.dm.op.Operation;
import com.scudata.expression.Expression;
import com.scudata.util.CursorUtil;
import com.scudata.util.HashUtil;
/**
* ?????α????????ڴ???????????
* joinx@u(csi:Fi,xj,..;P:Fi,xj,..;??)
* @author RunQian
*
*/
public class JoinxCursor_u extends ICursor {
private ICursor cursor; // ?α?
private Expression[] exps; // ????????ʽ
private DataStruct ds; // ????????ݽṹ
private int type = 0; // 0:JOIN, 1:LEFTJOIN, 2:FULLJOIN
private boolean isEnd = false; // ?Ƿ?ȡ??????
private HashUtil hashUtil = new HashUtil(); // ??ϣ?????ߣ????ڼ????ϣֵ
private ListBase1 [][]hashGroups; // ?ڴ????а??????ֶ????Ĺ?ϣ????
private Table result; // ????????
/**
* ?????????α?
* @param objs ????Դ???飬??Ϊ?α꣬??????Ϊ????
* @param exps ????????ʽ????
* @param names ??????ֶ???????
* @param opt ѡ??
* @param ctx ??????????
*/
public JoinxCursor_u(Object []objs, Expression[][] exps, String []names, String opt, Context ctx) {
this.cursor = (ICursor)objs[0];
this.exps = exps[0];
this.ctx = ctx;
int srcCount = objs.length;
if (names == null) {
names = new String[srcCount];
}
ds = new DataStruct(names);
setDataStruct(ds);
if (opt != null) {
if (opt.indexOf('1') != -1) {
type = 1;
} else if (opt.indexOf('f') != -1) {
type = 2;
}
}
hashGroups = new ListBase1[hashUtil.getCapacity()][];
result = new Table(ds, INITSIZE);
int keyCount = exps[0] == null ? 1 : exps[0].length;
int count = keyCount + 1;
ComputeStack stack = ctx.getComputeStack();
final int INIT_GROUPSIZE = HashUtil.getInitGroupSize();
HashUtil hashUtil = this.hashUtil;
ListBase1 [][]hashGroups = this.hashGroups;
for (int s = 1; s < srcCount; ++s) {
Sequence src = (Sequence)objs[s];
Expression []srcExps = exps[s];
Current current = new Current(src);
stack.push(current);
try {
for (int i = 1, len = src.length(); i <= len; ++i) {
Object []keys = new Object[count];
keys[keyCount] = src.getMem(i);
current.setCurrent(i);
if (srcExps == null) {
keys[0] = keys[keyCount];
} else {
for (int k = 0; k < keyCount; ++k) {
keys[k] = srcExps[k].calculate(ctx);
}
}
int hash = hashUtil.hashCode(keys, keyCount);
ListBase1 []groups = hashGroups[hash];
if (groups == null) {
groups = new ListBase1[srcCount];
hashGroups[hash] = groups;
}
if (groups[s] == null) {
groups[s] = new ListBase1(INIT_GROUPSIZE);
groups[s].add(keys);
} else {
int index = HashUtil.bsearch_a(groups[s], keys, keyCount);
if (index < 1) {
groups[s].add(-index, keys);
} else {
groups[s].add(index + 1, keys);
}
}
}
} finally {
stack.pop();
}
}
}
// ???м???ʱ??Ҫ?ı???????
// ?̳???????õ??˱???ʽ????Ҫ?????????????½???????ʽ
public void resetContext(Context ctx) {
if (this.ctx != ctx) {
cursor.resetContext(ctx);
exps = Operation.dupExpressions(exps, ctx);
super.resetContext(ctx);
}
}
/**
* ??ȡָ???????????ݷ???
* @param n ????
* @return Sequence
*/
protected Sequence get(int n) {
if (isEnd || n < 1) return null;
Table result = this.result;
ICursor cursor = this.cursor;
final int INIT_GROUPSIZE = HashUtil.getInitGroupSize();
HashUtil hashUtil = this.hashUtil;
ListBase1 [][]hashGroups = this.hashGroups;
Expression[] exps = this.exps;
Context ctx = this.ctx;
int keyCount = exps == null ? 1 : exps.length;
int count = keyCount + 1;
int srcCount = ds.getFieldCount();
ComputeStack stack = ctx.getComputeStack();
while (result.length() < n) {
Sequence src = cursor.fetch(INITSIZE);
if (src == null || src.length() == 0) {
break;
}
Current current = new Current(src);
stack.push(current);
try {
for (int i = 1, len = src.length(); i <= len; ++i) {
Object []keys = new Object[count];
keys[keyCount] = src.getMem(i);
current.setCurrent(i);
if (exps == null) {
keys[0] = keys[keyCount];
} else {
for (int k = 0; k < keyCount; ++k) {
keys[k] = exps[k].calculate(ctx);
}
}
int hash = hashUtil.hashCode(keys, keyCount);
ListBase1 []groups = hashGroups[hash];
if (groups == null) {
groups = new ListBase1[srcCount];
hashGroups[hash] = groups;
}
if (groups[0] == null) {
groups[0] = new ListBase1(INIT_GROUPSIZE);
groups[0].add(keys);
} else {
int index = HashUtil.bsearch_a(groups[0], keys, keyCount);
if (index < 1) {
groups[0].add(-index, keys);
} else {
groups[0].add(index + 1, keys);
}
}
}
} finally {
stack.pop();
}
for (int i = 0, len = hashGroups.length; i < len; ++i) {
if (hashGroups[i] != null) {
CursorUtil.join_m(hashGroups[i], keyCount, type, result);
if (hashGroups[i][0] != null && hashGroups[i][0].size() > 0) {
hashGroups[i][0].clear();;
}
}
}
}
int len = result.length();
if (len > n) {
return result.split(1, n);
} else if (len == n) {
this.result = new Table(ds, INITSIZE);
return result;
} else {
if (len > 0) {
return result;
} else {
return null;
}
}
}
/**
* ????ָ????????????
* @param n ????
* @return long ʵ????????????
*/
protected long skipOver(long n) {
if (isEnd || n < 1) return 0;
long skipCount = result.length();
Table result = this.result;
if (skipCount > n) {
result.split(1, (int)n);
return n;
} else if (skipCount == n) {
result.clear();
return n;
} else if (skipCount > 0) {
result.clear();
}
ICursor cursor = this.cursor;
final int INIT_GROUPSIZE = HashUtil.getInitGroupSize();
HashUtil hashUtil = this.hashUtil;
ListBase1 [][]hashGroups = this.hashGroups;
Expression[] exps = this.exps;
Context ctx = this.ctx;
int keyCount = exps == null ? 1 : exps.length;
int count = keyCount + 1;
int srcCount = ds.getFieldCount();
ComputeStack stack = ctx.getComputeStack();
while (true) {
Sequence src = cursor.fetch(FETCHCOUNT);
if (src == null || src.length() == 0) {
break;
}
Current current = new Current(src);
stack.push(current);
try {
for (int i = 1, len = src.length(); i <= len; ++i) {
Object []keys = new Object[count];
keys[keyCount] = src.getMem(i);
current.setCurrent(i);
if (exps == null) {
keys[0] = keys[keyCount];
} else {
for (int k = 0; k < keyCount; ++k) {
keys[k] = exps[k].calculate(ctx);
}
}
int hash = hashUtil.hashCode(keys, keyCount);
ListBase1 []groups = hashGroups[hash];
if (groups == null) {
groups = new ListBase1[srcCount];
hashGroups[hash] = groups;
}
if (groups[0] == null) {
groups[0] = new ListBase1(INIT_GROUPSIZE);
groups[0].add(keys);
} else {
int index = HashUtil.bsearch_a(groups[0], keys, keyCount);
if (index < 1) {
groups[0].add(-index, keys);
} else {
groups[0].add(index + 1, keys);
}
}
}
} finally {
stack.pop();
}
for (int i = 0, len = hashGroups.length; i < len; ++i) {
if (hashGroups[i] != null) {
CursorUtil.join_m(hashGroups[i], keyCount, type, result);
hashGroups[i][0] = null;
}
}
int len = result.length();
long dif = n - skipCount;
if (len > dif) {
result.split(1, (int)dif);
return n;
} else if (len == dif) {
result.clear();
return n;
} else if (len > 0) {
skipCount += len;
result.clear();
}
}
return skipCount;
}
/**
* ?ر??α?
*/
public synchronized void close() {
super.close();
cursor.close();
result = null;
isEnd = true;
}
/**
* ?????α?
* @return ?????Ƿ?ɹ???true???α???Դ?ͷ????ȡ????false???????Դ?ͷ????ȡ??
*/
public boolean reset() {
close();
if (!cursor.reset()) {
return false;
}
result = new Table(ds, INITSIZE);
isEnd = false;
return true;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy