/** * Sorts each local partition of a data set on the field(s) specified by the field expression in * the specified {@link Order} before it is emitted by the output format.</br> <b>Note: * Non-composite types can only be sorted on the full element which is specified by a wildcard * expression ("*" or "_").</b><br> * Data sets of composite types (Tuple or Pojo) can be sorted on multiple fields in different * orders by chaining {@link #sortLocalOutput(String, Order)} calls. * * @param fieldExpression The field expression for the field(s) on which the data set is locally * sorted. * @param order The Order in which the specified field(s) are locally sorted. * @return This data sink operator with specified output order. * @see Order */ public DataSink<T> sortLocalOutput(String fieldExpression, Order order) { int numFields; int[] fields; Order[] orders; if (this.type instanceof CompositeType) { // compute flat field positions for (nested) sorting fields Keys.ExpressionKeys<T> ek; try { ek = new Keys.ExpressionKeys<T>(new String[] {fieldExpression}, this.type); } catch (IllegalArgumentException iae) { throw new InvalidProgramException("Invalid specification of field expression.", iae); } fields = ek.computeLogicalKeyPositions(); numFields = fields.length; orders = new Order[numFields]; Arrays.fill(orders, order); } else { fieldExpression = fieldExpression.trim(); if (!(fieldExpression.equals("*") || fieldExpression.equals("_"))) { throw new InvalidProgramException( "Output sorting of non-composite types can only be defined on the full type. " + "Use a field wildcard for that (\"*\" or \"_\")"); } else { numFields = 1; fields = new int[] {0}; orders = new Order[] {order}; } } if (this.sortKeyPositions == null) { // set sorting info this.sortKeyPositions = fields; this.sortOrders = orders; } else { // append sorting info to existing info int oldLength = this.sortKeyPositions.length; int newLength = oldLength + numFields; this.sortKeyPositions = Arrays.copyOf(this.sortKeyPositions, newLength); this.sortOrders = Arrays.copyOf(this.sortOrders, newLength); for (int i = 0; i < numFields; i++) { this.sortKeyPositions[oldLength + i] = fields[i]; this.sortOrders[oldLength + i] = orders[i]; } } return this; }
/** * Sorts each local partition of a {@link org.apache.flink.api.java.tuple.Tuple} data set on the * specified field in the specified {@link Order} before it is emitted by the output format.</br> * <b>Note: Only tuple data sets can be sorted using integer field indices.</b><br> * The tuple data set can be sorted on multiple fields in different orders by chaining {@link * #sortLocalOutput(int, Order)} calls. * * @param field The Tuple field on which the data set is locally sorted. * @param order The Order in which the specified Tuple field is locally sorted. * @return This data sink operator with specified output order. * @see org.apache.flink.api.java.tuple.Tuple * @see Order */ public DataSink<T> sortLocalOutput(int field, Order order) { if (!this.type.isTupleType()) { throw new InvalidProgramException( "Specifying order keys via field positions is only valid for tuple data types"); } if (field >= this.type.getArity()) { throw new InvalidProgramException("Order key out of tuple bounds."); } // get flat keys Keys.ExpressionKeys<T> ek; try { ek = new Keys.ExpressionKeys<T>(new int[] {field}, this.type); } catch (IllegalArgumentException iae) { throw new InvalidProgramException("Invalid specification of field expression.", iae); } int[] flatKeys = ek.computeLogicalKeyPositions(); if (this.sortKeyPositions == null) { // set sorting info this.sortKeyPositions = flatKeys; this.sortOrders = new Order[flatKeys.length]; Arrays.fill(this.sortOrders, order); } else { // append sorting info to exising info int oldLength = this.sortKeyPositions.length; int newLength = oldLength + flatKeys.length; this.sortKeyPositions = Arrays.copyOf(this.sortKeyPositions, newLength); this.sortOrders = Arrays.copyOf(this.sortOrders, newLength); for (int i = 0; i < flatKeys.length; i++) { this.sortKeyPositions[oldLength + i] = flatKeys[i]; this.sortOrders[oldLength + i] = order; } } return this; }