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

net.sf.eBus.config.ENetConfigure Maven / Gradle / Ivy

//
// Copyright 2015, 2016 Charles W. Rapp
//
// 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 net.sf.eBus.config;

import com.google.common.base.Strings;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigException;
import com.typesafe.config.ConfigFactory;
import com.typesafe.config.ConfigObject;
import java.io.File;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * This immutable class contains selector thread configuration
 * extracted from properties. Selector threads configuration is
 * taken from the typesafe JSON file specified by the command
 * line parameter
 * {@code -Dnet.sf.eBus.config.jsonFile=}<conf file path>.
 * Selector threads may not be created at runtime but
 * only on JVM start up. That said, selector threads are not
 * started on JVM start time but only when its name referenced by
 * an {@code AsyncChannel}. So if no channels use the selector
 * during an application run, then the thread is never started.
 * 

* Selector thread configuration uses the following property * keys: *

*
    *
  • * {@code eBus.net.selectors}: a comma-separated list of * selector thread names. The names should be unique (no * duplicates). All duplicates are logged and ignored. The * selector thread name is used to retrieve the remaining * keys. *
  • *
  • * {@code eBus.net.selector}.name.{@code type}: * The selector thread type must be one of {@link ThreadType}. *

    * This property is required. *

    *
  • *
  • * {@code eBus.net.selector}.name.{@code isDefault}: * Set to "true" if this is the default selector. The default * selector is used by all {@code AsyncChannels} not * explicitly assigned to a selector. If multiple selectors * are designated as the default, then it cannot be determined * which selector will be used as the default. *

    * The default value for this setting is {@code false}. *

    *
  • *
  • * {@code eBus.net.selector}.name.{@code priority}: * The selector thread runs at this thread priority. The * specified value must be ≥ {@link Thread#MIN_PRIORITY} * and ≤ {@link Thread#MAX_PRIORITY}. *

    * The default value for this setting is * {@link Thread#NORM_PRIORITY}. *

    *
  • *
  • * {@code eBus.net.selector}.name.{@code spinLimit}: * If {@code type} is {@link ThreadType#SPINPARK}, then this * property specifies the number of times the thread will spin * on {@link java.nio.channels.Selector#selectNow()} before * parking. *

    * The default value is {@link #DEFAULT_SPIN_LIMIT}. *

    *
  • *
  • * {@code eBus.net.selector}.name.{@code parkTime}: * If {@code type} is {@link ThreadType#SPINPARK}, then this * property specifies the number of nanoseconds the thread * will park before returning to spinning. *

    * The default value is {@link #DEFAULT_PARK_TIME}. *

    *
  • *
*

*

*

* Example select thread configuration: *

*
selectors : [
    {
        name : faster     // required, must be unique.
        type : spinning   // required.
        isDefault : false // optional, defaults to false.
        priority : 10     // optional, defaults to Thread.NORM_PRIORITY
    },
    {
        name : slower
        type" : "spin+park"
        isDefault : true
        priority : 7
        spinLimit : 1000000
        parkTime : 500ns
    }
]
* * @see SelectorInfo * @see SelectorInfoBuilder * * @author Charles W. Rapp */ public final class ENetConfigure { //--------------------------------------------------------------- // Member data. // //----------------------------------------------------------- // Constants. // /** * The minimum allowed port number is zero. */ public static final int MIN_PORT = 0; /** * The maximum allowed port number is 65,535. */ public static final int MAX_PORT = 65535; /** * Use the value {@value} to specify socket is opened and * bound to any port. */ public static final int ANY_PORT = 0; // // System property keys. // // Property keys. /** * The key {@code eBus.net.selectors} contains a * comma-separated list of selector thread names. */ public static final String SELECTORS_KEY = "selectors"; /** * Selector keys are prefixed by {@code eBus.net.selector.} * and followed by a selector thread, which must appear in * the {@link #SELECTORS_KEY} property. */ public static final String SELECTOR_PREFIX = "eBus.net.selector"; /** * The {@value} property is used to specify the unique * selector name. Uniqueness is within the JVM. *

* This property is required. *

*/ public static final String NAME_KEY = "name"; /** * The {@link ThreadType type} property is used to specify * the {@code ESelector} used with the selector thread. *

* This property is required. *

*/ public static final String TYPE_KEY = "type"; /** * The boolean {@value} property is used to * specify when this selector thread should be used as the * default selector thread. At most one selector should be * designated as the default selector. If more than one is * so designated, the subsequent {@code .isDefault} keys are * ignored. *

* If no user-defined selector is marked as default, then * a {@link ThreadType#BLOCKING blocking}, * {@link Thread#NORM_PRIORITY normal priority} selector * named {@code AsyncChannel.sDefaultSelector} is used as the * default selector. *

*

* The default value is {@code false} * (not the default selector). *

*/ public static final String DEFAULT_KEY = "isDefault"; /** * The integer {@value} property is used to * set the select thread priority. *

* The default value is {@link Thread#NORM_PRIORITY}. *

*/ public static final String PRIORITY_KEY = "priority"; /** * If the selector type is * {@link ThreadType#SPINPARK spin+park}, then the * integer {@value} property may be specified. This * setting defines the number of times the selector thread * may call * {@link java.nio.channels.Selector#selectNow()} before * parking. *

* This value must be > zero. *

*

* Default values is {@link #DEFAULT_SPIN_LIMIT}. *

*

* This property is ignored is the selector type is not * spin+park. *

*/ public static final String SPIN_LIMIT_KEY = "spinLimit"; /** * If the selector type is * {@link ThreadType#SPINPARK spin+park}, then the * integer {@value} property may be specified. This * setting specifies the nanosecond park time taken * between * {@link java.nio.channels.Selector#selectNow()} spin * cycles. *

* This value must be > zero. *

*

* Default values is {@link #DEFAULT_PARK_TIME}. *

*

* This property is ignored is the selector type is not * spin+park. *

*/ public static final String PARK_TIME_KEY = "parkTime"; /** * Optional thread affinity configuration. May be * {@code null}. Thread affinity is best used when thread * type is {@link ThreadType#SPINNING}. */ public static final String AFFINITY_KEY = "threadAffinity"; // // Default values. // /** * The default selector thread priority is * {@link Thread#NORM_PRIORITY normal}. */ public static final int DEFAULT_PRIORITY = Thread.NORM_PRIORITY; /** * The default select spin limit is {@value} calls to * {@link java.nio.channels.Selector#selectNow()} before * parking the thread. */ public static final int DEFAULT_SPIN_LIMIT = 2_500_000; /** * The default thread park time is 1 microsecond. */ public static final Duration DEFAULT_PARK_TIME = Duration.ofNanos(1_000L); /** * The default input and output socket buffer size is * {@value} bytes. */ public static final int DEFAULT_BUFFER_SIZE = 2_048; /** * The default selector type is * {@link ThreadType#BLOCKING}. */ public static final ThreadType DEFAULT_SELECTOR_TYPE = ThreadType.BLOCKING; /** * The default selector thread name is "__DEFAULT__". * The default selector type is * {@link ThreadType#BLOCKING blocking}. */ private static final String DEFAULT_SELECTOR = "eBus:selectorThread:__DEFAULT__"; //----------------------------------------------------------- // Statics. // /** * The default selector name as defined in the eBus * configuration file. */ private static SelectorInfo sDefaultSelector; /** * The user-defined selectors mapped by selector name. * May be empty. */ private static Map sSelectors; // Class static initialization static { final String jsonFile = System.getProperty(EConfigure.JSON_FILE_ENV); sDefaultSelector = null; // Load the eBus configuration if specified on the // command line and fill in the selectors. if (!Strings.isNullOrEmpty(jsonFile)) { loadJsonFile(jsonFile); } // Was a default selector specified? if (sDefaultSelector == null) { // No. Then set the default selector information to // a blocking selector with normal priority. final SelectorInfoBuilder builder = new SelectorInfoBuilder(); sDefaultSelector = builder.name(DEFAULT_SELECTOR) .type(DEFAULT_SELECTOR_TYPE) .isDefault(true) .priority(Thread.NORM_PRIORITY) .build(); } if (sSelectors == null) { final Map selectors = new HashMap<>(1); selectors.put( sDefaultSelector.name(), sDefaultSelector); sSelectors = Collections.unmodifiableMap(selectors); } } // end of class static initialization. //--------------------------------------------------------------- // Member methods. // //----------------------------------------------------------- // Constructors. // /** * Private constructor to prevent instantiation. */ private ENetConfigure() {} // // end of Constructors. //----------------------------------------------------------- //----------------------------------------------------------- // Get Methods. // public static SelectorInfo defaultSelector() { return (sDefaultSelector); } // end of defaultSelector() /** * Returns {@code true} if {@code name} is a known selector * and {@code false} if not known. * @param name the name to be checked. * @return {@code true} if {@code name} is a known selector. */ public static boolean isKnownSelector(final String name) { return (sSelectors.containsKey(name)); } // end of isKnownSelector(String) /** * Returns the selector for the given name; * returns {@code null} if {@code name} does not reference * a known selector. * @param name selector name. * @return configured selector information. */ public static SelectorInfo selector(final String name) { return (sSelectors.get(name)); } // end of selector(String) /** * Returns the selector thread configurations. The returned * list is unmodifiable. * @return selector thread configurations. */ public static Map selectors() { return (sSelectors); } // end of selectors() /** * Returns the loaded network configuration as text. * @return textual representation of network configuration. */ public static String asText() { String sep = ""; final StringBuilder retval = new StringBuilder(); for (SelectorInfo info : sSelectors.values()) { retval.append(sep).append(info); sep = "\n"; } return (retval.toString()); } // end of asText() // // end of Get Methods. //----------------------------------------------------------- /** * Returns a selector thread configuration extracted from the * given JSON properties. * @param config JSON configuration. */ public static void load(final Config config) { SelectorInfo selector; final Map selectors = new HashMap<>(); // Are any selectors defined? if (config.hasPath(SELECTORS_KEY)) { // Yes. Load each selector in turn. for (ConfigObject co : config.getObjectList(SELECTORS_KEY)) { selector = loadInfo(co.toConfig()); selectors.put(selector.name(), selector); } } sSelectors = Collections.unmodifiableMap(selectors); } // end of load(Config) /** * Returns a builder used to create a {@link SelectorInfo} * instance. * @return {@link SelectorInfo} builder. */ public static SelectorInfoBuilder selectorBuilder() { return (new SelectorInfoBuilder()); } // end of selectorBuilder() /** * Sets the eBus network selectors to the given map. Used for * testing purposes only. * @param selectors network selectors map. * @throws IllegalArgumentException * if {@code selectors} is either {@code null} or empty. */ /* package */ static void load(final Map selectors) { if (selectors == null || selectors.isEmpty()) { throw ( new IllegalArgumentException( "selectors is null or empty")); } sSelectors = Collections.unmodifiableMap(selectors); selectors.values() .stream() .filter(selector -> (selector.isDefault())) .forEachOrdered( selector -> sDefaultSelector = selector); } // end of load(Map) /** * Initializes the eBus network configuration from the * typesafe JSON configuration file. * @param jsonFileName JSON configuration file. */ private static void loadJsonFile(final String jsonFileName) { final File jsonFile = new File(jsonFileName); final Config netConfig = ConfigFactory.parseFile(jsonFile); ENetConfigure.load(netConfig); } // end of loadJsonFile(String) /** * Returns a single {@link SelectorInfo} instance loaded * from the given JSON configuration. * @param config JSON configuration for a single selector. * @return selector information. * @throws ConfigException * if {@code config} contains an invalid selector * configuration. */ private static SelectorInfo loadInfo(final Config config) { final String value = config.getString(TYPE_KEY); final ThreadType type = ThreadType.find(value); final SelectorInfoBuilder builder = new SelectorInfoBuilder(); if (type == null) { throw ( new ConfigException.BadValue( TYPE_KEY, "\"" + value + "\" is not a valid selector type")); } builder.name(config.getString(NAME_KEY)) .type(type) .isDefault(config.getBoolean(DEFAULT_KEY)) .priority(config.hasPath(PRIORITY_KEY) ? config.getInt(PRIORITY_KEY) : DEFAULT_PRIORITY) .threadAffinity( ThreadAffinityConfigure.loadAffinity( AFFINITY_KEY, config)); if (builder.mType == ThreadType.SPINPARK || builder.mType == ThreadType.SPINYIELD) { builder.spinLimit(config.hasPath(SPIN_LIMIT_KEY) ? config.getLong(SPIN_LIMIT_KEY) : DEFAULT_SPIN_LIMIT); } if (builder.mType == ThreadType.SPINPARK) { builder.parkTime(config.hasPath(PARK_TIME_KEY) ? config.getDuration(PARK_TIME_KEY) : DEFAULT_PARK_TIME); } return (builder.build()); } // end of loadInfo(Config) //--------------------------------------------------------------- // Inner classes. // /** * Constructs an {@link SelectorInfo} instance based on the * parameters set via the builder's API. The minimally * allowed configuration is based on the selector's thread * type. In all cases a unique selector name and type must be * provided. The selector parameters are: *
    *
  • * name: unique selector name. * Uniqueness is within the JVM. *

    * Required: Yes. *

    *
  • *
  • * type: selector * {@link ThreadType thread type}. *

    * Required: Yes. *

    *
  • *
  • * isDefault: if set to {@code true}, * then this is the default selector for all channels * which do not specify a selector. *

    * Required: No. *

    *

    * Default Setting: {@code false}. *

    *
  • *
  • * priority: the selector thread's * priority. Should be one of {@link Thread#MIN_PRIORITY}, * {@link Thread#NORM_PRIORITY}, or * {@link Thread#MAX_PRIORITY}. *

    * Required: No. *

    *

    * Default Setting: * {@link #DEFAULT_PRIORITY}. *

    *
  • *
  • * spinLimit: number of times a selector * thread may spin before parking. *

    * Required: No. *

    *

    * Default Setting: * {@link #DEFAULT_SPIN_LIMIT}. *

    *
  • *
  • * parkTime: nanosecond duration for a * selector park. *

    * Required: No. *

    *

    * Default Setting: * {@link #DEFAULT_PARK_TIME}. *

    *
  • *
  • * threadAffinity: * {@link ThreadAffinityConfigure} used to associate * selector thread with a core. Thread affinity should be * considered when using a spinning thread type. *

    * Required: No. *

    *

    * Default Setting: {@code null}. *

    *
  • *
*

Example building a {@code SelectorInfo}

*
 final ENetConfigure.SelectorInfoBuilder builder = ENetConfigure.selectorBuilder();
     * final ENetConfigure.SelectorInfo selectorInfo = builder.name("app_selector")
     *                                                        .type(ThreadType.SPINPARK)
     *                                                        .isDefault(true)
     *                                                        .spinLimit(2_000_000L)
     *                                                        .parkTime(500L)
     *                                                        .build();
*/ public static final class SelectorInfoBuilder { //----------------------------------------------------------- // Member data. // //------------------------------------------------------- // Locals. // /** * The selector thread's unique name. */ private String mName; /** * The select thread's encapsulated {@link ESelector} * type. */ private ThreadType mType; /** * {@code true} if this selector thread is used as the * default. */ private boolean mIsDefault; /** * The selector thread priority. */ private int mPriority; /** * The spin limit for a * {@link ThreadType#SPINPARK spin+park} selector * type. */ private long mSpinLimit; /** * The park time for a * {@link ThreadType#SPINPARK spin+park} selector * type. */ private Duration mParkTime; /** * Optional thread affinity configuration. Defaults to * {@code null}. Thread affinity should be considered * when using {@link ThreadType#SPINNING} thread type. */ private ThreadAffinityConfigure mAffinity; //----------------------------------------------------------- // Member methods. // //------------------------------------------------------- // Constructors. // /** * Creates a {@link SelectorInfo} builder setting fields * to default values. */ private SelectorInfoBuilder() { mName = null; mType = null; mPriority = DEFAULT_PRIORITY; mIsDefault = false; mSpinLimit = 0L; mParkTime = Duration.ZERO; } // end of SelectorInfoBuilder() // // end of Constructors. //------------------------------------------------------- //------------------------------------------------------- // Set Methods. // /** * Sets the selector name to the given value. * @param name selector name. * @return {@code this SelectorInfoBuilder}. * @throws ConfigException * if {@code name} is either {@code null} or an empty * string. */ public SelectorInfoBuilder name(final String name) { if (Strings.isNullOrEmpty(name)) { throw ( new ConfigException.BadValue( NAME_KEY, "\"" + name + "\" is null or empty")); } mName = name; return (this); } // end of name(String) /** * Sets the selector thread type to the given value. * @param type selector thread type. * @return {@code this SelectorInfoBuilder}. * @throws ConfigException * if {@code type} is {@code null}. */ public SelectorInfoBuilder type(final ThreadType type) { if (type == null) { throw ( new ConfigException.BadValue( EConfigure.THREAD_TYPE_KEY, "type is null")); } mType = type; return (this); } // end of type(ThreadType) /** * Sets the selector flag marking whether this is the * default selector or not. * @param flag {@code true} if this is the default * selector thread. * @return {@code this SelectorInfoBuilder}. */ public SelectorInfoBuilder isDefault(final boolean flag) { mIsDefault = flag; return (this); } // end of isDefault(boolean) /** * Sets the selector thread priority to the given value. * @param priority thread priority. * @return {@code this SelectorInfoBuilder}. * @throws ConfigException * if {@code priority} is < {@link Thread#MIN_PRIORITY} * or > {@link Thread#MAX_PRIORITY}. */ public SelectorInfoBuilder priority(final int priority) { if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) { throw ( new ConfigException.BadValue( PRIORITY_KEY, String.format( "%d is not valid; must be >= %d and <= %d", priority, Thread.MIN_PRIORITY, Thread.MAX_PRIORITY))); } mPriority = priority; return (this); } // end of priority(int) /** * Sets a spinning selector thread's spin limit. * @param limit number of time the thread may spin on * select before parking. * @return {@code this SelectorInfoBuilder}. * @throws ConfigException * if {@code limit} is ≤ zero. */ public SelectorInfoBuilder spinLimit(final long limit) { if (limit < 0L) { throw ( new ConfigException.BadValue( SPIN_LIMIT_KEY, limit + " < zero")); } // If the spin limit is zero, then use the default // setting. mSpinLimit = (limit == 0L ? DEFAULT_SPIN_LIMIT : limit); return (this); } // end of spinLimit(long) /** * Sets a spin+park selector thread's park time. * @param time nanosecond thread park time. * @return {@code this SelectorInfoBuilder}. * @throws ConfigException * if {@code time} is {@code null} or ≤ zero. */ public SelectorInfoBuilder parkTime(final Duration time) { if (time == null) { throw ( new ConfigException.BadValue( PARK_TIME_KEY, time + " is null")); } if (time.isNegative()) { throw ( new ConfigException.BadValue( PARK_TIME_KEY, time + " < zero")); } // If the park time is zero, then use the default // setting. mParkTime = (time.isZero() ? DEFAULT_PARK_TIME : time); return (this); } // end of parkTime(Duration) /** * Sets thread affinity configuration. * @param affinity thread affinity configuration. May be * {@code null}. * @return {@code this SelectorInfoBuilder}. */ public SelectorInfoBuilder threadAffinity(final ThreadAffinityConfigure affinity) { mAffinity = affinity; return (this); } // end of threadAffinity(ThreadAffinityConfigure) // // end of Set Methods. //------------------------------------------------------- /** * Returns the {@link SelectorInfo} instance created from * the configuration settings. Sets spin limit for * spin/park and spin/yield thread types to * {@link #DEFAULT_SPIN_LIMIT} if spin limit is not set. * Sets park time to {@link #DEFAULT_PARK_TIME} if not * configured for spin/park thread type. * @return {@code SelectorInfo} instance. * @throws ConfigException * if {@code SelectorInfo} configuration is invalid. */ public SelectorInfo build() { validate(); // If spin limit and park time are not set, then // use the default settings. if ((mType == ThreadType.SPINPARK || mType == ThreadType.SPINYIELD) && mSpinLimit == 0L) { mSpinLimit = DEFAULT_SPIN_LIMIT; } if (mType == ThreadType.SPINPARK && mParkTime.isZero()) { mParkTime = DEFAULT_PARK_TIME; } return (new SelectorInfo(this)); } // end of build() /** * This method validates the selector configuration and * returns if the configuration passes. Otherwise throws * an {@code ConfigException}. This method is called for * effect only. * @throws ConfigException * if {@code SelectorInfo} configuration is invalid. */ private void validate() { if (mName == null) { throw ( new ConfigException.BadValue( NAME_KEY, "selector name not configured")); } if (mType == null) { throw ( new ConfigException.BadValue( TYPE_KEY, "selector type not configured")); } } // end of validate() } // end of class SelectorInfoBuilder /** * This immutable class contains the selector thread * configuration for the named selector. This includes: *
    *
  • * a unique selector name, *
  • *
  • * the selector {@link ThreadType thread type}, *
  • *
  • * a flag specifying whether this is the default selector * or not, *
  • *
  • * the spin limit used for {@link ThreadType#SPINPARK} * and {@link ThreadType#SPINYIELD} selectors, and *
  • *
  • * the nanosecond park time limit used for * {@link ThreadType#SPINPARK} selectors. *
  • *
*

* An example {@code SelectorInfo} configuration follows: *

*
name : s1
type : "spin+park"
isDefault : true
priority : 7
spinLimit : 1000000
parkTime : 500ns
*/ public static final class SelectorInfo implements Comparable { //----------------------------------------------------------- // Member data. // //------------------------------------------------------- // Locals. // /** * The selector thread's unique name. */ private final String mName; /** * The select thread's encapsulated {@link ESelector} * type. */ private final ThreadType mType; /** * {@code true} if this selector thread is used as the * default. */ private final boolean mIsDefault; /** * The selector thread priority. */ private final int mPriority; /** * The spin limit for a * {@link ThreadType#SPINPARK spin+park} selector * type. */ private final long mSpinLimit; /** * The park time for a * {@link ThreadType#SPINPARK spin+park} selector * type. */ private final Duration mParkTime; /** * Optional thread affinity configuration. Defaults to * {@code null}. Thread affinity should be considered * when using {@link ThreadType#SPINNING} thread type. */ private final ThreadAffinityConfigure mAffinity; //----------------------------------------------------------- // Member methods. // //------------------------------------------------------- // Constructors. // /** * Creates a new selector thread configuration from the * given builder settings. * @param builder contains selector thread settings. */ private SelectorInfo(final SelectorInfoBuilder builder) { mName = builder.mName; mType = builder.mType; mIsDefault = builder.mIsDefault; mPriority = builder.mPriority; mSpinLimit = builder.mSpinLimit; mParkTime = builder.mParkTime; mAffinity = builder.mAffinity; } // end of SelectorInfo(...) // // end of Constructors. //------------------------------------------------------- //------------------------------------------------------- // Comparable Interface Implementation. // /** * Compares {@code this} object with the specified * selector. Returns negative, zero, or positive integer * value based on whether {@code this} object is <, * equal to, or > {@code selector}. Comparison is * based on on the selector name. * @param selector object used in the comparison. * @return a negative, zero, or positive integer value. */ @Override public int compareTo(final SelectorInfo selector) { return (mName.compareTo(selector.mName)); } // end of compareTo(SelectorInfo) // // end of Comparable Interface Implementation. //------------------------------------------------------- //------------------------------------------------------- // Object Method Overrides. // /** * Returns {@code true} if {@code this} object equals * {@code o} and {@code false} otherwise. Comparison is * based on the name, thread type, "is default" flag, * thread priority, spin limit and park time. * @param o comparison object. * @return {@code true} if {@code o} is a * {@code SelectorInfo} instance with the same settings * as {@code this SelectorInfo} instance. */ @Override public boolean equals(final Object o) { boolean retcode = (this == o); if (!retcode && o instanceof SelectorInfo) { final SelectorInfo si = (SelectorInfo) o; retcode = (mName.equals(si.name()) && mType == si.type() && mIsDefault == si.isDefault() && mPriority == si.priority() && mSpinLimit == si.spinLimit() && Objects.equals( mParkTime, si.mParkTime) && Objects.equals(mAffinity, si.mAffinity)); } return (retcode); } // end of equals(Object) /** * Returns a hash code for this object. The hash is based * on the selector name, thread type, "is default" flag, * thread priority, spin limit, and park time. * @return object hash code. */ @Override public int hashCode() { return (Objects.hash(mName, mType, mIsDefault, mPriority, mSpinLimit, mParkTime, mAffinity)); } // end of hashCode() /** * Returns a string representation of this selector * info. * @return object string representation. */ @Override public String toString() { final StringBuilder retval = new StringBuilder(); retval.append('[') .append(mName) .append("]\nselector type: ") .append(mType) .append("\n priority: ") .append(mPriority) .append("\n is default: ") .append(mIsDefault); if (mType == ThreadType.SPINPARK) { retval.append("\n spin limit: ") .append(String.format("%,d", mSpinLimit)) .append("\n park time: ") .append(mParkTime); } if (mAffinity != null) { retval.append("\n affinity: ") .append(mAffinity); } return (retval.toString()); } // end of toString() // // end of Object Method Overrides. //------------------------------------------------------- //------------------------------------------------------- // Get Methods. // /** * Returns the unique selector thread name. * @return selector thread name. */ public String name() { return (mName); } // end of name() /** * Returns the {@code ESelector} type. * @return selector type. */ public ThreadType type() { return (mType); } // end of type() /** * Returns {@code true} if this user-defined selector * thread is the default selector. * @return {@code true} if the default selector thread. */ public boolean isDefault() { return (mIsDefault); } // end of isDefault() /** * Returns the selector thread priority. * @return thread priority. */ public int priority() { return (mPriority); } // end of priority() /** * Returns a spin+park {@code ESelector} spin limit. * @return spin limit. */ public long spinLimit() { return (mSpinLimit); } // end of spinLimit() /** * Returns the spin+park park time limit. * @return park time limit. */ public Duration parkTime() { return (mParkTime); } // end of parkTime() /** * Returns thread affinity and {@code null} if no * affinity is set. This affinity is used to associate a * thread with a particular CPU. * @return thread affinity. */ public ThreadAffinityConfigure affinity() { return (mAffinity); } // end of affinity() // // end of Get Methods. //------------------------------------------------------- } // end of class SelectorInfo } // end of class ENetConfigure




© 2015 - 2025 Weber Informatics LLC | Privacy Policy