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

com.scudata.vdb.Filter Maven / Gradle / Ivy

Go to download

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

The newest version!
package com.scudata.vdb;

import com.scudata.dm.BaseRecord;
import com.scudata.dm.ComputeStack;
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.expression.Expression;
import com.scudata.util.Variant;

/**
 * ????????
 * @author RunQian
 *
 */
class Filter {
	private String []filterDirs; // Ŀ¼??????
	private DirFilter []filters; // Ŀ¼????
	private String []selFields; // ѡ???ֶ?
	private Expression exp;
	private Context ctx;
	//private Expression filter; // ????ʶ??ı???ʽ
	
	private int filterCount = 0; // ????????
	private int filterIndex = 0; // ??һ??·????Ӧ??????????
	
	private int capacity = 16; // Ŀ¼??????
	private int dirIndex = 0; // ??һ??Ҫ?????Ŀ¼???????е?λ??
	private String []dirNames = new String[capacity]; // ·????
	private Object []dirValues = new Object[capacity]; // ·??ֵ
	
	private int selDirCount = 0;
	private String []resultFields; // ????????ݽṹ?????selFieldsΪ????ֻ????ѡ????Ŀ¼?ֶ?
	
	// retriveʹ??
	public Filter(String []dirNames, Object []dirValues, boolean []valueSigns, String []selFields, Expression exp, Context ctx) {
		this.filterDirs = dirNames;
		this.selFields = selFields;
		this.exp = exp;
		this.ctx = ctx;
		
		if (dirNames != null) {
			filterCount = dirNames.length;
			filters = new DirFilter[filterCount];
			for (int i = 0; i < filterCount; ++i) {
				filters[i] = new DirFilter(dirValues[i], valueSigns[i]);
				if (dirNames[i] != null) {
					selDirCount++;
				}
			}
			
			if (selFields != null) {
				resultFields = new String[selDirCount + selFields.length];
				for (int i = 0, j = 0; i < filterCount; ++i) {
					if (dirNames[i] != null) {
						resultFields[j++] = dirNames[i];
					}
				}
				
				System.arraycopy(selFields, 0, resultFields, selDirCount, selFields.length);
			} else {
				if (selDirCount == filterCount) {
					resultFields = dirNames;
				} else {
					resultFields = new String[selDirCount];
					for (int i = 0, j = 0; i < filterCount; ++i) {
						if (dirNames[i] != null) {
							resultFields[j++] = dirNames[i];
						}
					}
				}
			}
		} else {
			resultFields = selFields;
		}
	}
	
	// updateʹ??
	public Filter(String []dirNames, Object []dirValues, boolean []valueSigns, Expression exp, Context ctx) {
		this.filterDirs = dirNames;
		this.exp = exp;
		this.ctx = ctx;
		
		if (dirNames != null) {
			filterCount = dirNames.length;
			filters = new DirFilter[filterCount];
			for (int i = 0; i < filterCount; ++i) {
				filters[i] = new DirFilter(dirValues[i], valueSigns[i]);
			}
		}
	}
	
	// ?Ƿ??й??˱???ʽ
	public boolean hasExpression() {
		return exp != null;
	}
	
	private static boolean isEqualField(String filterName, String fname) {
		if (filterName == null) {
			return true;
		} else {
			return fname != null && fname.equals(filterName);
		}
	}
	
	// ?????????????????򷵻?false??????????
	public boolean pushDir(String name, Object value) {
		if (filterIndex < filterCount && isEqualField(filterDirs[filterIndex], name)) {
			if (filters[filterIndex].match(value)) {
				filterIndex++;
			} else {
				return false;
			}
		}
		
		int dirIndex = this.dirIndex;
		if (dirIndex == capacity) {
			capacity *= 2;
			String []newNames = new String[capacity];
			Object []newValues = new Object[capacity];
			System.arraycopy(dirNames, 0, newNames, 0, dirIndex);
			System.arraycopy(dirValues, 0, newValues, 0, dirIndex);
			dirNames = newNames;
			dirValues = newValues;
		}
		
		dirNames[dirIndex] = name;
		dirValues[dirIndex] = value;
		this.dirIndex++;
		return true;
	}
	
	public void popDir() {
		dirIndex--;
		int f = filterIndex - 1;
		if (f >= 0 && isEqualField(filterDirs[f], dirNames[dirIndex])) {
			filterIndex = f;
		}
	}
	
	private static Table getFields(Sequence seq, DataStruct ds, String []feilds) {
		int len = seq.length();
		int newCount = feilds.length;
		int []index = new int[newCount];

		for (int i = 0; i < newCount; ++i) {
			index[i] = ds.getFieldIndex(feilds[i]);
		}

		Table table = new Table(feilds, len);
		for (int i = 1; i <= len; ++i) {
			BaseRecord nr = table.newLast();
			BaseRecord r = (BaseRecord)seq.getMem(i);
			for (int f = 0; f < newCount; ++f) {
				if (index[f] != -1) {
					nr.setNormalFieldValue(f, r.getFieldValue(index[f]));
				}
			}
		}
		
		return table;
	}
	
	// ?ж?·??ֵ?Ƿ?????????ƥ????
	public boolean isDirMatch() {
		return filterIndex == filterCount;
	}
	
	public Sequence select(Object val) {
		if (filterIndex < filterCount) {
			return null;
		}
		
		if (!(val instanceof Sequence)) {
			return null;
		}
		
		Sequence seq = (Sequence)val;
		if (seq.length() == 0) {
			return null;
		}
		
		DataStruct ds = seq.dataStruct();
		if (ds == null) {
			return null;
		}
		
		if (exp == null && selDirCount == 0) {
			if (selFields == null) {
				return seq;
			} else {
				return getFields(seq, ds, selFields);
			}
		}
		
		String []fields = ds.getFieldNames();
		int dirCount = dirIndex;
		int fcount = fields.length;
		String []totalNames = new String[dirCount + fcount];
		System.arraycopy(dirNames, 0, totalNames, 0, dirCount);
		System.arraycopy(fields, 0, totalNames, dirCount, fcount);
		
		int len = seq.length();
		Table table = new Table(totalNames, len);
		Object []dirValues = this.dirValues;
		
		for (int i = 1; i <= len; ++i) {
			BaseRecord r = (BaseRecord)seq.getMem(i);
			BaseRecord nr = table.newLast();
			nr.setStart(0, dirValues, dirCount);
			nr.setStart(dirCount, r);
		}

		if (exp != null) {
			try {
				table.select(exp, "o", ctx);
				if (table.length() == 0) {
					return null;
				}
			} catch (Exception e) {
				return null;
			}
		}
		
		if (selFields == null) {
			if (resultFields == null) {
				return getFields(table, table.dataStruct(), fields);
			} else if (selDirCount == dirCount) {
				return table;
			} else {
				totalNames = new String[selDirCount + fcount];
				System.arraycopy(resultFields, 0, totalNames, 0, selDirCount);
				System.arraycopy(fields, 0, totalNames, selDirCount, fcount);
				return getFields(table, table.dataStruct(), totalNames);
			}
		} else {
			return getFields(table, table.dataStruct(), resultFields);
		}
	}
	
	private static void update(Sequence seq, Object []fvals, int []findex) {
		int mcount = findex.length;
		for (int i = 1, len = seq.length(); i <= len; ++i) {
			BaseRecord r = (BaseRecord)seq.getMem(i);
			for (int f = 0; f < mcount; ++f) {
				r.setNormalFieldValue(findex[f], fvals[f]);
			}
		}
	}
	
	public boolean update(Object val, Object []fvals, String []fields) {
		if (filterIndex < filterCount) {
			return false;
		}
		
		if (!(val instanceof Sequence)) {
			return false;
		}
		
		Sequence seq = (Sequence)val;
		if (seq.length() == 0) {
			return false;
		}
		
		DataStruct ds = seq.dataStruct();
		if (ds == null) {
			return false;
		}
		
		int mcount = fields.length;
		int []findex = new int[mcount];
		for (int i = 0; i < mcount; ++i) {
			findex[i] = ds.getFieldIndex(fields[i]);
			if (findex[i] == -1) {
				return false;
			}
		}
		
		Expression exp = this.exp;
		if (exp == null) {
			update(seq, fvals, findex);
			return true;
		}
		
		String []srcFields = ds.getFieldNames();
		int dirCount = dirIndex;
		int fcount = srcFields.length;
		String []totalNames = new String[dirCount + fcount];
		System.arraycopy(dirNames, 0, totalNames, 0, dirCount);
		System.arraycopy(srcFields, 0, totalNames, dirCount, fcount);
		
		DataStruct nds = new DataStruct(totalNames);
		Object []dirValues = this.dirValues;
		
		boolean match = false;
		Context ctx = this.ctx;
		ComputeStack stack = ctx.getComputeStack();
		Record nr = new Record(nds);
		stack.push(nr);
		
		try {
			for (int i = 1, len = seq.length(); i <= len; ++i) {
				BaseRecord r = (BaseRecord)seq.getMem(i);
				nr.setStart(0, dirValues, dirCount);
				nr.setStart(dirCount, r);
				
				if (Variant.isTrue(exp.calculate(ctx))) {
					match = true;
					for (int f = 0; f < mcount; ++f) {
						r.setNormalFieldValue(findex[f], fvals[f]);
					}
				}
			}
		} catch (Exception e) {
			return false;
		} finally {
			stack.pop();
		}
		
		return match;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy