// from Operator
  @Override
  public List<String> process(List<String> tuple) {
    _numTuplesProcessed++;
    if (_distinct != null) {
      tuple = _distinct.process(tuple);
      if (tuple == null) {
        return null;
      }
    }
    String tupleHash;
    if (_groupByType == GB_PROJECTION) {
      tupleHash =
          MyUtilities.createHashString(
              tuple, _groupByColumns, _groupByProjection.getExpressions(), _map);
    } else {
      tupleHash = MyUtilities.createHashString(tuple, _groupByColumns, _map);
    }
    T value = _storage.update(tuple, tupleHash);
    String strValue = _wrapper.toString(value);

    // propagate further the affected tupleHash-tupleValue pair
    List<String> affectedTuple = new ArrayList<String>();
    affectedTuple.add(tupleHash);
    affectedTuple.add(strValue);

    return affectedTuple;
  }
 @Override
 public String toString() {
   StringBuilder sb = new StringBuilder();
   sb.append("AggregateSumOperator with VE: ");
   sb.append(_ve.toString());
   if (_groupByColumns.isEmpty() && _groupByProjection == null) {
     sb.append("\n  No groupBy!");
   } else if (!_groupByColumns.isEmpty()) {
     sb.append("\n  GroupByColumns are ").append(getGroupByStr()).append(".");
   } else if (_groupByProjection != null) {
     sb.append("\n  GroupByProjection is ").append(_groupByProjection.toString()).append(".");
   }
   if (_distinct != null) {
     sb.append("\n  It also has distinct ").append(_distinct.toString());
   }
   return sb.toString();
 }