All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.hadoop.yarn.util.BoundedAppender Maven / Gradle / Ivy

There is a newer version: 3.4.1
Show newest version
/**
 * 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 org.apache.hadoop.shaded.com.liance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org.apache.hadoop.shaded.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.shaded.org.apache.hadoop.yarn.util;

import org.apache.hadoop.shaded.org.apache.hadoop.thirdparty.org.apache.hadoop.shaded.com.google.org.apache.hadoop.shaded.com.on.annotations.VisibleForTesting;
import org.apache.hadoop.shaded.org.apache.hadoop.thirdparty.org.apache.hadoop.shaded.com.google.org.apache.hadoop.shaded.com.on.base.Preconditions;
import org.apache.hadoop.shaded.org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.shaded.org.apache.hadoop.classification.InterfaceStability;

/**
 * A {@link CharSequence} appender that considers its {@link #limit} as upper
 * bound.
 * 

* When {@link #limit} would be reached on append, past messages will be * truncated from head, and a header telling the user about truncation will be * prepended, with ellipses in between header and messages. *

* Note that header and ellipses are not counted against {@link #limit}. *

* An example: * *

 * {@code
 *   // At the beginning it's an empty string
 *   final Appendable shortAppender = new BoundedAppender(80);
 *   // The whole message fits into limit
 *   shortAppender.append(
 *       "message1 this is a very long message but fitting into limit\n");
 *   // The first message is truncated, the second not
 *   shortAppender.append("message2 this is shorter than the previous one\n");
 *   // The first message is deleted, the second truncated, the third
 *   // preserved
 *   shortAppender.append("message3 this is even shorter message, maybe.\n");
 *   // The first two are deleted, the third one truncated, the last preserved
 *   shortAppender.append("message4 the shortest one, yet the greatest :)");
 *   // Current contents are like this:
 *   // Diagnostic messages truncated, showing last 80 chars out of 199:
 *   // ...s is even shorter message, maybe.
 *   // message4 the shortest one, yet the greatest :)
 * }
 * 
*

* Note that null values are {@link #append(CharSequence) append}ed * just like in {@link StringBuilder#append(CharSequence) original * implementation}. *

* Note that this class is not thread safe. */ @InterfaceAudience.Public @InterfaceStability.Unstable @VisibleForTesting public class BoundedAppender { @VisibleForTesting public static final String TRUNCATED_MESSAGES_TEMPLATE = "Diagnostic messages truncated, showing last " + "%d chars out of %d:%n...%s"; private final int limit; private final StringBuilder messages = new StringBuilder(); private int totalCharacterCount = 0; public BoundedAppender(final int limit) { Preconditions.checkArgument(limit > 0, "limit should be positive"); this.limit = limit; } /** * Append a {@link CharSequence} considering {@link #limit}, truncating * from the head of {@code csq} or {@link #messages} when necessary. * * @param csq the {@link CharSequence} to append * @return this */ public BoundedAppender append(final CharSequence csq) { appendAndCount(csq); checkAndCut(); return this; } private void appendAndCount(final CharSequence csq) { final int before = messages.length(); messages.append(csq); final int after = messages.length(); totalCharacterCount += after - before; } private void checkAndCut() { if (messages.length() > limit) { final int newStart = messages.length() - limit; messages.delete(0, newStart); } } /** * Get current length of messages considering truncates * without header and ellipses. * * @return current length */ public int length() { return messages.length(); } public int getLimit() { return limit; } /** * Get a string representation of the actual contents, displaying also a * header and ellipses when there was a truncate. * * @return String representation of the {@link #messages} */ @Override public String toString() { if (messages.length() < totalCharacterCount) { return String.format(TRUNCATED_MESSAGES_TEMPLATE, messages.length(), totalCharacterCount, messages.toString()); } return messages.toString(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy