All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.scudata.expression.mfn.sequence.Contain Maven / Gradle / Ivy

Go to download

SPL(Structured Process Language) A programming language specially for structured data computing.

There is a newer version: 20241126
Show newest version
package com.scudata.expression.mfn.sequence;

import com.scudata.array.ArrayUtil;
import com.scudata.array.BoolArray;
import com.scudata.array.ConstArray;
import com.scudata.array.IArray;
import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.dm.Context;
import com.scudata.dm.HashIndexSequence;
import com.scudata.dm.Sequence;
import com.scudata.expression.IParam;
import com.scudata.expression.Relation;
import com.scudata.expression.SequenceFunction;
import com.scudata.resources.EngineMessage;
import com.scudata.util.Variant;

/**
 * ?ж??????Ƿ????ָ??Ԫ??
 * A.contain(x)
 * @author RunQian
 *
 */
public class Contain extends SequenceFunction {
	private Sequence prevSequence = null;
	private Sequence sortedSequence = null;
	private HashIndexSequence hashIndex;
	private boolean isSorted;
	
	public void setDotLeftObject(Object obj) {
		srcSequence = (Sequence)obj;
		
		if (option != null && option.indexOf('h') != -1 && prevSequence != srcSequence) {
			prevSequence = srcSequence;
			hashIndex = new HashIndexSequence(srcSequence);
		}
	}
	
	/**
	 * ?ͷŽڵ????õĵ?????????Ķ???
	 */
	public void releaseDotLeftObject() {
		if (option == null || option.indexOf('h') == -1) {
			srcSequence = null;
		}
	}
	
	public boolean ifModifySequence() {
		return false;
	}
	
	/**
	 * ??????ʽ????Ч?ԣ???Ч???׳??쳣
	 */
	public void checkValidity() {
		if (param == null) {
			MessageManager mm = EngineMessage.get();
			throw new RQException("contain" + mm.getMessage("function.missingParam"));
		}
		
		isSorted = option != null && option.indexOf('b') != -1;
	}

	public Object calculate(Context ctx) {
		if (param.isLeaf()) {
			Object obj = param.getLeafExpression().calculate(ctx);
			if (hashIndex != null) {
				return hashIndex.findPos(obj) > 0;
			}
			
			return srcSequence.contains(obj, option != null && option.indexOf('b') != -1);
		} else {
			int size = param.getSubSize();
			if (hashIndex != null) {
				for (int i = 0; i < size; ++i) {
					IParam sub = param.getSub(i);
					Object val = null;
					if (sub != null) {
						val = sub.getLeafExpression().calculate(ctx);
					}
					
					if (hashIndex.findPos(val) < 1) {
						return false;
					}
				}

				return true;
			}
			
			for (int i = 0; i < size; ++i) {
				IParam sub = param.getSub(i);
				Object val = null;
				if (sub != null) {
					val = sub.getLeafExpression().calculate(ctx);
				}
				
				if (!srcSequence.contains(val, isSorted)) {
					return false;
				}
			}

			return true;
		}
	}
	
	/**
	 * ??????????еĽ??
	 * @param ctx ??????????
	 * @return IArray
	 */
	public IArray calculateAll(Context ctx) {
		IArray leftArray = left.calculateAll(ctx);
		if (leftArray instanceof ConstArray) {
			Object leftValue = ((ConstArray)leftArray).getData();
			if (leftValue instanceof Sequence && param.isLeaf()) {
				Sequence srcSequence = (Sequence)leftValue;
				IArray array = param.getLeafExpression().calculateAll(ctx);
				BoolArray result = new BoolArray(true, array.size());
				result.setTemporary(true);
				
				if (isSorted) {
					srcSequence.contains(true, array, result);
				} else if (srcSequence.length() <= 3) {
					srcSequence.contains(false, array, result);
				} else {
					if (prevSequence != srcSequence) {
						prevSequence = srcSequence;
						hashIndex = new HashIndexSequence(srcSequence);
						//sortedSequence = srcSequence.sort(null);
					}
					
					hashIndex.contains(array, result);
					//sortedSequence.contains(true, array, result);
				}
				
				return result;
			}
		}
		
		return calculateAll(leftArray, ctx);
	}

	/**
	 * ????signArray??ȡֵΪsign????
	 * @param ctx
	 * @param signArray ?б?ʶ????
	 * @param sign ??ʶ
	 * @return IArray
	 */
	public IArray calculateAll(Context ctx, IArray signArray, boolean sign) {
		IArray leftArray = left.calculateAll(ctx);
		if (leftArray instanceof ConstArray) {
			Object leftValue = ((ConstArray)leftArray).getData();
			if (leftValue instanceof Sequence && param.isLeaf()) {
				Sequence srcSequence = (Sequence)leftValue;
				BoolArray result = ArrayUtil.booleanValue(signArray, sign);
				IArray array = param.getLeafExpression().calculateAll(ctx, result, true);
				
				if (isSorted) {
					srcSequence.contains(true, array, result);
				} else if (srcSequence.length() <= 3) {
					srcSequence.contains(false, array, result);
				} else {
					if (prevSequence != srcSequence) {
						prevSequence = srcSequence;
						hashIndex = new HashIndexSequence(srcSequence);
						//sortedSequence = srcSequence.sort(null);
					}
					
					hashIndex.contains(array, result);
					//sortedSequence.contains(true, array, result);
				}
				
				return result;
			}
		}
		
		return calculateAll(leftArray, ctx, signArray, sign);
	}
	
	/**
	 * ?????߼????????&&???Ҳ????ʽ
	 * @param ctx ??????????
	 * @param leftResult &&??????ʽ?ļ?????
	 * @return BoolArray
	 */
	public BoolArray calculateAnd(Context ctx, IArray leftResult) {
		IArray leftArray = left.calculateAll(ctx);
		if (leftArray instanceof ConstArray) {
			Object leftValue = ((ConstArray)leftArray).getData();
			if (leftValue instanceof Sequence && param.isLeaf()) {
				Sequence srcSequence = (Sequence)leftValue;
				BoolArray result = leftResult.isTrue();
				IArray array = param.getLeafExpression().calculateAll(ctx, result, true);
				
				if (isSorted) {
					srcSequence.contains(true, array, result);
				} else if (srcSequence.length() <= 3) {
					srcSequence.contains(false, array, result);
				} else {
					if (prevSequence != srcSequence) {
						prevSequence = srcSequence;
						hashIndex = new HashIndexSequence(srcSequence);
						//sortedSequence = srcSequence.sort(null);
					}
					
					hashIndex.contains(array, result);
					//sortedSequence.contains(true, array, result);
				}
				
				return result;
			}
		}
		
		return calculateAnd(leftArray, ctx, leftResult);
	}
	
	/**
	 * ?жϸ?????ֵ??Χ?Ƿ????㵱ǰ????????ʽ
	 * @param ctx ??????????
	 * @return ȡֵ????Relation. -1??ֵ??Χ??û????????????ֵ??0??ֵ??Χ??????????????ֵ??1??ֵ??Χ??ֵ??????????
	 */
	public int isValueRangeMatch(Context ctx) {
		IArray leftArray = left.calculateAll(ctx);
		if (leftArray instanceof ConstArray) {
			Object leftValue = ((ConstArray)leftArray).getData();
			if (leftValue instanceof Sequence && param.isLeaf()) {
				IArray array = param.getLeafExpression().calculateRange(ctx);
				if (array == null) {
					return Relation.PARTICALMATCH;
				}
				
				Sequence srcSequence = (Sequence)leftValue;
				Sequence seq;
				if (option != null && option.indexOf('b') != -1) {
					seq = srcSequence;
				} else {
					if (prevSequence != srcSequence) {
						prevSequence = srcSequence;
						sortedSequence = srcSequence.sort(null);
						hashIndex = new HashIndexSequence(srcSequence);
					}
					
					seq = sortedSequence;
				}
				
				Object minValue = array.get(1);
				Object maxValue = array.get(2);
				Object obj = seq.pos(minValue, "bs");
				int index1 = ((Number)obj).intValue();
				
				if (Variant.isEquals(minValue, maxValue)) {
					return index1 < 1 ? Relation.UNMATCH : Relation.ALLMATCH;
				} else {
					if (index1 > 0) {
						return Relation.PARTICALMATCH;
					}
					
					obj = seq.pos(maxValue, "bs");
					int index2 = ((Number)obj).intValue();
					if (index2 != index1) {
						return Relation.PARTICALMATCH;
					} else {
						return Relation.UNMATCH;
					}
				}
			}
		}

		return Relation.PARTICALMATCH;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy