hadoop TimelineReaderUtils 源码

  • 2022-10-20
  • 浏览 (237)

haddop TimelineReaderUtils 代码

文件路径:/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-timelineservice/src/main/java/org/apache/hadoop/yarn/server/timelineservice/reader/TimelineReaderUtils.java

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.hadoop.yarn.server.timelineservice.reader;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import org.apache.hadoop.classification.VisibleForTesting;

/**
 * Set of utility methods to be used across timeline reader.
 */
public final class TimelineReaderUtils {
  private TimelineReaderUtils() {
  }

  /**
   * Default delimiter for joining strings.
   */
  @VisibleForTesting
  public static final char DEFAULT_DELIMITER_CHAR = '!';

  /**
   * Default escape character used for joining strings.
   */
  @VisibleForTesting
  public static final char DEFAULT_ESCAPE_CHAR = '*';

  public static final String FROMID_KEY = "FROM_ID";

  @VisibleForTesting
  public static final String UID_KEY = "UID";

  /**
   * Split the passed string along the passed delimiter character while looking
   * for escape char to interpret the splitted parts correctly. For delimiter or
   * escape character to be interpreted as part of the string, they have to be
   * escaped by putting an escape character in front.
   * @param str string to be split.
   * @param delimiterChar delimiter used for splitting.
   * @param escapeChar delimiter and escape character will be escaped using this
   *     character.
   * @return a list of strings after split.
   * @throws IllegalArgumentException if string is not properly escaped.
   */
  static List<String> split(final String str, final char delimiterChar,
      final char escapeChar) throws IllegalArgumentException {
    if (str == null) {
      return null;
    }
    int len = str.length();
    if (len == 0) {
      return Collections.emptyList();
    }
    List<String> list = new ArrayList<String>();
    // Keeps track of offset of the passed string.
    int offset = 0;
    // Indicates start offset from which characters will be copied from original
    // string to destination string. Resets when an escape or delimiter char is
    // encountered.
    int startOffset = 0;
    StringBuilder builder = new StringBuilder(len);
    // Iterate over the string till we reach the end.
    while (offset < len) {
      if (str.charAt(offset) == escapeChar) {
        // An escape character must be followed by a delimiter or escape char
        // but we have reached the end and have no further character to look at.
        if (offset + 1 >= len) {
          throw new IllegalArgumentException(
              "Escape char not properly escaped.");
        }
        char nextChar = str.charAt(offset + 1);
        // Next character must be a delimiter or an escape char.
        if (nextChar != escapeChar && nextChar != delimiterChar) {
          throw new IllegalArgumentException(
              "Escape char or delimiter char not properly escaped.");
        }
        // Copy contents from the offset where last escape or delimiter char was
        // encountered.
        if (startOffset < offset) {
          builder.append(str.substring(startOffset, offset));
        }
        builder.append(nextChar);
        offset += 2;
        // Reset the start offset as an escape char has been encountered.
        startOffset = offset;
        continue;
      } else if (str.charAt(offset) == delimiterChar) {
        // A delimiter has been encountered without an escape character.
        // String needs to be split here. Copy remaining chars and add the
        // string to list.
        builder.append(str.substring(startOffset, offset));
        list.add(builder.toString().trim());
        // Reset the start offset as a delimiter has been encountered.
        startOffset = ++offset;
        builder = new StringBuilder(len - offset);
        continue;
      }
      offset++;
    }
    // Copy rest of the characters.
    if (!str.isEmpty()) {
      builder.append(str.substring(startOffset));
    }
    // Add the last part of delimited string to list.
    list.add(builder.toString().trim());
    return list;
  }

  private static String escapeString(final String str, final char delimiterChar,
      final char escapeChar) {
    if (str == null) {
      return null;
    }
    int len = str.length();
    if (len == 0) {
      return "";
    }
    StringBuilder builder = new StringBuilder();
    // Keeps track of offset of the passed string.
    int offset = 0;
    // Indicates start offset from which characters will be copied from original
    // string to destination string. Resets when an escape or delimiter char is
    // encountered.
    int startOffset = 0;
    // Iterate over the string till we reach the end.
    while (offset < len) {
      char charAtOffset = str.charAt(offset);
      if (charAtOffset == escapeChar || charAtOffset == delimiterChar) {
        // If an escape or delimiter character is encountered, copy characters
        // from the offset where escape or delimiter was last encountered.
        if (startOffset < offset) {
          builder.append(str.substring(startOffset, offset));
        }
        // Append escape char before delimiter/escape char.
        builder.append(escapeChar).append(charAtOffset);
        // Reset start offset for copying characters when next escape/delimiter
        // char is encountered.
        startOffset = offset + 1;
      }
      offset++;
    }
    // Copy remaining characters.
    builder.append(str.substring(startOffset));
    return builder.toString();
  }

  /**
   * Join different strings in the passed string array delimited by passed
   * delimiter with delimiter and escape character escaped using passed escape
   * char.
   * @param strs strings to be joined.
   * @param delimiterChar delimiter used to join strings.
   * @param escapeChar escape character used to escape delimiter and escape
   *     char.
   * @return a single string joined using delimiter and properly escaped.
   */
  static String joinAndEscapeStrings(final String[] strs,
      final char delimiterChar, final char escapeChar) {
    int len = strs.length;
    // Escape each string in string array.
    for (int index = 0; index < len; index++) {
      if (strs[index] == null) {
        return null;
      }
      strs[index] = escapeString(strs[index], delimiterChar, escapeChar);
    }
    // Join the strings after they have been escaped.
    return StringUtils.join(strs, delimiterChar);
  }

  public static List<String> split(final String str)
      throws IllegalArgumentException {
    return split(str, DEFAULT_DELIMITER_CHAR, DEFAULT_ESCAPE_CHAR);
  }

  public static String joinAndEscapeStrings(final String[] strs) {
    return joinAndEscapeStrings(strs, DEFAULT_DELIMITER_CHAR,
        DEFAULT_ESCAPE_CHAR);
  }
}

相关信息

hadoop 源码目录

相关文章

hadoop TimelineDataToRetrieve 源码

hadoop TimelineEntityFilters 源码

hadoop TimelineFromIdConverter 源码

hadoop TimelineParseConstants 源码

hadoop TimelineParseException 源码

hadoop TimelineParser 源码

hadoop TimelineParserForCompareExpr 源码

hadoop TimelineParserForDataToRetrieve 源码

hadoop TimelineParserForEqualityExpr 源码

hadoop TimelineParserForExistFilters 源码

0  赞