static byte[][] splitJobKey(byte[] rawKey) {
    byte[][] splits = ByteUtil.split(rawKey, Constants.SEP_BYTES, 4);

    /* final components (runId!jobId!additional) need to be split separately for correct
     * handling of runId long encoding */
    if (splits.length == 4) {
      // TODO: this splitting is getting really ugly, look at using Orderly instead for keying
      byte[] remainder = splits[3];
      byte[][] extraComponents = new byte[3][];

      int offset = 0;
      // run ID
      extraComponents[0] = ByteUtil.safeCopy(remainder, offset, 8);
      // followed by sep + job epoch + job seq
      offset += 8+Constants.SEP_BYTES.length;
      extraComponents[1] = ByteUtil.safeCopy(remainder, offset, 16);
      offset += 16+Constants.SEP_BYTES.length;
      // followed by any remainder
      extraComponents[2] = ByteUtil.safeCopy(remainder, offset, remainder.length - offset);

      int extraSize = 0;
      // figure out the full size of all splits
      for (int i=0; i < extraComponents.length; i++) {
        if (extraComponents[i] != null) {
          extraSize++;
        } else {
          break; // first null signals hitting the end of remainder
        }
      }

      byte[][] allComponents = new byte[3+extraSize][];
      // fill in the first 3 elts
      for (int i=0; i < 3; i++) {
        allComponents[i] = splits[i];
      }
      // add any extra that were non-null
      for (int i=0; i < extraSize; i++) {
        allComponents[3+i] = extraComponents[i];
      }

      return allComponents;
    }
    return splits;
  }
static byte [ ] [ ] splitJobKey ( byte [ ] rawKey ) { byte [ ] [ ] splits = ByteUtil . split ( rawKey , Constants . SEP_BYTES , 4 ) ; if ( splits . length == 4 ) { byte [ ] remainder = splits [ 3 ] ; byte [ ] [ ] extraComponents = new byte [ 3 ] [ ] ; int offset = 0 ; extraComponents [ 0 ] = ByteUtil . safeCopy ( remainder , offset , 8 ) ; offset += 8 + Constants . SEP_BYTES . length ; extraComponents [ 1 ] = ByteUtil . safeCopy ( remainder , offset , 16 ) ; offset += 16 + Constants . SEP_BYTES . length ; extraComponents [ 2 ] = ByteUtil . safeCopy ( remainder , offset , remainder . length - offset ) ; int extraSize = 0 ; for ( int i = 0 ; i < extraComponents . length ; i ++ ) { if ( extraComponents [ i ] != null ) { extraSize ++ ; } else { break ; } } byte [ ] [ ] allComponents = new byte [ 3 + extraSize ] [ ] ; for ( int i = 0 ; i < 3 ; i ++ ) { allComponents [ i ] = splits [ i ] ; } for ( int i = 0 ; i < extraSize ; i ++ ) { allComponents [ 3 + i ] = extraComponents [ i ] ; } return allComponents ; } return splits ; }
Handles splitting the encoded job key correctly, accounting for long
encoding of the run ID.  Since the long encoding of the run ID may
legitimately contain the separator bytes, we first split the leading 3
elements (cluster!user!appId), then split out the runId and remaining
fields based on the encoded long length;

@param rawKey byte encoded representation of the job key
@return