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

com.scudata.dm.op.PrimaryJoin Maven / Gradle / Ivy

Go to download

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

There is a newer version: 20240823
Show newest version
package com.scudata.dm.op;

import java.util.ArrayList;

import com.scudata.array.IArray;
import com.scudata.common.MessageManager;
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.Sequence;
import com.scudata.dm.Table;
import com.scudata.dm.cursor.ICursor;
import com.scudata.expression.Expression;
import com.scudata.expression.Function;
import com.scudata.resources.EngineMessage;
import com.scudata.util.Variant;


/**
 * ???α꣨???У???????????鲢????
 * A.pjoin(K:..,x:F,??; Ai:z,K:??,x:F,??; ??)
 * @author RunQian
 *
 */
public class PrimaryJoin extends Operation {
	private Expression []srcKeyExps;
	private Expression []srcNewExps;
	private String []srcNewNames;
	
	private ICursor []cursors; // ?????α?????
	private String []options;
	private Expression [][]keyExps;
	private Expression [][]newExps;
	private String [][]newNames;
	private String opt;
	
	private DataStruct resultDs; // ????????ݽṹ
	private Object []resultValues;
	private Object []srcKeyValues;
	private int []newSeqs; // new?ֶ??ڽ???????ݽṹ?е????
	private int []keySeqs; // ?????ֶ??ڽ???????ݽṹ?е????
	private int tableCount;
	private PrimaryJoinItem []joinItems;
	private int []joinTypes; // ???????ͣ?0:??????, 1:??????, 2???????㣬????ƥ?䲻?ϵ?
	
	private int []ranks; // ??ǰԪ?ص???????0??1??-1 ????full join
	private Object []minValues; // ??С?????ֶ?ֵ
	private int srcRefCount; // ??????????????????ֶ???

	private boolean hasNew = false;
	private boolean isPrevMatch = false;
	//private boolean hasGather = false; // ???????ʽ?Ƿ???????ܱ???ʽ
	private boolean isFullJoin = false;
	private boolean hasTimeKey = false;
	
	public PrimaryJoin(Function function, Expression []srcKeyExps, Expression []srcNewExps, String []srcNewNames, 
			ICursor []cursors, String []options, Expression [][]keyExps, 
			Expression [][]newExps, String [][]newNames, String opt, Context ctx) {
		super(function);
		this.srcKeyExps = srcKeyExps;
		this.srcNewExps = srcNewExps;
		this.srcNewNames = srcNewNames;
		this.cursors = cursors;
		this.options = options;
		this.keyExps = keyExps;
		this.newExps = newExps;
		this.newNames = newNames;
		this.opt = opt;
		
		if (opt != null) {
			if (opt.indexOf('f') != -1) {
				isFullJoin = true;
			} else if (opt.indexOf('t') != -1) {
				hasTimeKey = true;
			}
		}
		
		tableCount = cursors.length;
		joinItems = new PrimaryJoinItem [tableCount];
		joinTypes = new int[tableCount];
		
		if (isFullJoin) {
			ranks = new int[tableCount];
		}
		
		for (int t = 0; t < tableCount; ++t) {
			String option = options[t];
			if (option == null) {
				joinTypes[t] = 0;
			} else if (option.equals("null")) {
				if (newExps[t] != null && newExps[t].length > 0) {
					joinTypes[t] = 1;
				} else {
					joinTypes[t] = 2;
				}
			//} else if (option.equals("0")) {
			//	joinTypes[t] = 2;
			} else {
				joinTypes[t] = 0;
			}
			
			joinItems[t] = new PrimaryJoinItem(cursors[t], keyExps[t], newExps[t], joinTypes[t], ctx);
			if (newExps[t] != null && newExps[t].length > 0) {
				hasNew = true;
			}
		}
	}
	
	/**
	 * ȡ?????Ƿ?????Ԫ????????????˺???????ټ?¼
	 * ?˺????????α?ľ?ȷȡ??????????ӵIJ???????ʹ??¼????????ֻ?谴?????????ȡ??????
	 * @return true???ᣬfalse??????
	 */
	public boolean isDecrease() {
		if (isFullJoin) {
			return false;
		}
		
		for (int type : joinTypes) {
			if (type == 0 || type == 2) {
				return true;
			}
		}
		
		return false;
	}

	public Operation duplicate(Context ctx) {
		Expression []tmpSrcKeyExps = dupExpressions(srcKeyExps, ctx);
		Expression []tmpSrcNewExps = dupExpressions(srcNewExps, ctx);
		Expression [][]tmpKeyExps = dupExpressions(keyExps, ctx);
		Expression [][]tmpNewExps = dupExpressions(newExps, ctx);
		return new PrimaryJoin(function, tmpSrcKeyExps, tmpSrcNewExps, srcNewNames, 
				cursors, options, tmpKeyExps, tmpNewExps, newNames, opt, ctx);
	}
	
	private void init(Sequence seq, Context ctx) {
		int keyCount = srcKeyExps.length;
		keySeqs = new int[keyCount];
		srcKeyValues = new Object[keyCount];
		ArrayList fieldList = new ArrayList();
		DataStruct srcDs = null;
		
		if (srcNewExps == null || srcNewExps.length == 0) {
			srcDs = seq.dataStruct();
			if (srcDs == null) {
				MessageManager mm = EngineMessage.get();
				throw new RQException(mm.getMessage("engine.needPurePmt"));
			}
			
			String []names = srcDs.getFieldNames();
			srcRefCount = names.length;
			for (String name : names) {
				fieldList.add(name);
			}
			
			for (int k = 0; k < keyCount; ++k) {
				keySeqs[k] = srcKeyExps[k].getFieldIndex(srcDs);
			}
		} else {
			int fcount = srcRefCount = srcNewExps.length;
			String []oldFieldNames = new String[fcount];
			for (int i = 0; i < fcount; ++i) {
				oldFieldNames[i] = srcNewExps[i].getFieldName();
			}
			
			for (int k = 0; k < keyCount; ++k) {
				keySeqs[k] = -1;
				String keyName = srcKeyExps[k].getFieldName();
				for (int i = 0; i < fcount; ++i) {
					if (keyName.equals(oldFieldNames[i])) {
						keySeqs[k] = i;
						break;
					}
				}
			}
			
			for (int i = 0; i < fcount; ++i) {
				if (srcNewNames != null && srcNewNames[i] != null) {
					fieldList.add(srcNewNames[i]);
				} else {
					fieldList.add(oldFieldNames[i]);
				}
			}
		}
		
		int tcount = cursors.length;
		newSeqs = new int[tcount];
		
		for (int t = 0; t < tcount; ++t) {
			//keyValues[t] = new Object[keyCount];
			Expression []curNewExps = newExps[t];
			newSeqs[t] = fieldList.size();
			
			if (curNewExps != null) {
				String []curNewNames = newNames[t];
				int count = curNewExps.length;
				
				for (int i = 0; i < count; ++i) {
					if (curNewNames != null && curNewNames[i] != null) {
						fieldList.add(curNewNames[i]);
					} else {
						fieldList.add(curNewExps[i].getFieldName());
					}
				}
			}
		}
		
		int fcount = fieldList.size();
		if (srcDs == null || srcDs.getFieldCount() != fcount) {
			resultValues = new Object[fcount];
			String []fnames = new String[fcount];
			fieldList.toArray(fnames);
			resultDs = new DataStruct(fnames);
		} else {
			resultDs = srcDs;
		}
	}
	
	public Sequence process(Sequence seq, Context ctx) {
		if (isFullJoin) {
			if (tableCount == 1) {
				return fullJoin1(seq, ctx);
			} else {
				return fullJoin(seq, ctx);
			}
		} else if (hasTimeKey) {
			if (hasNew) {
				return timeKeyJoin(seq, ctx);
			} else {
				return timeKeyFilterJoin(seq, ctx);
			}
		} else if (hasNew) {
			return join(seq, ctx);
		} else {
			return filterJoin(seq, ctx);
		}
	}
	
	// ??????????ĵ?ǰ??????ֵ??????
	private void calcRanks() {
		PrimaryJoinItem []joinItems = this.joinItems;
		int tableCount = this.tableCount;
		int []ranks = this.ranks;
		Object []minValues = null;
		
		for (int i = 0; i < tableCount; ++i) {
			Object []curValues = joinItems[i].getCurrentKeyValues();
			if (curValues != null) {
				if (minValues == null) {
					ranks[i] = 0;
					minValues = curValues;
				} else {
					int cmp = Variant.compareArrays(minValues, curValues);
					if (cmp == 0) {
						ranks[i] = 0;
					} else if (cmp < 0) {
						ranks[i] = 1;
					} else {
						ranks[i] = 0;
						minValues = curValues;
						
						for (int j = 0; j < i; ++j) {
							if (ranks[j] == 0) {
								ranks[j] = 1;
							}
						}
					}
				}
			} else {
				ranks[i] = -1;
			}
		}
		
		this.minValues = minValues;
	}
	
	private void popTop(Object []resultValues) {
		int []newSeqs = this.newSeqs;
		int []ranks = this.ranks;
		PrimaryJoinItem []joinItems = this.joinItems;
		int tableCount = joinItems.length;
		
		for (int i = 0; i < tableCount; ++i) {
			if (ranks[i] == 0) {
				joinItems[i].popTop(resultValues, newSeqs[i]);
			} else {
				joinItems[i].resetNewValues(resultValues, newSeqs[i]);
			}
		}
		
		calcRanks();
	}
	
	public Sequence finish(Context ctx) {
		if (!isFullJoin) {
			return null;
		}

		boolean isFirst = resultDs == null;
		if (tableCount == 1) {
			PrimaryJoinItem joinItem = joinItems[0];
			Object []topValues = joinItem.getCurrentKeyValues();
			if (topValues == null) {
				return null;
			}
			
			if (isFirst) {
				if (srcNewExps == null || srcNewExps.length == 0) {
					return null;
				}
				
				init(null, ctx);
			}
			
			int srcRefCount = this.srcRefCount;
			for (int f = 0; f < srcRefCount; ++f) {
				resultValues[f] = null;
			}
			
			int keyCount = srcKeyValues.length;
			Object []resultValues = this.resultValues;
			int []keySeqs = this.keySeqs;
			int newSeq = newSeqs[0];
			Table result = new Table(resultDs);
			
			do {
				for (int f = 0; f < keyCount; ++f) {
					if (keySeqs[f] != -1) {
						resultValues[keySeqs[f]] = topValues[f];
					}
				}
				
				joinItem.popTop(resultValues, newSeq);
				result.newLast(resultValues);
				topValues = joinItem.getCurrentKeyValues();
			} while (topValues != null);
						
			return result;
		} else {
			if (isFirst) {
				if (srcNewExps == null || srcNewExps.length == 0) {
					return null;
				}
				
				init(null, ctx);
				calcRanks();
			}
			
			if (minValues == null) {
				return null;
			}
			
			int srcRefCount = this.srcRefCount;
			for (int f = 0; f < srcRefCount; ++f) {
				resultValues[f] = null;
			}
				
			int keyCount = srcKeyValues.length;
			Object []resultValues = this.resultValues;
			int []keySeqs = this.keySeqs;
			
			Table result = new Table(resultDs);
			while (minValues != null) {
				for (int f = 0; f < keyCount; ++f) {
					if (keySeqs[f] != -1) {
						resultValues[keySeqs[f]] = minValues[f];
					}
				}
				
				popTop(resultValues);
				result.newLast(resultValues);
			}
			
			return result;
		}
	}
	
	private Sequence fullJoin1(Sequence seq, Context ctx) {
		boolean isFirst = resultDs == null;
		if (isFirst) {
			init(seq, ctx);
		}
		
		Expression []srcKeyExps = this.srcKeyExps;
		Expression []srcNewExps = this.srcNewExps;
		int srcNewCount = srcNewExps == null ? 0 : srcNewExps.length;
		Object []srcKeyValues = this.srcKeyValues;
		int keyCount = srcKeyValues.length;
		Object []resultValues = this.resultValues;
		int []keySeqs = this.keySeqs;
		int srcRefCount = this.srcRefCount;
		int resultFieldCount = resultValues.length;
		PrimaryJoinItem joinItem = joinItems[0];
		int newSeq = newSeqs[0];
		
		int len = seq.length();
		Table result = new Table(resultDs, len);
		
		ComputeStack stack = ctx.getComputeStack();
		Current current = new Current(seq);
		stack.push(current);
		
		try {
			for (int i = 1; i <= len; ++i) {
				current.setCurrent(i);
				boolean isEquals = true;
				
				for (int k = 0; k < keyCount; ++k) {
					Object value = srcKeyExps[k].calculate(ctx);
					if (isEquals) {
						isEquals = Variant.isEquals(srcKeyValues[k], value);
					}
					
					srcKeyValues[k] = value;
				}
				
				if (isEquals) {
					if (srcNewCount > 0) {
						for (int f = 0; f < srcNewCount; ++f) {
							resultValues[f] = srcNewExps[f].calculate(ctx);
						}
					} else {
						BaseRecord r = (BaseRecord)seq.getMem(i);
						Object []vals = r.getFieldValues();
						System.arraycopy(vals, 0, resultValues, 0, srcRefCount);
					}
					
					result.newLast(resultValues);
				} else {
					while (true) {
						Object []topValues = joinItem.getCurrentKeyValues();
						int cmp = topValues == null ? -1 : Variant.compareArrays(srcKeyValues, topValues, keyCount);
						if (cmp == 0) {
							if (srcNewCount > 0) {
								for (int f = 0; f < srcNewCount; ++f) {
									resultValues[f] = srcNewExps[f].calculate(ctx);
								}
							} else {
								BaseRecord r = (BaseRecord)seq.getMem(i);
								Object []vals = r.getFieldValues();
								System.arraycopy(vals, 0, resultValues, 0, srcRefCount);
							}
							
							joinItem.popTop(resultValues, newSeq);
							result.newLast(resultValues);
							break;
						} else if (cmp < 0) {
							if (srcNewCount > 0) {
								for (int f = 0; f < srcNewCount; ++f) {
									resultValues[f] = srcNewExps[f].calculate(ctx);
								}
							} else {
								BaseRecord r = (BaseRecord)seq.getMem(i);
								Object []vals = r.getFieldValues();
								System.arraycopy(vals, 0, resultValues, 0, srcRefCount);
							}
							
							for (int f = srcRefCount; f < resultFieldCount; ++f) {
								resultValues[f] = null;
							}
							
							result.newLast(resultValues);
							break;
						} else {
							for (int f = 0; f < srcRefCount; ++f) {
								resultValues[f] = null;
							}
							
							for (int f = 0; f < keyCount; ++f) {
								if (keySeqs[f] != -1) {
									resultValues[keySeqs[f]] = topValues[f];
								}
							}
							
							joinItem.popTop(resultValues, newSeq);
							result.newLast(resultValues);
						}
					}
				}
			}
		} finally {
			stack.pop();
		}
		
		return result;
	}
	
	private Sequence fullJoin(Sequence seq, Context ctx) {
		boolean isFirst = resultDs == null;
		if (isFirst) {
			init(seq, ctx);
			calcRanks();
		}
		
		Expression []srcKeyExps = this.srcKeyExps;
		Expression []srcNewExps = this.srcNewExps;
		int srcNewCount = srcNewExps == null ? 0 : srcNewExps.length;
		Object []srcKeyValues = this.srcKeyValues;
		int keyCount = srcKeyValues.length;
		Object []resultValues = this.resultValues;
		int []keySeqs = this.keySeqs;
		int srcRefCount = this.srcRefCount;
		int resultFieldCount = resultValues.length;
		
		int len = seq.length();
		Table result = new Table(resultDs, len);
		
		ComputeStack stack = ctx.getComputeStack();
		Current current = new Current(seq);
		stack.push(current);
		
		try {
			for (int i = 1; i <= len; ++i) {
				current.setCurrent(i);
				boolean isEquals = true;
				
				for (int k = 0; k < keyCount; ++k) {
					Object value = srcKeyExps[k].calculate(ctx);
					if (isEquals) {
						isEquals = Variant.isEquals(srcKeyValues[k], value);
					}
					
					srcKeyValues[k] = value;
				}
				
				if (isEquals) {
					if (srcNewCount > 0) {
						for (int f = 0; f < srcNewCount; ++f) {
							resultValues[f] = srcNewExps[f].calculate(ctx);
						}
					} else {
						BaseRecord r = (BaseRecord)seq.getMem(i);
						Object []vals = r.getFieldValues();
						System.arraycopy(vals, 0, resultValues, 0, srcRefCount);
					}
					
					result.newLast(resultValues);
				} else {
					while (true) {
						int cmp = minValues == null ? -1 : Variant.compareArrays(srcKeyValues, minValues, keyCount);
						if (cmp == 0) {
							if (srcNewCount > 0) {
								for (int f = 0; f < srcNewCount; ++f) {
									resultValues[f] = srcNewExps[f].calculate(ctx);
								}
							} else {
								BaseRecord r = (BaseRecord)seq.getMem(i);
								Object []vals = r.getFieldValues();
								System.arraycopy(vals, 0, resultValues, 0, srcRefCount);
							}
							
							popTop(resultValues);
							result.newLast(resultValues);
							break;
						} else if (cmp < 0) {
							if (srcNewCount > 0) {
								for (int f = 0; f < srcNewCount; ++f) {
									resultValues[f] = srcNewExps[f].calculate(ctx);
								}
							} else {
								BaseRecord r = (BaseRecord)seq.getMem(i);
								Object []vals = r.getFieldValues();
								System.arraycopy(vals, 0, resultValues, 0, srcRefCount);
							}
							
							for (int f = srcRefCount; f < resultFieldCount; ++f) {
								resultValues[f] = null;
							}
							
							result.newLast(resultValues);
							break;
						} else {
							for (int f = 0; f < srcRefCount; ++f) {
								resultValues[f] = null;
							}
							
							for (int f = 0; f < keyCount; ++f) {
								if (keySeqs[f] != -1) {
									resultValues[keySeqs[f]] = minValues[f];
								}
							}
							
							popTop(resultValues);
							result.newLast(resultValues);
						}
					}
				}
			}
		} finally {
			stack.pop();
		}
		
		return result;
	}
	
	private Sequence join(Sequence seq, Context ctx) {
		boolean isFirst = resultDs == null;
		if (isFirst) {
			init(seq, ctx);
		}
		
		Expression []srcKeyExps = this.srcKeyExps;
		Expression []srcNewExps = this.srcNewExps;
		int srcNewCount = srcNewExps == null ? 0 : srcNewExps.length;
		Object []srcKeyValues = this.srcKeyValues;
		int keyCount = srcKeyValues.length;
		Object []resultValues = this.resultValues;
		int []newSeqs = this.newSeqs;
		PrimaryJoinItem []joinItems = this.joinItems;
		int tableCount = joinItems.length;
		boolean isPrevMatch = this.isPrevMatch;
		
		int i = 1;
		int len = seq.length();
		Table result = new Table(resultDs, len);
		
		ComputeStack stack = ctx.getComputeStack();
		Current current = new Current(seq);
		stack.push(current);
		
		try {
			if (isFirst) {
				current.setCurrent(1);
				i++;
				
				for (int k = 0; k < keyCount; ++k) {
					srcKeyValues[k] = srcKeyExps[k].calculate(ctx);
				}
				
				for (int t = 0; t < tableCount; ++t) {
					isPrevMatch = joinItems[t].join(srcKeyValues, resultValues, newSeqs[t]);
					if (isPrevMatch == false) {
						break;
					}
				}
				
				if (isPrevMatch) {
					if (srcNewCount > 0) {
						for (int f = 0; f < srcNewCount; ++f) {
							resultValues[f] = srcNewExps[f].calculate(ctx);
						}
					} else {
						BaseRecord r = (BaseRecord)seq.getMem(1);
						Object []vals = r.getFieldValues();
						System.arraycopy(vals, 0, resultValues, 0, vals.length);
					}
					
					result.newLast(resultValues);
				}
			}
			
			for (; i <= len; ++i) {
				current.setCurrent(i);
				boolean isEquals = true;
				
				for (int k = 0; k < keyCount; ++k) {
					Object value = srcKeyExps[k].calculate(ctx);
					if (isEquals) {
						isEquals = Variant.isEquals(srcKeyValues[k], value);
					}
					
					srcKeyValues[k] = value;
				}
				
				if (!isEquals) {
					for (int t = 0; t < tableCount; ++t) {
						isPrevMatch = joinItems[t].join(srcKeyValues, resultValues, newSeqs[t]);
						if (isPrevMatch == false) {
							break;
						}
					}
				}
				
				if (isPrevMatch) {
					if (srcNewCount > 0) {
						for (int f = 0; f < srcNewCount; ++f) {
							resultValues[f] = srcNewExps[f].calculate(ctx);
						}
					} else {
						BaseRecord r = (BaseRecord)seq.getMem(i);
						Object []vals = r.getFieldValues();
						System.arraycopy(vals, 0, resultValues, 0, vals.length);
					}
					
					result.newLast(resultValues);
				}
			}
		} finally {
			stack.pop();
		}
		
		this.isPrevMatch = isPrevMatch;
		return result;
	}
	
	private Sequence filterJoin(Sequence seq, Context ctx) {
		boolean isFirst = resultDs == null;
		if (isFirst) {
			init(seq, ctx);
		}
		
		Expression []srcKeyExps = this.srcKeyExps;
		Object []srcKeyValues = this.srcKeyValues;
		int keyCount = srcKeyValues.length;
		PrimaryJoinItem []joinItems = this.joinItems;
		int tableCount = joinItems.length;
		boolean isPrevMatch = this.isPrevMatch;
		
		int i = 1;
		int len = seq.length();
		Sequence result = new Sequence(len);
		IArray array = result.getMems();
		
		ComputeStack stack = ctx.getComputeStack();
		Current current = new Current(seq);
		stack.push(current);
		
		try {
			if (isFirst) {
				current.setCurrent(1);
				i++;
				
				for (int k = 0; k < keyCount; ++k) {
					srcKeyValues[k] = srcKeyExps[k].calculate(ctx);
				}
				
				for (int t = 0; t < tableCount; ++t) {
					isPrevMatch = joinItems[t].join(srcKeyValues, null, -1);
					if (isPrevMatch == false) {
						break;
					}
				}
				
				if (isPrevMatch) {
					array.push(seq.getMem(1));
				}
			}
			
			for (; i <= len; ++i) {
				current.setCurrent(i);
				boolean isEquals = true;
				
				for (int k = 0; k < keyCount; ++k) {
					Object value = srcKeyExps[k].calculate(ctx);
					if (isEquals) {
						isEquals = Variant.isEquals(srcKeyValues[k], value);
					}
					
					srcKeyValues[k] = value;
				}
				
				if (isEquals) {
					if (isPrevMatch) {
						array.push(seq.getMem(i));
					}
				} else {
					for (int t = 0; t < tableCount; ++t) {
						isPrevMatch = joinItems[t].join(srcKeyValues, null, -1);
						if (isPrevMatch == false) {
							break;
						}
					}
					
					if (isPrevMatch) {
						array.push(seq.getMem(i));
					}
				}
			}
		} finally {
			stack.pop();
		}
		
		this.isPrevMatch = isPrevMatch;
		return result;
	}

	private Sequence timeKeyJoin(Sequence seq, Context ctx) {
		boolean isFirst = resultDs == null;
		if (isFirst) {
			init(seq, ctx);
		}
		
		Expression []srcKeyExps = this.srcKeyExps;
		Expression []srcNewExps = this.srcNewExps;
		int srcNewCount = srcNewExps == null ? 0 : srcNewExps.length;
		Object []srcKeyValues = this.srcKeyValues;
		int keyCount = srcKeyValues.length;
		Object []resultValues = this.resultValues;
		int []newSeqs = this.newSeqs;
		PrimaryJoinItem []joinItems = this.joinItems;
		int tableCount = joinItems.length;
		
		int len = seq.length();
		Table result = new Table(resultDs, len);
		
		ComputeStack stack = ctx.getComputeStack();
		Current current = new Current(seq);
		stack.push(current);
		
		try {
			Next:
			for (int i = 1; i <= len; ++i) {
				current.setCurrent(i);
				for (int k = 0; k < keyCount; ++k) {
					srcKeyValues[k] = srcKeyExps[k].calculate(ctx);
				}
				
				for (int t = 0; t < tableCount; ++t) {
					if (!joinItems[t].timeKeyJoin(srcKeyValues, resultValues, newSeqs[t])) {
						continue Next;
					}
				}
				
				if (srcNewCount > 0) {
					for (int f = 0; f < srcNewCount; ++f) {
						resultValues[f] = srcNewExps[f].calculate(ctx);
					}
				} else {
					BaseRecord r = (BaseRecord)seq.getMem(i);
					Object []vals = r.getFieldValues();
					System.arraycopy(vals, 0, resultValues, 0, vals.length);
				}
				
				result.newLast(resultValues);
			}
		} finally {
			stack.pop();
		}
		
		return result;
	}

	private Sequence timeKeyFilterJoin(Sequence seq, Context ctx) {
		boolean isFirst = resultDs == null;
		if (isFirst) {
			init(seq, ctx);
		}
		
		Expression []srcKeyExps = this.srcKeyExps;
		Object []srcKeyValues = this.srcKeyValues;
		int keyCount = srcKeyValues.length;
		PrimaryJoinItem []joinItems = this.joinItems;
		int tableCount = joinItems.length;
		
		int len = seq.length();
		Sequence result = new Sequence(len);
		IArray array = result.getMems();
		
		ComputeStack stack = ctx.getComputeStack();
		Current current = new Current(seq);
		stack.push(current);
		
		try {
			Next:
			for (int i = 1; i <= len; ++i) {
				current.setCurrent(i);
				for (int k = 0; k < keyCount; ++k) {
					srcKeyValues[k] = srcKeyExps[k].calculate(ctx);
				}
				
				for (int t = 0; t < tableCount; ++t) {
					if (!joinItems[t].timeKeyJoin(srcKeyValues, null, -1)) {
						continue Next;
					}
				}
				
				array.push(seq.getMem(i));
			}
		} finally {
			stack.pop();
		}
		
		return result;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy