Package eu.stratosphere.api.java.operators

Source Code of eu.stratosphere.api.java.operators.Keys

/***********************************************************************************************************************
*
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
**********************************************************************************************************************/
package eu.stratosphere.api.java.operators;

import java.util.Arrays;

import eu.stratosphere.api.common.InvalidProgramException;
import eu.stratosphere.api.java.functions.KeySelector;
import eu.stratosphere.api.java.typeutils.TupleTypeInfo;
import eu.stratosphere.api.java.typeutils.TypeExtractor;
import eu.stratosphere.types.TypeInformation;


public abstract class Keys<T> {


  public abstract int getNumberOfKeyFields();
 
  public boolean isEmpty() {
    return getNumberOfKeyFields() == 0;
  }
 
  public abstract boolean areCompatibale(Keys<?> other);
 
  public abstract int[] computeLogicalKeyPositions();
 
  // --------------------------------------------------------------------------------------------
  //  Specializations for field indexed / expression-based / extractor-based grouping
  // --------------------------------------------------------------------------------------------
 
  public static class FieldPositionKeys<T> extends Keys<T> {
   
    private final int[] groupingFields;
    private final TypeInformation<?>[] types;
   
    public FieldPositionKeys(int[] groupingFields, TypeInformation<T> type) {
      this(groupingFields, type, false);
    }
   
    public FieldPositionKeys(int[] groupingFields, TypeInformation<T> type, boolean allowEmpty) {
      if (!type.isTupleType()) {
        throw new InvalidProgramException("Specifying keys via field positions is only valid for tuple data types");
      }
     
      if (!allowEmpty && (groupingFields == null || groupingFields.length == 0)) {
        throw new IllegalArgumentException("The grouping fields must not be empty.");
      }
     
      TupleTypeInfo<?> tupleType = (TupleTypeInfo<?>)type;
 
      this.groupingFields = makeFields(groupingFields, (TupleTypeInfo<?>) type);
     
      types = new TypeInformation[this.groupingFields.length];
      for(int i = 0; i < this.groupingFields.length; i++) {
        types[i] = tupleType.getTypeAt(this.groupingFields[i]);
      }
     
    }

    @Override
    public int getNumberOfKeyFields() {
      return this.groupingFields.length;
    }

    @Override
    public boolean areCompatibale(Keys<?> other) {
     
      if (other instanceof FieldPositionKeys) {
        FieldPositionKeys<?> oKey = (FieldPositionKeys<?>) other;
       
        if(oKey.types.length != this.types.length) {
          return false;
        }
        for(int i=0; i<this.types.length; i++) {
          if(!this.types[i].equals(oKey.types[i])) {
            return false;
          }
        }
        return true;
       
      } else if (other instanceof SelectorFunctionKeys) {
        if(this.types.length != 1) {
          return false;
        }
       
        SelectorFunctionKeys<?, ?> sfk = (SelectorFunctionKeys<?, ?>) other;
       
        return sfk.keyType.equals(this.types[0]);
      }
      else {
        return false;
      }
    }

    @Override
    public int[] computeLogicalKeyPositions() {
      return this.groupingFields;
    }
 
  }
 
  // --------------------------------------------------------------------------------------------
 
  public static class SelectorFunctionKeys<T, K> extends Keys<T> {

    private final KeySelector<T, K> keyExtractor;
    private final TypeInformation<K> keyType;
   
    public SelectorFunctionKeys(KeySelector<T, K> keyExtractor, TypeInformation<T> type) {
      this.keyExtractor = keyExtractor;
      this.keyType = TypeExtractor.getKeySelectorTypes(keyExtractor, type);
    }

    public TypeInformation<K> getKeyType() {
      return keyType;
    }

    public KeySelector<T, K> getKeyExtractor() {
      return keyExtractor;
    }

    @Override
    public int getNumberOfKeyFields() {
      return 1;
    }

    @Override
    public boolean areCompatibale(Keys<?> other) {
     
      if (other instanceof SelectorFunctionKeys) {
        @SuppressWarnings("unchecked")
        SelectorFunctionKeys<?, K> sfk = (SelectorFunctionKeys<?, K>) other;
       
        return sfk.keyType.equals(this.keyType);
      }
      else if (other instanceof FieldPositionKeys) {
        FieldPositionKeys<?> fpk = (FieldPositionKeys<?>) other;
           
        if(fpk.types.length != 1) {
          return false;
        }
       
        return fpk.types[0].equals(this.keyType);
      }
      else {
        return false;
      }
    }

    @Override
    public int[] computeLogicalKeyPositions() {
      return new int[] {0};
    }
  }
 
  // --------------------------------------------------------------------------------------------
 
  public static class ExpressionKeys<T> extends Keys<T> {

    public ExpressionKeys(String expression, TypeInformation<T> type) {
    }

    @Override
    public int getNumberOfKeyFields() {
      throw new UnsupportedOperationException("Expression keys not yet implemented");
    }

    @Override
    public boolean areCompatibale(Keys<?> other) {
      throw new UnsupportedOperationException("Expression keys not yet implemented");
    }

    @Override
    public int[] computeLogicalKeyPositions() {
      throw new UnsupportedOperationException("Expression keys not yet implemented");
    }
  }
 
 
  // --------------------------------------------------------------------------------------------
  //  Utilities
  // --------------------------------------------------------------------------------------------
 
  private static int[] makeFields(int[] fields, TupleTypeInfo<?> type) {
    int inLength = type.getArity();
   
    // null parameter means all fields are considered
    if (fields == null || fields.length == 0) {
      fields = new int[inLength];
      for (int i = 0; i < inLength; i++) {
        fields[i] = i;
      }
      return fields;
    } else {
      return rangeCheckAndOrderFields(fields, inLength-1);
    }
  }
 
  private static final int[] rangeCheckAndOrderFields(int[] fields, int maxAllowedField) {
    // order
    Arrays.sort(fields);
   
    // range check and duplicate eliminate
    int i = 1, k = 0;
    int last = fields[0];
   
    if (last < 0 || last > maxAllowedField) {
      throw new IllegalArgumentException("Tuple position is out of range.");
    }
   
    for (; i < fields.length; i++) {
      if (fields[i] < 0 || i > maxAllowedField) {
        throw new IllegalArgumentException("Tuple position is out of range.");
      }
     
      if (fields[i] != last) {
        k++;
        fields[k] = fields[i];
      }
    }
   
    // check if we eliminated something
    if (k == fields.length - 1) {
      return fields;
    } else {
      return Arrays.copyOfRange(fields, 0, k);
    }
  }
}
TOP

Related Classes of eu.stratosphere.api.java.operators.Keys

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.