com.scudata.expression.fn.gather.ICount 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.expression.fn.gather;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
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.Context;
import com.scudata.dm.Env;
import com.scudata.dm.Sequence;
import com.scudata.expression.Expression;
import com.scudata.expression.Gather;
import com.scudata.expression.IParam;
import com.scudata.resources.EngineMessage;
import com.scudata.util.HashUtil;
import com.scudata.util.Variant;
/**
* ȡ???ظ???Ԫ?ظ?????ȥ??ȡֵΪfalse??Ԫ??
* icount(x1,??)
* @author RunQian
*
*/
public class ICount extends Gather {
private Expression exp; // ????ʽ
private boolean isSorted = false; // ?????Ƿ???ʽ????
private boolean optB = false; // ʹ??λģʽ
// ????icount???м?????Ϣ
public static class ICountInfo implements Serializable {
private static final long serialVersionUID = 1L;
private int count;
private Object startValue;
private Object endValue;
public ICountInfo() {
}
public ICountInfo(Object startValue) {
if (startValue != null) {
count = 1;
this.startValue = startValue;
this.endValue = startValue;
}
}
public void put(Object value) {
if (value instanceof ICountInfo) {
ICountInfo next = (ICountInfo)value;
if (count == 0) {
count = next.count;
startValue = next.startValue;
endValue = next.endValue;
} else if (next.count != 0) {
if (Variant.isEquals(endValue, next.startValue)) {
count += next.count - 1;
} else {
count += next.count;
}
endValue = next.endValue;
}
} else if (value != null) {
if (endValue == null) {
// ǰ??Ķ??ǿ?
startValue = value;
endValue = value;
count = 1;
} else if (!Variant.isEquals(endValue, value)) {
count++;
endValue = value;
}
}
}
}
//û??ʹ?ã??ȷ???????
public static class ICountHashSet implements Serializable {
private static final long serialVersionUID = 1L;
private static final int INIT_SIZE = 64;
private IArray elementArray; // ??ϣ????ŵ???Ԫ?ص?λ?ã???Ҫ????λ?õ?Դ??ȡԪ??
private HashUtil hashUtil; // ???ڼ????ϣֵ
private int count = 0;// ??ǰԪ?ظ???
private int []entries; // ??ϣ????????Ź?ϣֵ??Ӧ?????һ????¼??λ??
private IntArray linkArray; // ??ϣֵ??ͬ?ļ?¼????
public ICountHashSet(IArray src) {
hashUtil = new HashUtil(INIT_SIZE);
entries = new int[hashUtil.getCapacity()];
linkArray = new IntArray(INIT_SIZE);
elementArray = src.newInstance(INIT_SIZE);
}
public void add(IArray array, int index) {
if (array.isNull(index)) {
return;
}
IArray elementArray = this.elementArray;
int[] linkArray = this.linkArray.getDatas();
int[] entries = this.entries;
int hash = hashUtil.hashCode(array.hashCode(index));
int seq = entries[hash];
while (seq != 0) {
if (elementArray.isEquals(seq, array, index)) {
return;
} else {
seq = linkArray[seq];
}
}
count++;
int count = this.count;
if (count == linkArray.length) {
this.linkArray.setSize(count - 1);
elementArray.ensureCapacity(count);
this.linkArray.ensureCapacity(count);
linkArray = this.linkArray.getDatas();
}
elementArray.push(array, index);
linkArray[count] = entries[hash];
entries[hash] = count;
}
public void addInt(int key) {
int[] elementArray = ((IntArray) this.elementArray).getDatas();
int[] linkArray = this.linkArray.getDatas();
int[] entries = this.entries;
int hash = hashUtil.hashCode(key);//key % INIT_SIZE;//
int seq = entries[hash];
while (seq != 0) {
if (elementArray[seq] == key) {
return;
} else {
seq = linkArray[seq];
}
}
count++;
int count = this.count;
if (count == linkArray.length) {
this.elementArray.setSize(count - 1);
this.linkArray.setSize(count - 1);
this.elementArray.ensureCapacity(count);
this.linkArray.ensureCapacity(count);
elementArray = ((IntArray) this.elementArray).getDatas();
linkArray = this.linkArray.getDatas();
}
elementArray[count] = key;
linkArray[count] = entries[hash];
entries[hash] = count;
}
public void addAll(IArray array) {
if (elementArray == null) {
elementArray = array.newInstance(INIT_SIZE);
}
IArray elementArray = this.elementArray;
int[] linkArray = this.linkArray.getDatas();
int[] entries = this.entries;
HashUtil hashUtil = this.hashUtil;
int count = this.count;
for (int i = 1, len = array.size(); i <= len; i++) {
if (array.isNull(i)) {
continue;
}
int hash = hashUtil.hashCode(array.hashCode(i));
int seq = entries[hash];
boolean find = false;
while (seq != 0) {
if (elementArray.isEquals(seq, array, i)) {
find = true;
break;
} else {
seq = linkArray[seq];
}
}
if (find) continue;
count++;
if (count == linkArray.length) {
elementArray.ensureCapacity(count);
this.linkArray.setSize(count - 1);
this.linkArray.ensureCapacity(count);
linkArray = this.linkArray.getDatas();
}
elementArray.push(array, i);
linkArray[count] = entries[hash];
entries[hash] = count;
}
this.count = count;
}
public int size() {
return count;
}
}
//??bitλ?ж??Ƿ??ظ?
public static class ICountBitSet implements Serializable {
private static final long serialVersionUID = 1L;
private static final int INIT_BIT_SIZE = 1024;
private int count = 0;
private long[] bitArray;
public ICountBitSet() {
bitArray = new long[INIT_BIT_SIZE];
}
public ICountBitSet(long[] bitArray) {
this.bitArray = bitArray;
count = countBit(bitArray);
}
public boolean add(int num) {
//IntArray elementArray = this.elementArray;
int idx = (num / 64);
long bit = (1L << (num % 64));
long[] bitArray = this.bitArray;
if (idx >= bitArray.length) {
int newSize = idx + idx / 3;
long[] newBitArray = new long[newSize];
System.arraycopy(bitArray, 0, newBitArray, 0, bitArray.length);
bitArray = this.bitArray = newBitArray;
}
long cur = bitArray[idx];
if ((cur & bit) != 0) {
return false;
} else {
bitArray[idx] = cur | bit;
count++;
}
return true;
}
public boolean add(IArray array, int index) {
if (array.isNull(index)) {
return false;
}
int num = array.getInt(index);
int idx = (num / 64);
long bit = (1L << (num % 64));
long[] bitArray = this.bitArray;
if (idx >= bitArray.length) {
int newSize = idx + idx / 3;
long[] newBitArray = new long[newSize];
System.arraycopy(bitArray, 0, newBitArray, 0, bitArray.length);
bitArray = this.bitArray = newBitArray;
}
long cur = bitArray[idx];
if ((cur & bit) != 0) {
return false;
} else {
bitArray[idx] = cur | bit;
count++;;
}
return true;
}
public static int countBit(long[] bitArray) {
int count = 0;
for (long i : bitArray) {
i = i - ((i >>> 1) & 0x5555555555555555L);
i = (i & 0x3333333333333333L) + ((i >>> 2) & 0x3333333333333333L);
i = (i + (i >>> 4)) & 0x0f0f0f0f0f0f0f0fL;
i = i + (i >>> 8);
i = i + (i >>> 16);
i = i + (i >>> 32);
count += (int)i & 0x7f;
}
return count;
}
public int size() {
return count;
}
public void addAll(long[] newBits) {
long[] curBits = bitArray;
int newLen = newBits.length;
int curLen = curBits.length;
if (curLen >= newLen) {
for (int i = 0; i <= newLen; i++) {
curBits[i] |= newBits[i];
}
} else {
long[] temp = new long[newLen];
System.arraycopy(newBits, curLen, temp, curLen, newLen - curLen);
for (int i = 0; i <= curLen; i++) {
temp[i] = curBits[i] | newBits[i];
}
bitArray = temp;
}
count = countBit(bitArray);
}
public void addAll(ICountBitSet set) {
long[] newBits = set.bitArray;
addAll(newBits);
}
}
//??λ???ж??Ƿ??ظ?
public static class ICountPositionSet implements Serializable {
private static final long serialVersionUID = 1L;
private static final int INIT_SIZE = 65536;
private int count = 0;
private boolean[] posArray;
public ICountPositionSet() {
posArray = new boolean[INIT_SIZE];
}
public boolean add(int num) {
boolean[] posArray = this.posArray;
if (num >= posArray.length) {
int newSize = num + num / 3;
boolean[] newPosArray = new boolean[newSize];
System.arraycopy(posArray, 0, newPosArray, 0, posArray.length);
posArray = this.posArray = newPosArray;
}
if (posArray[num]) {
return false;
} else {
posArray[num] = true;
count++;
}
return true;
}
public boolean add(IArray array, int index) {
int num = array.getInt(index);
boolean[] posArray = this.posArray;
if (num >= posArray.length) {
int newSize = num + num / 3;
boolean[] newPosArray = new boolean[newSize];
System.arraycopy(posArray, 0, newPosArray, 0, posArray.length);
posArray = this.posArray = newPosArray;
}
if (posArray[num]) {
return false;
} else {
posArray[num] = true;
count++;;
}
return true;
}
public int size() {
return count;
}
}
public Object calculate(Context ctx) {
IParam param = this.param;
if (param == null) {
MessageManager mm = EngineMessage.get();
throw new RQException("icount" + mm.getMessage("function.missingParam"));
} else if (param.isLeaf()) {
Object obj = param.getLeafExpression().calculate(ctx);
if (obj instanceof Sequence) {
return ((Sequence)obj).icount(option);
} else {
if (Variant.isTrue(obj)) {
return ObjectCache.getInteger(1);
} else {
return ObjectCache.getInteger(0);
}
}
}
int size = param.getSubSize();
HashSet