/** @see niagara.query_engine.PhysicalOperator#processTuple(Tuple, int) */ protected void processTuple(Tuple tuple, int streamId) throws ShutdownException, InterruptedException { String hash = hasher.hashKey(tuple); // ignore null attributes... if (hash == null) return; // Have we seen this group before? Tuple representativeTuple = (Tuple) hash2tuple.get(hash); if (representativeTuple == null) { // Output tuples contain the groupby attributes plus // two more fields: previous and current group info representativeTuple = new Tuple(true, groupAttrs.length + 2); // Copy the groupby attributes for (int i = 0; i < groupAttrs.length; i++) { representativeTuple.appendAttribute(tuple.getAttribute(groupAttrs[i])); } // Initialize the group hashtable entries hash2partial.put(hash, emptyGroupValue()); hash2final.put(hash, emptyGroupValue()); hash2tuple.put(hash, representativeTuple); } Tuple newTuple = new Tuple(tuple.isPartial(), groupAttrs.length + 2); newTuple.appendTuple(representativeTuple); Node oldResult = null; Node newResult; // partial tuples only affect partial results Object oldGroupInfo = hash2partial.get(hash); if (logicalGroupOperator.outputOldValue()) oldResult = constructOutput(oldGroupInfo); Object newGroupInfo = processTuple(tuple, oldGroupInfo); newResult = constructOutput(newGroupInfo); hash2partial.put(hash, newGroupInfo); // final tuples affect both final and partial results if (!tuple.isPartial()) { // final tuples affect both final and partial results oldGroupInfo = hash2final.get(hash); if (logicalGroupOperator.outputOldValue()) oldResult = constructOutput(oldGroupInfo); newGroupInfo = processTuple(tuple, hash2final.get(hash)); newResult = constructOutput(newGroupInfo); hash2final.put(hash, newGroupInfo); } if (newGroupInfo == oldGroupInfo) { // There was no change in the group, // do not output a tuple return; } if (logicalGroupOperator.outputOldValue()) newTuple.appendAttribute(oldResult); newTuple.appendAttribute(newResult); putTuple(newTuple, 0); }
/** * This function initializes the data structures for an operator. This over-rides the * corresponding function in the base class. * * @return True if the operator is to continue and false otherwise */ protected void opInitialize() { // Get the grouping attributes skolem grouping = logicalGroupOperator.getSkolemAttributes(); Vector groupVars = grouping.getVarList(); hasher = new Hasher(groupVars); groupAttrs = new int[groupVars.size()]; for (int i = 0; i < groupAttrs.length; i++) { groupAttrs[i] = inputTupleSchemas[0].getPosition(((Attribute) groupVars.get(i)).getName()); } hasher.resolveVariables(inputTupleSchemas[0]); // Initialize the hash tables hash2final = new HashMap(); hash2partial = new HashMap(); hash2tuple = new HashMap(); }