private void insertIntoTableKToV(int entry, int keyHash) {
    checkArgument(entry != ABSENT);
    int keyBucket = bucket(keyHash);
    nextInBucketKToV[entry] = hashTableKToV[keyBucket];
    hashTableKToV[keyBucket] = entry;
  }

private void insertIntoTableKToV ( int entry , int keyHash ) { checkArgument ( entry != ABSENT ) ; int keyBucket = bucket ( keyHash ) ; nextInBucketKToV [ entry ] = hashTableKToV [ keyBucket ] ; hashTableKToV [ keyBucket ] = entry ; }

Updates the K-to-V hash table to include the entry at the specified index, which is assumed to
have not yet been added.

Updates the K - to - V hash table to include the entry at the specified index which is assumed to have not yet been added .


private void insertIntoTableVToK(int entry, int valueHash) {
    checkArgument(entry != ABSENT);
    int valueBucket = bucket(valueHash);
    nextInBucketVToK[entry] = hashTableVToK[valueBucket];
    hashTableVToK[valueBucket] = entry;
  }

private void insertIntoTableVToK ( int entry , int valueHash ) { checkArgument ( entry != ABSENT ) ; int valueBucket = bucket ( valueHash ) ; nextInBucketVToK [ entry ] = hashTableVToK [ valueBucket ] ; hashTableVToK [ valueBucket ] = entry ; }

Updates the V-to-K hash table to include the entry at the specified index, which is assumed to
have not yet been added.

Updates the V - to - K hash table to include the entry at the specified index which is assumed to have not yet been added .


private void deleteFromTableKToV(int entry, int keyHash) {
    checkArgument(entry != ABSENT);
    int keyBucket = bucket(keyHash);

    if (hashTableKToV[keyBucket] == entry) {
      hashTableKToV[keyBucket] = nextInBucketKToV[entry];
      nextInBucketKToV[entry] = ABSENT;
      return;
    }

    int prevInBucket = hashTableKToV[keyBucket];
    for (int entryInBucket = nextInBucketKToV[prevInBucket];
        entryInBucket != ABSENT;
        entryInBucket = nextInBucketKToV[entryInBucket]) {
      if (entryInBucket == entry) {
        nextInBucketKToV[prevInBucket] = nextInBucketKToV[entry];
        nextInBucketKToV[entry] = ABSENT;
        return;
      }
      prevInBucket = entryInBucket;
    }
    throw new AssertionError("Expected to find entry with key " + keys[entry]);
  }

private
void
deleteFromTableKToV
(
int
entry
,
int
keyHash
)
{
checkArgument
(
entry
!=
ABSENT
)
;
int
keyBucket
=
bucket
(
keyHash
)
;
if
(
hashTableKToV
[
keyBucket
]
==
entry
)
{
hashTableKToV
[
keyBucket
]
=
nextInBucketKToV
[
entry
]
;
nextInBucketKToV
[
entry
]
=
ABSENT
;
return
;
}
int
prevInBucket
=
hashTableKToV
[
keyBucket
]
;
for
(
int
entryInBucket
=
nextInBucketKToV
[
prevInBucket
]
;
entryInBucket
!=
ABSENT
;
entryInBucket
=
nextInBucketKToV
[
entryInBucket
]
)
{
if
(
entryInBucket
==
entry
)
{
nextInBucketKToV
[
prevInBucket
]
=
nextInBucketKToV
[
entry
]
;
nextInBucketKToV
[
entry
]
=
ABSENT
;
return
;
}
prevInBucket
=
entryInBucket
;
}
throw
new
AssertionError
(
"Expected to find entry with key "
+
keys
[
entry
]
)
;
}

Updates the K-to-V hash table to remove the entry at the specified index, which is assumed to
be present. Does not update any other data structures.

Updates the K - to - V hash table to remove the entry at the specified index which is assumed to be present . Does not update any other data structures .


private void deleteFromTableVToK(int entry, int valueHash) {
    checkArgument(entry != ABSENT);
    int valueBucket = bucket(valueHash);

    if (hashTableVToK[valueBucket] == entry) {
      hashTableVToK[valueBucket] = nextInBucketVToK[entry];
      nextInBucketVToK[entry] = ABSENT;
      return;
    }

    int prevInBucket = hashTableVToK[valueBucket];
    for (int entryInBucket = nextInBucketVToK[prevInBucket];
        entryInBucket != ABSENT;
        entryInBucket = nextInBucketVToK[entryInBucket]) {
      if (entryInBucket == entry) {
        nextInBucketVToK[prevInBucket] = nextInBucketVToK[entry];
        nextInBucketVToK[entry] = ABSENT;
        return;
      }
      prevInBucket = entryInBucket;
    }
    throw new AssertionError("Expected to find entry with value " + values[entry]);
  }

private
void
deleteFromTableVToK
(
int
entry
,
int
valueHash
)
{
checkArgument
(
entry
!=
ABSENT
)
;
int
valueBucket
=
bucket
(
valueHash
)
;
if
(
hashTableVToK
[
valueBucket
]
==
entry
)
{
hashTableVToK
[
valueBucket
]
=
nextInBucketVToK
[
entry
]
;
nextInBucketVToK
[
entry
]
=
ABSENT
;
return
;
}
int
prevInBucket
=
hashTableVToK
[
valueBucket
]
;
for
(
int
entryInBucket
=
nextInBucketVToK
[
prevInBucket
]
;
entryInBucket
!=
ABSENT
;
entryInBucket
=
nextInBucketVToK
[
entryInBucket
]
)
{
if
(
entryInBucket
==
entry
)
{
nextInBucketVToK
[
prevInBucket
]
=
nextInBucketVToK
[
entry
]
;
nextInBucketVToK
[
entry
]
=
ABSENT
;
return
;
}
prevInBucket
=
entryInBucket
;
}
throw
new
AssertionError
(
"Expected to find entry with value "
+
values
[
entry
]
)
;
}

Updates the V-to-K hash table to remove the entry at the specified index, which is assumed to
be present. Does not update any other data structures.

Updates the V - to - K hash table to remove the entry at the specified index which is assumed to be present . Does not update any other data structures .


private void removeEntry(int entry, int keyHash, int valueHash) {
    checkArgument(entry != ABSENT);
    deleteFromTableKToV(entry, keyHash);
    deleteFromTableVToK(entry, valueHash);

    int oldPredecessor = prevInInsertionOrder[entry];
    int oldSuccessor = nextInInsertionOrder[entry];
    setSucceeds(oldPredecessor, oldSuccessor);

    moveEntryToIndex(size - 1, entry);
    keys[size - 1] = null;
    values[size - 1] = null;
    size--;
    modCount++;
  }

private void removeEntry ( int entry , int keyHash , int valueHash ) { checkArgument ( entry != ABSENT ) ; deleteFromTableKToV ( entry , keyHash ) ; deleteFromTableVToK ( entry , valueHash ) ; int oldPredecessor = prevInInsertionOrder [ entry ] ; int oldSuccessor = nextInInsertionOrder [ entry ] ; setSucceeds ( oldPredecessor , oldSuccessor ) ; moveEntryToIndex ( size - 1 , entry ) ; keys [ size - 1 ] = null ; values [ size - 1 ] = null ; size -- ; modCount ++ ; }

Removes the entry at the specified index, given the hash of its key and value.

Removes the entry at the specified index given the hash of its key and value .


void removeEntryKeyHashKnown(int entry, int keyHash) {
    removeEntry(entry, keyHash, Hashing.smearedHash(values[entry]));
  }

void removeEntryKeyHashKnown ( int entry , int keyHash ) { removeEntry ( entry , keyHash , Hashing . smearedHash ( values [ entry ] ) ) ; }

Removes the entry at the specified index, given the hash of its key.

Removes the entry at the specified index given the hash of its key .


void removeEntryValueHashKnown(int entry, int valueHash) {
    removeEntry(entry, Hashing.smearedHash(keys[entry]), valueHash);
  }

void removeEntryValueHashKnown ( int entry , int valueHash ) { removeEntry ( entry , Hashing . smearedHash ( keys [ entry ] ) , valueHash ) ; }

Removes the entry at the specified index, given the hash of its value.

Removes the entry at the specified index given the hash of its value .


public NetworkBuilder<N, E> expectedNodeCount(int expectedNodeCount) {
    this.expectedNodeCount = Optional.of(checkNonNegative(expectedNodeCount));
    return this;
  }

public NetworkBuilder < N , E > expectedNodeCount ( int expectedNodeCount ) { this . expectedNodeCount = Optional . of ( checkNonNegative ( expectedNodeCount ) ) ; return this ; }

Specifies the expected number of nodes in the network.

@throws IllegalArgumentException if {@code expectedNodeCount} is negative

Specifies the expected number of nodes in the network .


public NetworkBuilder<N, E> expectedEdgeCount(int expectedEdgeCount) {
    this.expectedEdgeCount = Optional.of(checkNonNegative(expectedEdgeCount));
    return this;
  }

public NetworkBuilder < N , E > expectedEdgeCount ( int expectedEdgeCount ) { this . expectedEdgeCount = Optional . of ( checkNonNegative ( expectedEdgeCount ) ) ; return this ; }

Specifies the expected number of edges in the network.

@throws IllegalArgumentException if {@code expectedEdgeCount} is negative

Specifies the expected number of edges in the network .


@Override
  public String getSqlWithValues() {

    if( namedParameterValues.size() == 0 ) {
      return super.getSqlWithValues();
    }

    /*
      If named parameters were used, it is no longer possible to simply replace the placeholders in the
      original statement with the values of the bind variables.  The only way it could be done is if the names
      could be resolved by to the ordinal positions which is not possible on all databases.

      New log format:  <original statement> name:value, name:value

      Example: {? = call test_proc(?,?)} param1:value1, param2:value2, param3:value3

      In the event that ordinal and named parameters are both used, the original position will be used as the name.
      Example:  {? = call test_proc(?,?)} 1:value1, 3:value3, param2:value2
    */

    final StringBuilder result = new StringBuilder();
    final String statementQuery = getStatementQuery();

    // first append the original statement
    result.append(statementQuery);
    result.append(" ");

    StringBuilder parameters = new StringBuilder();

    // add parameters set with ordinal positions
    for( Map.Entry<Integer, Value> entry : getParameterValues().entrySet() ) {
      appendParameter(parameters, entry.getKey().toString(), entry.getValue());
    }

    // add named parameters
    for( Map.Entry<String, Value> entry : namedParameterValues.entrySet() ) {
      appendParameter(parameters, entry.getKey(), entry.getValue());
    }

    result.append(parameters);

    return result.toString();
  }

Generates the query for the callable statement with all parameter placeholders
replaced with the actual parameter values

@return the SQL


public void setParameterValue(final String name, final Object value) {
    namedParameterValues.put(name, new Value(value));
  }

public void setParameterValue ( final String name , final Object value ) { namedParameterValues . put ( name , new Value ( value ) ) ; }

Records the value of a parameter.

@param name the name of the parameter
@param value the value of the parameter


public static byte[] objectToBlob(Object o) {
        try {
            return SerializerContext.getInstance().serialize(o);
        } catch (SerializerException e) {
            throw new RuntimeException(e);
        }
    }

public static byte [ ] objectToBlob ( Object o ) { try { return SerializerContext . getInstance ( ) . serialize ( o ) ; } catch ( SerializerException e ) { throw new RuntimeException ( e ) ; } }

java Object to bytes

@param o o
@return byte[]


public static <T> T blobToObject(byte[] blob, Class<T> type) {
        try {
            return SerializerContext.getInstance().deSerialize(blob, type);
        } catch (SerializerException e) {
            throw new IllegalStateException(e);
        }
    }

public static < T > T blobToObject ( byte [ ] blob , Class < T > type ) { try { return SerializerContext . getInstance ( ) . deSerialize ( blob , type ) ; } catch ( SerializerException e ) { throw new IllegalStateException ( e ) ; } }

bytes to java object.

@param blob blob
@param type type
@param <T>  T
@return T


private void lockDataLine(String groupId, String unitId, Set<String> lockIdSet, boolean isXLock) throws TxcLogicException {
        try {
            if (!reliableMessenger.acquireLocks(groupId, lockIdSet, isXLock ? DTXLocks.X_LOCK : DTXLocks.S_LOCK)) {
                throw new TxcLogicException("resource is locked! place try again later.");
            }
            globalContext.addTxcLockId(groupId, unitId, lockIdSet);
        } catch (RpcException e) {
            throw new TxcLogicException("can't contact to any TM for lock info. default error.");
        }
    }

lock data line

@param groupId   groupId
@param unitId    unitId
@param lockIdSet lockIdSet
@param isXLock   isXLock
@throws TxcLogicException 业务异常


private void saveUndoLog(String groupId, String unitId, int sqlType, TableRecordList recordList) throws TxcLogicException {
        UndoLogDO undoLogDO = new UndoLogDO();
        undoLogDO.setRollbackInfo(SqlUtils.objectToBlob(recordList));
        undoLogDO.setUnitId(unitId);
        undoLogDO.setGroupId(groupId);
        undoLogDO.setSqlType(sqlType);
        try {
            txcLogHelper.saveUndoLog(undoLogDO);
        } catch (SQLException e) {
            throw new TxcLogicException(e);
        }
    }

private void saveUndoLog ( String groupId , String unitId , int sqlType , TableRecordList recordList ) throws TxcLogicException { UndoLogDO undoLogDO = new UndoLogDO ( ) ; undoLogDO . setRollbackInfo ( SqlUtils . objectToBlob ( recordList ) ) ; undoLogDO . setUnitId ( unitId ) ; undoLogDO . setGroupId ( groupId ) ; undoLogDO . setSqlType ( sqlType ) ; try { txcLogHelper . saveUndoLog ( undoLogDO ) ; } catch ( SQLException e ) { throw new TxcLogicException ( e ) ; } }

save sql undo log

@param groupId    groupId
@param unitId     unitId
@param sqlType    sqlType
@param recordList recordList
@throws TxcLogicException 业务异常


@Bean
    @ConditionalOnClass(name = "org.springframework.data.redis.connection.RedisConnectionFactory")
    public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        JdkSerializationRedisSerializer serializationRedisSerializer = new JdkSerializationRedisSerializer();
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setHashValueSerializer(serializationRedisSerializer);
        redisTemplate.setValueSerializer(serializationRedisSerializer);
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }

default configuration redis template when have RedisConnectionFactory


public String appMapString() {
        if (hasGroup()) {
            String appMap = Optional.ofNullable(this.fields.get(TracingConstants.APP_MAP)).orElse("");
            log.debug("App map: {}", appMap);
            return appMap;
        }
        raiseNonGroupException();
        return "{}";
    }

public
String
appMapString
(
)
{
if
(
hasGroup
(
)
)
{
String
appMap
=
Optional
.
ofNullable
(
this
.
fields
.
get
(
TracingConstants
.
APP_MAP
)
)
.
orElse
(
""
)
;
log
.
debug
(
"App map: {}"
,
appMap
)
;
return
appMap
;
}
raiseNonGroupException
(
)
;
return
"{}"
;
}


public static URL locateOnClassPath(String filename) {
    URL result;
    // first try to load from context class loader
    result = Thread.currentThread().getContextClassLoader().getResource(filename);

    // next try the current class loader which loaded p6spy
    if (result == null) {
      result = P6Util.class.getClassLoader().getResource(filename);
    }

    // finally try the system class loader
    if (result == null) {
      result = ClassLoader.getSystemResource(filename);
    }

    return result;
  }

Locates a file on the classpath.

@param filename the relative filePath of the file to load
@return the URL of the file or null if not found


public static ConnectionInformation fromConnection(Connection connection) {
    final ConnectionInformation connectionInformation = new ConnectionInformation();
    connectionInformation.connection = connection;
    return connectionInformation;
  }

public static ConnectionInformation fromConnection ( Connection connection ) { final ConnectionInformation connectionInformation = new ConnectionInformation ( ) ; connectionInformation . connection = connection ; return connectionInformation ; }

This method should only be used in test scenarios

@param connection the underlying connection (possibly a mock)
@return a new {@link ConnectionInformation} instance


public Integer mapThrowable(final Throwable throwable) {
        Throwable throwableToCheck = throwable;
        int depthToGo = 20;

        while (true) {
            Integer resId = mapThrowableFlat(throwableToCheck);
            if (resId != null) {
                return resId;
            } else {
                throwableToCheck = throwableToCheck.getCause();
                depthToGo--;
                if (depthToGo <= 0 || throwableToCheck == throwable || throwableToCheck == null) {
                    Log.d("EventBus", "No specific message resource ID found for " + throwable);
                    // return config.defaultErrorMsgId;
                    return null;
                }
            }
        }

    }

Looks at the exception and its causes trying to find an ID.

Looks at the exception and its causes trying to find an ID .


private void checkForSubscribersToSkip(Messager messager, String myPackage) {
        for (TypeElement skipCandidate : methodsByClass.keySet()) {
            TypeElement subscriberClass = skipCandidate;
            while (subscriberClass != null) {
                if (!isVisible(myPackage, subscriberClass)) {
                    boolean added = classesToSkip.add(skipCandidate);
                    if (added) {
                        String msg;
                        if (subscriberClass.equals(skipCandidate)) {
                            msg = "Falling back to reflection because class is not public";
                        } else {
                            msg = "Falling back to reflection because " + skipCandidate +
                                    " has a non-public super class";
                        }
                        messager.printMessage(Diagnostic.Kind.NOTE, msg, subscriberClass);
                    }
                    break;
                }
                List<ExecutableElement> methods = methodsByClass.get(subscriberClass);
                if (methods != null) {
                    for (ExecutableElement method : methods) {
                        String skipReason = null;
                        VariableElement param = method.getParameters().get(0);
                        TypeMirror typeMirror = getParamTypeMirror(param, messager);
                        if (!(typeMirror instanceof DeclaredType) ||
                                !(((DeclaredType) typeMirror).asElement() instanceof TypeElement)) {
                            skipReason = "event type cannot be processed";
                        }
                        if (skipReason == null) {
                            TypeElement eventTypeElement = (TypeElement) ((DeclaredType) typeMirror).asElement();
                            if (!isVisible(myPackage, eventTypeElement)) {
                                skipReason = "event type is not public";
                            }
                        }
                        if (skipReason != null) {
                            boolean added = classesToSkip.add(skipCandidate);
                            if (added) {
                                String msg = "Falling back to reflection because " + skipReason;
                                if (!subscriberClass.equals(skipCandidate)) {
                                    msg += " (found in super class for " + skipCandidate + ")";
                                }
                                messager.printMessage(Diagnostic.Kind.NOTE, msg, param);
                            }
                            break;
                        }
                    }
                }
                subscriberClass = getSuperclass(subscriberClass);
            }
        }
    }

Subscriber classes should be skipped if their class or any involved event class are not visible to the index.

Subscriber classes should be skipped if their class or any involved event class are not visible to the index .


public static EventBus getDefault() {
        EventBus instance = defaultInstance;
        if (instance == null) {
            synchronized (EventBus.class) {
                instance = EventBus.defaultInstance;
                if (instance == null) {
                    instance = EventBus.defaultInstance = new EventBus();
                }
            }
        }
        return instance;
    }

public static EventBus getDefault ( ) { EventBus instance = defaultInstance ; if ( instance == null ) { synchronized ( EventBus . class ) { instance = EventBus . defaultInstance ; if ( instance == null ) { instance = EventBus . defaultInstance = new EventBus ( ) ; } } } return instance ; }

Convenience singleton for apps using a process-wide EventBus instance.

Convenience singleton for apps using a process - wide EventBus instance .


private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
        Class<?> eventType = subscriberMethod.eventType;
        Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
        CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions == null) {
            subscriptions = new CopyOnWriteArrayList<>();
            subscriptionsByEventType.put(eventType, subscriptions);
        } else {
            if (subscriptions.contains(newSubscription)) {
                throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
                        + eventType);
            }
        }

        int size = subscriptions.size();
        for (int i = 0; i <= size; i++) {
            if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
                subscriptions.add(i, newSubscription);
                break;
            }
        }

        List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
        if (subscribedEvents == null) {
            subscribedEvents = new ArrayList<>();
            typesBySubscriber.put(subscriber, subscribedEvents);
        }
        subscribedEvents.add(eventType);

        if (subscriberMethod.sticky) {
            if (eventInheritance) {
                // Existing sticky events of all subclasses of eventType have to be considered.
                // Note: Iterating over all events may be inefficient with lots of sticky events,
                // thus data structure should be changed to allow a more efficient lookup
                // (e.g. an additional map storing sub classes of super classes: Class -> List<Class>).
                Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
                for (Map.Entry<Class<?>, Object> entry : entries) {
                    Class<?> candidateEventType = entry.getKey();
                    if (eventType.isAssignableFrom(candidateEventType)) {
                        Object stickyEvent = entry.getValue();
                        checkPostStickyEventToSubscription(newSubscription, stickyEvent);
                    }
                }
            } else {
                Object stickyEvent = stickyEvents.get(eventType);
                checkPostStickyEventToSubscription(newSubscription, stickyEvent);
            }
        }
    }


private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
        List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
        if (subscriptions != null) {
            int size = subscriptions.size();
            for (int i = 0; i < size; i++) {
                Subscription subscription = subscriptions.get(i);
                if (subscription.subscriber == subscriber) {
                    subscription.active = false;
                    subscriptions.remove(i);
                    i--;
                    size--;
                }
            }
        }
    }

private void unsubscribeByEventType ( Object subscriber , Class < ? > eventType ) { List < Subscription > subscriptions = subscriptionsByEventType . get ( eventType ) ; if ( subscriptions != null ) { int size = subscriptions . size ( ) ; for ( int i = 0 ; i < size ; i ++ ) { Subscription subscription = subscriptions . get ( i ) ; if ( subscription . subscriber == subscriber ) { subscription . active = false ; subscriptions . remove ( i ) ; i -- ; size -- ; } } } }

Only updates subscriptionsByEventType, not typesBySubscriber! Caller must update typesBySubscriber.

Only updates subscriptionsByEventType not typesBySubscriber! Caller must update typesBySubscriber .


public synchronized void unregister(Object subscriber) {
        List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
        if (subscribedTypes != null) {
            for (Class<?> eventType : subscribedTypes) {
                unsubscribeByEventType(subscriber, eventType);
            }
            typesBySubscriber.remove(subscriber);
        } else {
            logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
        }
    }

Unregisters the given subscriber from all event classes.

Unregisters the given subscriber from all event classes .


public void post(Object event) {
        PostingThreadState postingState = currentPostingThreadState.get();
        List<Object> eventQueue = postingState.eventQueue;
        eventQueue.add(event);

        if (!postingState.isPosting) {
            postingState.isMainThread = isMainThread();
            postingState.isPosting = true;
            if (postingState.canceled) {
                throw new EventBusException("Internal error. Abort state was not reset");
            }
            try {
                while (!eventQueue.isEmpty()) {
                    postSingleEvent(eventQueue.remove(0), postingState);
                }
            } finally {
                postingState.isPosting = false;
                postingState.isMainThread = false;
            }
        }
    }

Posts the given event to the event bus .


public <T> T getStickyEvent(Class<T> eventType) {
        synchronized (stickyEvents) {
            return eventType.cast(stickyEvents.get(eventType));
        }
    }

public < T > T getStickyEvent ( Class < T > eventType ) { synchronized ( stickyEvents ) { return eventType . cast ( stickyEvents . get ( eventType ) ) ; } }

Gets the most recent sticky event for the given type.

@see #postSticky(Object)

Gets the most recent sticky event for the given type .


public <T> T removeStickyEvent(Class<T> eventType) {
        synchronized (stickyEvents) {
            return eventType.cast(stickyEvents.remove(eventType));
        }
    }

public < T > T removeStickyEvent ( Class < T > eventType ) { synchronized ( stickyEvents ) { return eventType . cast ( stickyEvents . remove ( eventType ) ) ; } }

Remove and gets the recent sticky event for the given event type.

@see #postSticky(Object)

Remove and gets the recent sticky event for the given event type .


public boolean removeStickyEvent(Object event) {
        synchronized (stickyEvents) {
            Class<?> eventType = event.getClass();
            Object existingEvent = stickyEvents.get(eventType);
            if (event.equals(existingEvent)) {
                stickyEvents.remove(eventType);
                return true;
            } else {
                return false;
            }
        }
    }

public boolean removeStickyEvent ( Object event ) { synchronized ( stickyEvents ) { Class < ? > eventType = event . getClass ( ) ; Object existingEvent = stickyEvents . get ( eventType ) ; if ( event . equals ( existingEvent ) ) { stickyEvents . remove ( eventType ) ; return true ; } else { return false ; } } }

Removes the sticky event if it equals to the given event.

@return true if the events matched and the sticky event was removed.

Removes the sticky event if it equals to the given event .


private static List<Class<?>> lookupAllEventTypes(Class<?> eventClass) {
        synchronized (eventTypesCache) {
            List<Class<?>> eventTypes = eventTypesCache.get(eventClass);
            if (eventTypes == null) {
                eventTypes = new ArrayList<>();
                Class<?> clazz = eventClass;
                while (clazz != null) {
                    eventTypes.add(clazz);
                    addInterfaces(eventTypes, clazz.getInterfaces());
                    clazz = clazz.getSuperclass();
                }
                eventTypesCache.put(eventClass, eventTypes);
            }
            return eventTypes;
        }
    }

private static List < Class < ? > > lookupAllEventTypes ( Class < ? > eventClass ) { synchronized ( eventTypesCache ) { List < Class < ? > > eventTypes = eventTypesCache . get ( eventClass ) ; if ( eventTypes == null ) { eventTypes = new ArrayList <> ( ) ; Class < ? > clazz = eventClass ; while ( clazz != null ) { eventTypes . add ( clazz ) ; addInterfaces ( eventTypes , clazz . getInterfaces ( ) ) ; clazz = clazz . getSuperclass ( ) ; } eventTypesCache . put ( eventClass , eventTypes ) ; } return eventTypes ; } }

Looks up all Class objects including super classes and interfaces. Should also work for interfaces.

Looks up all Class objects including super classes and interfaces . Should also work for interfaces .


static void addInterfaces(List<Class<?>> eventTypes, Class<?>[] interfaces) {
        for (Class<?> interfaceClass : interfaces) {
            if (!eventTypes.contains(interfaceClass)) {
                eventTypes.add(interfaceClass);
                addInterfaces(eventTypes, interfaceClass.getInterfaces());
            }
        }
    }

static void addInterfaces ( List < Class < ? > > eventTypes , Class < ? > [ ] interfaces ) { for ( Class < ? > interfaceClass : interfaces ) { if ( ! eventTypes . contains ( interfaceClass ) ) { eventTypes . add ( interfaceClass ) ; addInterfaces ( eventTypes , interfaceClass . getInterfaces ( ) ) ; } } }


public EventBusBuilder addIndex(SubscriberInfoIndex index) {
        if (subscriberInfoIndexes == null) {
            subscriberInfoIndexes = new ArrayList<>();
        }
        subscriberInfoIndexes.add(index);
        return this;
    }

public EventBusBuilder addIndex ( SubscriberInfoIndex index ) { if ( subscriberInfoIndexes == null ) { subscriberInfoIndexes = new ArrayList <> ( ) ; } subscriberInfoIndexes . add ( index ) ; return this ; }

Adds an index generated by EventBus' annotation preprocessor.

Adds an index generated by EventBus annotation preprocessor .


public static void attachTo(Activity activity, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
        Object executionScope = activity.getClass();
        attachTo(activity, executionScope, finishAfterDialog, argumentsForErrorDialog);
    }

public static void attachTo ( Activity activity , boolean finishAfterDialog , Bundle argumentsForErrorDialog ) { Object executionScope = activity . getClass ( ) ; attachTo ( activity , executionScope , finishAfterDialog , argumentsForErrorDialog ) ; }

Scope is limited to the activity's class.

Scope is limited to the activity s class .


protected T prepareErrorFragment(ThrowableFailureEvent event, boolean finishAfterDialog,
            Bundle argumentsForErrorDialog) {
        if (event.isSuppressErrorUi()) {
            // Show nothing by default
            return null;
        }
        Bundle bundle;
        if (argumentsForErrorDialog != null) {
            bundle = (Bundle) argumentsForErrorDialog.clone();
        } else {
            bundle = new Bundle();
        }

        if (!bundle.containsKey(ErrorDialogManager.KEY_TITLE)) {
            String title = getTitleFor(event, bundle);
            bundle.putString(ErrorDialogManager.KEY_TITLE, title);
        }
        if (!bundle.containsKey(ErrorDialogManager.KEY_MESSAGE)) {
            String message = getMessageFor(event, bundle);
            bundle.putString(ErrorDialogManager.KEY_MESSAGE, message);
        }
        if (!bundle.containsKey(ErrorDialogManager.KEY_FINISH_AFTER_DIALOG)) {
            bundle.putBoolean(ErrorDialogManager.KEY_FINISH_AFTER_DIALOG, finishAfterDialog);
        }
        if (!bundle.containsKey(ErrorDialogManager.KEY_EVENT_TYPE_ON_CLOSE)
                && config.defaultEventTypeOnDialogClosed != null) {
            bundle.putSerializable(ErrorDialogManager.KEY_EVENT_TYPE_ON_CLOSE, config.defaultEventTypeOnDialogClosed);
        }
        if (!bundle.containsKey(ErrorDialogManager.KEY_ICON_ID) && config.defaultDialogIconId != 0) {
            bundle.putInt(ErrorDialogManager.KEY_ICON_ID, config.defaultDialogIconId);
        }
        return createErrorFragment(event, bundle);
    }

protected
T
prepareErrorFragment
(
ThrowableFailureEvent
event
,
boolean
finishAfterDialog
,
Bundle
argumentsForErrorDialog
)
{
if
(
event
.
isSuppressErrorUi
(
)
)
{
// Show nothing by default
return
;
}
Bundle
bundle
;
if
(
argumentsForErrorDialog
!=
)
{
bundle
=
(
Bundle
)
argumentsForErrorDialog
.
clone
(
)
;
}
else
{
bundle
=
new
Bundle
(
)
;
}
if
(
!
bundle
.
containsKey
(
ErrorDialogManager
.
KEY_TITLE
)
)
{
String
title
=
getTitleFor
(
event
,
bundle
)
;
bundle
.
putString
(
ErrorDialogManager
.
KEY_TITLE
,
title
)
;
}
if
(
!
bundle
.
containsKey
(
ErrorDialogManager
.
KEY_MESSAGE
)
)
{
String
message
=
getMessageFor
(
event
,
bundle
)
;
bundle
.
putString
(
ErrorDialogManager
.
KEY_MESSAGE
,
message
)
;
}
if
(
!
bundle
.
containsKey
(
ErrorDialogManager
.
KEY_FINISH_AFTER_DIALOG
)
)
{
bundle
.
putBoolean
(
ErrorDialogManager
.
KEY_FINISH_AFTER_DIALOG
,
finishAfterDialog
)
;
}
if
(
!
bundle
.
containsKey
(
ErrorDialogManager
.
KEY_EVENT_TYPE_ON_CLOSE
)
&&
config
.
defaultEventTypeOnDialogClosed
!=
)
{
bundle
.
putSerializable
(
ErrorDialogManager
.
KEY_EVENT_TYPE_ON_CLOSE
,
config
.
defaultEventTypeOnDialogClosed
)
;
}
if
(
!
bundle
.
containsKey
(
ErrorDialogManager
.
KEY_ICON_ID
)
&&
config
.
defaultDialogIconId
!=
0
)
{
bundle
.
putInt
(
ErrorDialogManager
.
KEY_ICON_ID
,
config
.
defaultDialogIconId
)
;
}
return
createErrorFragment
(
event
,
bundle
)
;
}

Prepares the fragment's arguments and creates the fragment. May be overridden to provide custom error fragments.

Prepares the fragment s arguments and creates the fragment . May be overridden to provide custom error fragments .


protected String getTitleFor(ThrowableFailureEvent event, Bundle arguments) {
        return config.resources.getString(config.defaultTitleId);
    }

protected String getTitleFor ( ThrowableFailureEvent event , Bundle arguments ) { return config . resources . getString ( config . defaultTitleId ) ; }

May be overridden to provide custom error title.

May be overridden to provide custom error title .


protected String getMessageFor(ThrowableFailureEvent event, Bundle arguments) {
        int msgResId = config.getMessageIdForThrowable(event.throwable);
        return config.resources.getString(msgResId);
    }

protected String getMessageFor ( ThrowableFailureEvent event , Bundle arguments ) { int msgResId = config . getMessageIdForThrowable ( event . throwable ) ; return config . resources . getString ( msgResId ) ; }

May be overridden to provide custom error messages.

May be overridden to provide custom error messages .


static <T, F> boolean postCompleteDrain(long n,
			Subscriber<? super T> actual,
			Queue<T> queue,
			AtomicLongFieldUpdater<F> field,
			F instance,
			BooleanSupplier isCancelled) {

// TODO enable fast-path
//        if (n == -1 || n == Long.MAX_VALUE) {
//            for (;;) {
//                if (isDisposed.getAsBoolean()) {
//                    break;
//                }
//
//                T v = queue.poll();
//
//                if (v == null) {
//                    actual.onComplete();
//                    break;
//                }
//
//                actual.onNext(v);
//            }
//
//            return true;
//        }

		long e = n & COMPLETED_MASK;

		for (; ; ) {

			while (e != n) {
				if (isCancelled.getAsBoolean()) {
					return true;
				}

				T t = queue.poll();

				if (t == null) {
					actual.onComplete();
					return true;
				}

				actual.onNext(t);
				e++;
			}

			if (isCancelled.getAsBoolean()) {
				return true;
			}

			if (queue.isEmpty()) {
				actual.onComplete();
				return true;
			}

			n = field.get(instance);

			if (n == e) {

				n = field.addAndGet(instance, -(e & REQUESTED_MASK));

				if ((n & REQUESTED_MASK) == 0L) {
					return false;
				}

				e = n & COMPLETED_MASK;
			}
		}

	}

//                if (isDisposed.getAsBoolean()) {

//                    actual.onComplete();

Drains the queue either in a pre- or post-complete state.

@param n the requested amount
@param actual the consumer of values
@param queue the queue holding available values
@param field the field updater holding the requested amount
@param instance the parent instance of the requested field
@param isCancelled callback to detect cancellation
@return true if the queue was completely drained or the drain process was cancelled

Drains the queue either in a pre - or post - complete state .


@Nullable
	final T blockingGet(long timeout, TimeUnit unit) {
		if (Schedulers.isInNonBlockingThread()) {
			throw new IllegalStateException("block()/blockFirst()/blockLast() are blocking, which is not supported in thread " + Thread.currentThread().getName());
		}
		if (getCount() != 0) {
			try {
				if (!await(timeout, unit)) {
					dispose();
					throw new IllegalStateException("Timeout on blocking read for " + timeout + " " + unit);
				}
			}
			catch (InterruptedException ex) {
				dispose();
				RuntimeException re = Exceptions.propagate(ex);
				//this is ok, as re is always a new non-singleton instance
				re.addSuppressed(new Exception("#block has been interrupted"));
				throw re;
			}
		}

		Throwable e = error;
		if (e != null) {
			RuntimeException re = Exceptions.propagate(e);
			//this is ok, as re is always a new non-singleton instance
			re.addSuppressed(new Exception("#block terminated with an error"));
			throw re;
		}
		return value;
	}

Block until the first value arrives and return it, otherwise
return null for an empty source and rethrow any exception.

@param timeout the timeout to wait
@param unit the time unit

@return the first value or null if the source is empty

Block until the first value arrives and return it otherwise return null for an empty source and rethrow any exception .


public final Mono<T> elementAt(int index, T defaultValue) {
		return Mono.onAssembly(new MonoElementAt<>(this, index, defaultValue));
	}

public final Mono < T > elementAt ( int index , T defaultValue ) { return Mono . onAssembly ( new MonoElementAt <> ( this , index , defaultValue ) ) ; }

Emit only the element at the given index position or fall back to a
default value if the sequence is shorter.

@reactor.discard This operator discards elements that appear before the requested index.

@param index zero-based index of the only item to emit
@param defaultValue a default value to emit if the sequence is shorter

@return a {@link Mono} of the item at the specified zero-based index or a default value

Emit only the element at the given index position or fall back to a default value if the sequence is shorter .


public final Flux<T> onErrorResume(Function<? super Throwable, ? extends Publisher<? extends T>> fallback) {
		return onAssembly(new FluxOnErrorResume<>(this, fallback));
	}

public final Flux < T > onErrorResume ( Function < ? super Throwable , ? extends Publisher < ? extends T > > fallback ) { return onAssembly ( new FluxOnErrorResume <> ( this , fallback ) ) ; }

Subscribe to a returned fallback publisher when any error occurs, using a function to
choose the fallback depending on the error.

@param fallback the function to choose the fallback to an alternative {@link Publisher}

@return a {@link Flux} falling back upon source onError

Subscribe to a returned fallback publisher when any error occurs using a function to choose the fallback depending on the error .


public final Flux<T> repeat(long numRepeat, BooleanSupplier predicate) {
		if (numRepeat < 0L) {
			throw new IllegalArgumentException("numRepeat >= 0 required");
		}
		if (numRepeat == 0) {
			return this;
		}
		return defer( () -> repeat(countingBooleanSupplier(predicate, numRepeat)));
	}

public
final
Flux
<
T
>
repeat
(
long
numRepeat
,
BooleanSupplier
predicate
)
{
if
(
numRepeat
<
0L
)
{
throw
new
IllegalArgumentException
(
"numRepeat >= 0 required"
)
;
}
if
(
numRepeat
==
0
)
{
return
this
;
}
return
defer
(
(
)
->
repeat
(
countingBooleanSupplier
(
predicate
,
numRepeat
)
)
)
;
}

Repeatedly subscribe to the source if the predicate returns true after completion of the previous
subscription. A specified maximum of repeat will limit the number of re-subscribe.

@param numRepeat the number of times to re-subscribe on complete (positive, or 0 for original sequence only)
@param predicate the boolean to evaluate on onComplete

@return a {@link Flux} that repeats on onComplete while the predicate matches,
up to the specified number of repetitions

Repeatedly subscribe to the source if the predicate returns true after completion of the previous subscription . A specified maximum of repeat will limit the number of re - subscribe .


static <T> Mono<T> convertToMono(Callable<T> supplier) {
		if (supplier instanceof Fuseable.ScalarCallable) {
			Fuseable.ScalarCallable<T> scalarCallable = (Fuseable.ScalarCallable<T>) supplier;

			T v;
			try {
				v = scalarCallable.call();
			}
			catch (Exception e) {
				return Mono.error(e);
			}
			if (v == null) {
				return Mono.empty();
			}
			return Mono.just(v);
		}
		return Mono.onAssembly(new MonoCallable<>(supplier));
	}

static < T > Mono < T > convertToMono ( Callable < T > supplier ) { if ( supplier instanceof Fuseable . ScalarCallable ) { Fuseable . ScalarCallable < T > scalarCallable = ( Fuseable . ScalarCallable < T > ) supplier ; T v ; try { v = scalarCallable . call ( ) ; } catch ( Exception e ) { return Mono . error ( e ) ; } if ( v == null ) { return Mono . empty ( ) ; } return Mono . just ( v ) ; } return Mono . onAssembly ( new MonoCallable <> ( supplier ) ) ; }

Returns the appropriate Mono instance for a known Supplier Flux.

@param supplier the supplier Flux

@return the mono representing that Flux

Returns the appropriate Mono instance for a known Supplier Flux .


static long getAndSub(RingBuffer.Sequence sequence, long toSub) {
		long r, u;
		do {
			r = sequence.getAsLong();
			if (r == 0 || r == Long.MAX_VALUE) {
				return r;
			}
			u = Operators.subOrZero(r, toSub);
		}
		while (!sequence.compareAndSet(r, u));

		return r;
	}

static long getAndSub ( RingBuffer . Sequence sequence , long toSub ) { long r , u ; do { r = sequence . getAsLong ( ) ; if ( r == 0 || r == Long . MAX_VALUE ) { return r ; } u = Operators . subOrZero ( r , toSub ) ; } while ( ! sequence . compareAndSet ( r , u ) ) ; return r ; }

Concurrent subtraction bound to 0 and Long.MAX_VALUE. Any concurrent write will
"happen" before this operation.

@param sequence current sequence to update
@param toSub delta to sub

@return value before subscription, 0 or Long.MAX_VALUE

Concurrent subtraction bound to 0 and Long . MAX_VALUE . Any concurrent write will happen before this operation .


@SuppressWarnings("unchecked")
	@Nullable
	public static <T> QueueSubscription<T> as(Subscription s) {
		if (s instanceof QueueSubscription) {
			return (QueueSubscription<T>) s;
		}
		return null;
	}

@ SuppressWarnings ( "unchecked" ) @ Nullable public static < T > QueueSubscription < T > as ( Subscription s ) { if ( s instanceof QueueSubscription ) { return ( QueueSubscription < T > ) s ; } return null ; }

Returns the subscription as QueueSubscription if possible or null.
@param <T> the value type of the QueueSubscription.
@param s the source subscription to try to convert.
@return the QueueSubscription instance or null

Returns the subscription as QueueSubscription if possible or null .


public static void error(Subscriber<?> s, Throwable e) {
		s.onSubscribe(EmptySubscription.INSTANCE);
		s.onError(e);
	}

public static void error ( Subscriber < ? > s , Throwable e ) { s . onSubscribe ( EmptySubscription . INSTANCE ) ; s . onError ( e ) ; }

Calls onSubscribe on the target Subscriber with the empty instance followed by a call to onError with the
supplied error.

@param s target Subscriber to error
@param e the actual error

Calls onSubscribe on the target Subscriber with the empty instance followed by a call to onError with the supplied error .


public static <T> long produced(AtomicLongFieldUpdater<T> updater, T instance, long toSub) {
		long r, u;
		do {
			r = updater.get(instance);
			if (r == 0 || r == Long.MAX_VALUE) {
				return r;
			}
			u = subOrZero(r, toSub);
		} while (!updater.compareAndSet(instance, r, u));

		return u;
	}

public static < T > long produced ( AtomicLongFieldUpdater < T > updater , T instance , long toSub ) { long r , u ; do { r = updater . get ( instance ) ; if ( r == 0 || r == Long . MAX_VALUE ) { return r ; } u = subOrZero ( r , toSub ) ; } while ( ! updater . compareAndSet ( instance , r , u ) ) ; return u ; }

Concurrent subtraction bound to 0, mostly used to decrement a request tracker by
the amount produced by the operator. Any concurrent write will "happen before"
this operation.

@param <T> the parent instance type
@param updater  current field updater
@param instance current instance to update
@param toSub    delta to subtract
@return value after subtraction or zero

Concurrent subtraction bound to 0 mostly used to decrement a request tracker by the amount produced by the operator . Any concurrent write will happen before this operation .


public static <T> Subscription scalarSubscription(CoreSubscriber<? super T> subscriber,
			T value){
		return new ScalarSubscription<>(subscriber, value);
	}

public static < T > Subscription scalarSubscription ( CoreSubscriber < ? super T > subscriber , T value ) { return new ScalarSubscription <> ( subscriber , value ) ; }

Represents a fuseable Subscription that emits a single constant value synchronously
to a Subscriber or consumer.

@param subscriber the delegate {@link Subscriber} that will be requesting the value
@param value the single value to be emitted
@param <T> the value type
@return a new scalar {@link Subscription}

Represents a fuseable Subscription that emits a single constant value synchronously to a Subscriber or consumer .


<U> MonoIgnoreThen<U> shift(Mono<U> newLast) {
        Objects.requireNonNull(newLast, "newLast");
        Publisher<?>[] a = ignore;
        int n = a.length;
        Publisher<?>[] b = new Publisher[n + 1];
        System.arraycopy(a, 0, b, 0, n);
        b[n] = last;

        return new MonoIgnoreThen<>(b, newLast);
    }

< U > MonoIgnoreThen < U > shift ( Mono < U > newLast ) { Objects . requireNonNull ( newLast , "newLast" ) ; Publisher < ? > [ ] a = ignore ; int n = a . length ; Publisher < ? > [ ] b = new Publisher [ n + 1 ] ; System . arraycopy ( a , 0 , b , 0 , n ) ; b [ n ] = last ; return new MonoIgnoreThen <> ( b , newLast ) ; }

Shifts the current last Mono into the ignore array and sets up a new last Mono instance.
@param <U> the new last value type
@param newLast the new last Mono instance
@return the new operator set up

Shifts the current last Mono into the ignore array and sets up a new last Mono instance .


public static WaitStrategy phasedOffSleep(long spinTimeout, long yieldTimeout, TimeUnit units) {
        return phasedOff(spinTimeout, yieldTimeout, units, parking(0));
    }

public static WaitStrategy phasedOffSleep ( long spinTimeout , long yieldTimeout , TimeUnit units ) { return phasedOff ( spinTimeout , yieldTimeout , units , parking ( 0 ) ) ; }

Block by parking in a loop
@param spinTimeout the spin timeout
@param yieldTimeout the yield timeout
@param units the time unit
@return the wait strategy


public final Mono<Void> and(Publisher<?> other) {
		if (this instanceof MonoWhen) {
			@SuppressWarnings("unchecked") MonoWhen o = (MonoWhen) this;
			Mono<Void> result = o.whenAdditionalSource(other);
			if (result != null) {
				return result;
			}
		}

		return when(this, other);
	}

public final Mono < Void > and ( Publisher < ? > other ) { if ( this instanceof MonoWhen ) { @ SuppressWarnings ( "unchecked" ) MonoWhen o = ( MonoWhen ) this ; Mono < Void > result = o . whenAdditionalSource ( other ) ; if ( result != null ) { return result ; } } return when ( this , other ) ; }

Join the termination signals from this mono and another source into the returned
void mono

@param other the {@link Publisher} to wait for
complete
@return a new combined Mono
@see #when


public final Mono<T> defaultIfEmpty(T defaultV) {
	    if (this instanceof Fuseable.ScalarCallable) {
		    try {
			    T v = block();
			    if (v == null) {
				    return Mono.just(defaultV);
			    }
		    }
		    catch (Throwable e) {
			    //leave MonoError returns as this
		    }
		    return this;
	    }
		return onAssembly(new MonoDefaultIfEmpty<>(this, defaultV));
	}

public
final
Mono
<
T
>
defaultIfEmpty
(
T
defaultV
)
{
if
(
this
instanceof
Fuseable
.
ScalarCallable
)
{
try
{
T
v
=
block
(
)
;
if
(
v
==
)
{
return
Mono
.
just
(
defaultV
)
;
}
}
catch
(
Throwable
e
)
{
//leave MonoError returns as this
}
return
this
;
}
return
onAssembly
(
new
MonoDefaultIfEmpty
<>
(
this
,
defaultV
)
)
;
}

Provide a default single value if this mono is completed without any data

@param defaultV the alternate value if this sequence is empty

@return a new {@link Mono}

@see Flux#defaultIfEmpty(Object)


public final Mono<T> or(Mono<? extends T> other) {
		if (this instanceof MonoFirst) {
			MonoFirst<T> a = (MonoFirst<T>) this;
			Mono<T> result =  a.orAdditionalSource(other);
			if (result != null) {
				return result;
			}
		}
		return first(this, other);
	}

public final Mono < T > or ( Mono < ? extends T > other ) { if ( this instanceof MonoFirst ) { MonoFirst < T > a = ( MonoFirst < T > ) this ; Mono < T > result = a . orAdditionalSource ( other ) ; if ( result != null ) { return result ; } } return first ( this , other ) ; }

Emit the first available result from this mono or the other mono.

@param other the racing other {@link Mono} to compete with for the result

@return a new {@link Mono}
@see #first

Emit the first available result from this mono or the other mono .


public final Mono<T> onErrorResume(Function<? super Throwable, ? extends Mono<? extends
			T>> fallback) {
		return onAssembly(new MonoOnErrorResume<>(this, fallback));
	}

public final Mono < T > onErrorResume ( Function < ? super Throwable , ? extends Mono < ? extends T > > fallback ) { return onAssembly ( new MonoOnErrorResume <> ( this , fallback ) ) ; }

Subscribe to a fallback publisher when any error occurs, using a function to
choose the fallback depending on the error.

@param fallback the function to choose the fallback to an alternative {@link Mono}

@return a {@link Mono} falling back upon source onError

@see Flux#onErrorResume

Subscribe to a fallback publisher when any error occurs using a function to choose the fallback depending on the error .


static final Map<String, Function<? super Publisher<Object>, ? extends Publisher<Object>>> getOnEachOperatorHooks() {
		return Collections.unmodifiableMap(onEachOperatorHooks);
	}

static final Map < String , Function < ? super Publisher < Object > , ? extends Publisher < Object > > > getOnEachOperatorHooks ( ) { return Collections . unmodifiableMap ( onEachOperatorHooks ) ; }

Immutable views on hook trackers, for testing purpose

Immutable views on hook trackers for testing purpose


@SuppressWarnings("unchecked")
	MonoDelayUntil<T> copyWithNewTriggerGenerator(boolean delayError,
			Function<? super T, ? extends Publisher<?>> triggerGenerator) {
		Objects.requireNonNull(triggerGenerator, "triggerGenerator");
		Function<? super T, ? extends Publisher<?>>[] oldTriggers = this.otherGenerators;
		Function<? super T, ? extends Publisher<?>>[] newTriggers = new Function[oldTriggers.length + 1];
		System.arraycopy(oldTriggers, 0, newTriggers, 0, oldTriggers.length);
		newTriggers[oldTriggers.length] = triggerGenerator;
		return new MonoDelayUntil<>(this.source, newTriggers);
	}

@ SuppressWarnings ( "unchecked" ) MonoDelayUntil < T > copyWithNewTriggerGenerator ( boolean delayError , Function < ? super T , ? extends Publisher < ? > > triggerGenerator ) { Objects . requireNonNull ( triggerGenerator , "triggerGenerator" ) ; Function < ? super T , ? extends Publisher < ? > > [ ] oldTriggers = this . otherGenerators ; Function < ? super T , ? extends Publisher < ? > > [ ] newTriggers = new Function [ oldTriggers . length + 1 ] ; System . arraycopy ( oldTriggers , 0 , newTriggers , 0 , oldTriggers . length ) ; newTriggers [ oldTriggers . length ] = triggerGenerator ; return new MonoDelayUntil <> ( this . source , newTriggers ) ; }

Add a trigger generator to wait for.
@param delayError the delayError parameter for the trigger being added, ignored if already true
@param triggerGenerator the new trigger to add to the copy of the operator
@return a new {@link MonoDelayUntil} instance with same source but additional trigger generator


static <Q, S> void drainMaxLoop(Queue<Q> q, Subscriber<? super S> a, boolean delayError,
			Disposable dispose, QueueDrainSubscriber<?, Q, S> qd) {
		int missed = 1;

		for (;;) {
			for (;;) {
				boolean d = qd.done();

				Q v = q.poll();

				boolean empty = v == null;

				if (checkTerminated(d, empty, a, delayError, q, qd)) {
					if (dispose != null) {
						dispose.dispose();
					}
					return;
				}

				if (empty) {
					break;
				}

				long r = qd.requested();
				if (r != 0L) {
					if (qd.accept(a, v)) {
						if (r != Long.MAX_VALUE) {
							qd.produced(1);
						}
					}
				} else {
					q.clear();
					if (dispose != null) {
						dispose.dispose();
					}
					a.onError(Exceptions.failWithOverflow("Could not emit value due to lack of requests."));
					return;
				}
			}

			missed = qd.leave(-missed);
			if (missed == 0) {
				break;
			}
		}
	}

Drain the queue but give up with an error if there aren't enough requests.
@param <Q> the queue value type
@param <S> the emission value type
@param q the queue
@param a the subscriber
@param delayError true if errors should be delayed after all normal items
@param dispose the disposable to call when termination happens and cleanup is necessary
@param qd the QueueDrain instance that gives status information to the drain logic

Drain the queue but give up with an error if there aren t enough requests .


@SuppressWarnings("unchecked")
	static <T, R> boolean trySubscribeScalarMap(Publisher<? extends T> source,
			CoreSubscriber<? super R> s,
			Function<? super T, ? extends Publisher<? extends R>> mapper,
			boolean fuseableExpected) {
		if (source instanceof Callable) {
			T t;

			try {
				t = ((Callable<? extends T>) source).call();
			}
			catch (Throwable e) {
				Operators.error(s, Operators.onOperatorError(e, s.currentContext()));
				return true;
			}

			if (t == null) {
				Operators.complete(s);
				return true;
			}

			Publisher<? extends R> p;

			try {
				p = Objects.requireNonNull(mapper.apply(t),
						"The mapper returned a null Publisher");
			}
			catch (Throwable e) {
				Operators.error(s, Operators.onOperatorError(null, e, t, s.currentContext()));
				return true;
			}

			if (p instanceof Callable) {
				R v;

				try {
					v = ((Callable<R>) p).call();
				}
				catch (Throwable e) {
					Operators.error(s, Operators.onOperatorError(null, e, t, s.currentContext()));
					return true;
				}

				if (v != null) {
					s.onSubscribe(Operators.scalarSubscription(s, v));
				}
				else {
					Operators.complete(s);
				}
			}
			else {
				if (!fuseableExpected || p instanceof Fuseable) {
					p.subscribe(s);
				}
				else {
					p.subscribe(new FluxHide.SuppressFuseableSubscriber<>(s));
				}
			}

			return true;
		}

		return false;
	}

@
SuppressWarnings
(
"unchecked"
)
static
<
T
,
R
>
boolean
trySubscribeScalarMap
(
Publisher
<
extends
T
>
source
,
CoreSubscriber
<
super
R
>
s
,
Function
<
super
T
,
extends
Publisher
<
extends
R
>
>
mapper
,
boolean
fuseableExpected
)
{
if
(
source
instanceof
Callable
)
{
T
t
;
try
{
t
=
(
(
Callable
<
extends
T
>
)
source
)
.
call
(
)
;
}
catch
(
Throwable
e
)
{
Operators
.
error
(
s
,
Operators
.
onOperatorError
(
e
,
s
.
currentContext
(
)
)
)
;
return
true
;
}
if
(
t
==
)
{
Operators
.
complete
(
s
)
;
return
true
;
}
Publisher
<
extends
R
>
p
;
try
{
p
=
Objects
.
requireNonNull
(
mapper
.
apply
(
t
)
,
"The mapper returned a null Publisher"
)
;
}
catch
(
Throwable
e
)
{
Operators
.
error
(
s
,
Operators
.
onOperatorError
(
,
e
,
t
,
s
.
currentContext
(
)
)
)
;
return
true
;
}
if
(
p
instanceof
Callable
)
{
R
v
;
try
{
v
=
(
(
Callable
<
R
>
)
p
)
.
call
(
)
;
}
catch
(
Throwable
e
)
{
Operators
.
error
(
s
,
Operators
.
onOperatorError
(
,
e
,
t
,
s
.
currentContext
(
)
)
)
;
return
true
;
}
if
(
v
!=
)
{
s
.
onSubscribe
(
Operators
.
scalarSubscription
(
s
,
v
)
)
;
}
else
{
Operators
.
complete
(
s
)
;
}
}
else
{
if
(
!
fuseableExpected
||
p
instanceof
Fuseable
)
{
p
.
subscribe
(
s
)
;
}
else
{
p
.
subscribe
(
new
FluxHide
.
SuppressFuseableSubscriber
<>
(
s
)
)
;
}
}
return
true
;
}
return
false
;
}

Checks if the source is a Supplier and if the mapper's publisher output is also
a supplier, thus avoiding subscribing to any of them.

@param source the source publisher
@param s the end consumer
@param mapper the mapper function
@param fuseableExpected if true, the parent class was marked Fuseable thus the
mapping output has to signal onSubscribe with a QueueSubscription

@return true if the optimization worked

Checks if the source is a Supplier and if the mapper s publisher output is also a supplier thus avoiding subscribing to any of them .


public final <U> U as(Function<? super ParallelFlux<T>, U> converter) {
		return converter.apply(this);
	}

public final < U > U as ( Function < ? super ParallelFlux < T > , U > converter ) { return converter . apply ( this ) ; }

Perform a fluent transformation to a value via a converter function which receives
this ParallelFlux.

@param <U> the output value type
@param converter the converter function from {@link ParallelFlux} to some type

@return the value returned by the converter function

Perform a fluent transformation to a value via a converter function which receives this ParallelFlux .


public final <C> ParallelFlux<C> collect(Supplier<? extends C> collectionSupplier,
			BiConsumer<? super C, ? super T> collector) {
		return onAssembly(new ParallelCollect<>(this, collectionSupplier, collector));
	}

public final < C > ParallelFlux < C > collect ( Supplier < ? extends C > collectionSupplier , BiConsumer < ? super C , ? super T > collector ) { return onAssembly ( new ParallelCollect <> ( this , collectionSupplier , collector ) ) ; }

Collect the elements in each rail into a collection supplied via a
collectionSupplier and collected into with a collector action, emitting the
collection at the end.

@param <C> the collection type
@param collectionSupplier the supplier of the collection in each rail
@param collector the collector, taking the per-rail collection and the current
item

@return the new {@link ParallelFlux} instance

Collect the elements in each rail into a collection supplied via a collectionSupplier and collected into with a collector action emitting the collection at the end .


public final <R> ParallelFlux<R> concatMap(Function<? super T, ? extends Publisher<? extends R>> mapper) {
		return concatMap(mapper, 2, ErrorMode.IMMEDIATE);
	}

public final < R > ParallelFlux < R > concatMap ( Function < ? super T , ? extends Publisher < ? extends R > > mapper ) { return concatMap ( mapper , 2 , ErrorMode . IMMEDIATE ) ; }

Generates and concatenates Publishers on each 'rail', signalling errors immediately
and generating 2 publishers upfront.

@param <R> the result type
@param mapper the function to map each rail's value into a Publisher source and the
inner Publishers (immediate, boundary, end)

@return the new {@link ParallelFlux} instance

Generates and concatenates Publishers on each rail signalling errors immediately and generating 2 publishers upfront .


public final ParallelFlux<T> doOnCancel(Runnable onCancel) {
		Objects.requireNonNull(onCancel, "onCancel");
		return doOnSignal(this, null, null, null, null, null, null, null, onCancel);
	}

public final ParallelFlux < T > doOnCancel ( Runnable onCancel ) { Objects . requireNonNull ( onCancel , "onCancel" ) ; return doOnSignal ( this , null , null , null , null , null , null , null , onCancel ) ; }

Run the specified runnable when a 'rail' receives a cancellation.

@param onCancel the callback

@return the new {@link ParallelFlux} instance

Run the specified runnable when a rail receives a cancellation .


public final ParallelFlux<T> doOnComplete(Runnable onComplete) {
		Objects.requireNonNull(onComplete, "onComplete");
		return doOnSignal(this, null, null, null, onComplete, null, null, null, null);
	}

public final ParallelFlux < T > doOnComplete ( Runnable onComplete ) { Objects . requireNonNull ( onComplete , "onComplete" ) ; return doOnSignal ( this , null , null , null , onComplete , null , null , null , null ) ; }

Run the specified runnable when a 'rail' completes.

@param onComplete the callback

@return the new {@link ParallelFlux} instance

Run the specified runnable when a rail completes .


public final ParallelFlux<T> doOnError(Consumer<? super Throwable> onError) {
		Objects.requireNonNull(onError, "onError");
		return doOnSignal(this, null, null, onError, null, null, null, null, null);
	}

public final ParallelFlux < T > doOnError ( Consumer < ? super Throwable > onError ) { Objects . requireNonNull ( onError , "onError" ) ; return doOnSignal ( this , null , null , onError , null , null , null , null , null ) ; }

Call the specified consumer with the exception passing through any 'rail'.

@param onError the callback

@return the new {@link ParallelFlux} instance

Call the specified consumer with the exception passing through any rail .


public final ParallelFlux<T> doOnRequest(LongConsumer onRequest) {
		Objects.requireNonNull(onRequest, "onRequest");
		return doOnSignal(this, null, null, null, null, null, null, onRequest, null);
	}

public final ParallelFlux < T > doOnRequest ( LongConsumer onRequest ) { Objects . requireNonNull ( onRequest , "onRequest" ) ; return doOnSignal ( this , null , null , null , null , null , null , onRequest , null ) ; }

Call the specified consumer with the request amount if any rail receives a
request.

@param onRequest the callback

@return the new {@link ParallelFlux} instance

Call the specified consumer with the request amount if any rail receives a request .


public final <R> ParallelFlux<R> flatMap(Function<? super T, ? extends Publisher<? extends R>> mapper,
			boolean delayError,
			int maxConcurrency,
			int prefetch) {
		return onAssembly(new ParallelFlatMap<>(this,
				mapper,
				delayError,
				maxConcurrency,
				Queues.get(maxConcurrency),
				prefetch, Queues.get(prefetch)));
	}

public final < R > ParallelFlux < R > flatMap ( Function < ? super T , ? extends Publisher < ? extends R > > mapper , boolean delayError , int maxConcurrency , int prefetch ) { return onAssembly ( new ParallelFlatMap <> ( this , mapper , delayError , maxConcurrency , Queues . get ( maxConcurrency ) , prefetch , Queues . get ( prefetch ) ) ) ; }

Generates and flattens Publishers on each 'rail', optionally delaying errors,
having a total number of simultaneous subscriptions to the inner Publishers and
using the given prefetch amount for the inner Publishers.

@param <R> the result type
@param mapper the function to map each rail's value into a Publisher
@param delayError should the errors from the main and the inner sources delayed
till everybody terminates?
@param maxConcurrency the maximum number of simultaneous subscriptions to the
generated inner Publishers
@param prefetch the number of items to prefetch from each inner Publisher

@return the new {@link ParallelFlux} instance

Generates and flattens Publishers on each rail optionally delaying errors having a total number of simultaneous subscriptions to the inner Publishers and using the given prefetch amount for the inner Publishers .


public final Flux<T> sequential(int prefetch) {
		return Flux.onAssembly(new ParallelMergeSequential<>(this,
				prefetch,
				Queues.get(prefetch)));
	}

public final Flux < T > sequential ( int prefetch ) { return Flux . onAssembly ( new ParallelMergeSequential <> ( this , prefetch , Queues . get ( prefetch ) ) ) ; }

Merges the values from each 'rail' in a round-robin or same-order fashion and
exposes it as a regular Publisher sequence, running with a give prefetch value for
the rails.

@param prefetch the prefetch amount to use for each rail

@return the new Flux instance

Merges the values from each rail in a round - robin or same - order fashion and exposes it as a regular Publisher sequence running with a give prefetch value for the rails .


protected final boolean validate(Subscriber<?>[] subscribers) {
		int p = parallelism();
		if (subscribers.length != p) {
			IllegalArgumentException iae = new IllegalArgumentException("parallelism = " +
					"" + p + ", subscribers = " + subscribers.length);
			for (Subscriber<?> s : subscribers) {
				Operators.error(s, iae);
			}
			return false;
		}
		return true;
	}

protected
final
boolean
validate
(
Subscriber
<
>
[
]
subscribers
)
{
int
p
=
parallelism
(
)
;
if
(
subscribers
.
length
!=
p
)
{
IllegalArgumentException
iae
=
new
IllegalArgumentException
(
"parallelism = "
+
""
+
p
+
", subscribers = "
+
subscribers
.
length
)
;
for
(
Subscriber
<
>
s
:
subscribers
)
{
Operators
.
error
(
s
,
iae
)
;
}
return
false
;
}
return
true
;
}

Validates the number of subscribers and returns true if their number matches the
parallelism level of this ParallelFlux.

@param subscribers the array of Subscribers

@return true if the number of subscribers equals to the parallelism level

Validates the number of subscribers and returns true if their number matches the parallelism level of this ParallelFlux .


final <R> ParallelFlux<R> concatMap(Function<? super T, ? extends Publisher<? extends R>> mapper,
			int prefetch,
			ErrorMode errorMode) {
		return onAssembly(new ParallelConcatMap<>(this,
				mapper,
				Queues.get(prefetch),
				prefetch,
				errorMode));
	}

final < R > ParallelFlux < R > concatMap ( Function < ? super T , ? extends Publisher < ? extends R > > mapper , int prefetch , ErrorMode errorMode ) { return onAssembly ( new ParallelConcatMap <> ( this , mapper , Queues . get ( prefetch ) , prefetch , errorMode ) ) ; }

Generates and concatenates Publishers on each 'rail', optionally delaying errors
and using the given prefetch amount for generating Publishers upfront.

@param <R> the result type
@param mapper the function to map each rail's value into a Publisher
@param prefetch the number of items to prefetch from each inner Publisher
@param errorMode the error handling, i.e., when to report errors from the main
source and the inner Publishers (immediate, boundary, end)

@return the new {@link ParallelFlux} instance

Generates and concatenates Publishers on each rail optionally delaying errors and using the given prefetch amount for generating Publishers upfront .


final <R> ParallelFlux<R> concatMapDelayError(Function<? super T, ? extends
			Publisher<? extends R>> mapper,
			boolean delayUntilEnd,
			int prefetch) {
		return concatMap(mapper, prefetch, delayUntilEnd ? ErrorMode.END: ErrorMode.BOUNDARY);
	}

final < R > ParallelFlux < R > concatMapDelayError ( Function < ? super T , ? extends Publisher < ? extends R > > mapper , boolean delayUntilEnd , int prefetch ) { return concatMap ( mapper , prefetch , delayUntilEnd ? ErrorMode . END : ErrorMode . BOUNDARY ) ; }

Generates and concatenates Publishers on each 'rail', delaying errors
and using the given prefetch amount for generating Publishers upfront.

@param <R> the result type
@param mapper the function to map each rail's value into a Publisher
@param delayUntilEnd true if delayed until all sources are concatenated
@param prefetch the number of items to prefetch from each inner Publisher
source and the inner Publishers (immediate, boundary, end)

@return the new {@link ParallelFlux} instance

Generates and concatenates Publishers on each rail delaying errors and using the given prefetch amount for generating Publishers upfront .


@Nullable
	public static <T> Throwable terminate(AtomicReferenceFieldUpdater<T, Throwable> field,
			T instance) {
		Throwable current = field.get(instance);
		if (current != TERMINATED) {
			current = field.getAndSet(instance, TERMINATED);
		}
		return current;
	}

@ Nullable public static < T > Throwable terminate ( AtomicReferenceFieldUpdater < T , Throwable > field , T instance ) { Throwable current = field . get ( instance ) ; if ( current != TERMINATED ) { current = field . getAndSet ( instance , TERMINATED ) ; } return current ; }

Atomic utility to safely mark a volatile throwable reference with a terminal
marker.

@param field the atomic container
@param instance the reference instance
@param <T> the instance type

@return the previously masked throwable

Atomic utility to safely mark a volatile throwable reference with a terminal marker .


void log(SignalType signalType, Object signalValue) {
		String line = fuseable ? LOG_TEMPLATE_FUSEABLE : LOG_TEMPLATE;
		if (operatorLine != null) {
			line = line + " " + operatorLine;
		}
		if (level == Level.FINEST) {
			log.trace(line, signalType, signalValue);
		}
		else if (level == Level.FINE) {
			log.debug(line, signalType, signalValue);
		}
		else if (level == Level.INFO) {
			log.info(line, signalType, signalValue);
		}
		else if (level == Level.WARNING) {
			log.warn(line, signalType, signalValue);
		}
		else if (level == Level.SEVERE) {
			log.error(line, signalType, signalValue);
		}
	}

void
log
(
SignalType
signalType
,
Object
signalValue
)
{
String
line
=
fuseable
LOG_TEMPLATE_FUSEABLE
:
LOG_TEMPLATE
;
if
(
operatorLine
!=
)
{
line
=
line
+
" "
+
operatorLine
;
}
if
(
level
==
Level
.
FINEST
)
{
log
.
trace
(
line
,
signalType
,
signalValue
)
;
}
else
if
(
level
==
Level
.
FINE
)
{
log
.
debug
(
line
,
signalType
,
signalValue
)
;
}
else
if
(
level
==
Level
.
INFO
)
{
log
.
info
(
line
,
signalType
,
signalValue
)
;
}
else
if
(
level
==
Level
.
WARNING
)
{
log
.
warn
(
line
,
signalType
,
signalValue
)
;
}
else
if
(
level
==
Level
.
SEVERE
)
{
log
.
error
(
line
,
signalType
,
signalValue
)
;
}
}

Structured logging with level adaptation and operator ascii graph if required.

@param signalType the type of signal being logged
@param signalValue the value for the signal (use empty string if not required)

Structured logging with level adaptation and operator ascii graph if required .


public boolean start(final FileDownloadListener listener, final boolean isSerial) {

        if (listener == null) {
            FileDownloadLog.w(this, "Tasks with the listener can't start, because the listener "
                    + "provided is null: [null, %B]", isSerial);
            return false;
        }

        return isSerial
                ? getQueuesHandler().startQueueSerial(listener)
                : getQueuesHandler().startQueueParallel(listener);
    }

Start the download queue by the same listener.

@param listener Used to assemble tasks which is bound by the same {@code listener}
@param isSerial Whether start tasks one by one rather than parallel.
@return {@code true} if start tasks successfully.

Start the download queue by the same listener .


public void pauseAll() {
        FileDownloadTaskLauncher.getImpl().expireAll();
        final BaseDownloadTask.IRunningTask[] downloadList = FileDownloadList.getImpl().copy();
        for (BaseDownloadTask.IRunningTask task : downloadList) {
            task.getOrigin().pause();
        }
        // double check, for case: File Download progress alive but ui progress has died and relived
        // so FileDownloadList not always contain all running task exactly.
        if (FileDownloadServiceProxy.getImpl().isConnected()) {
            FileDownloadServiceProxy.getImpl().pauseAllTasks();
        } else {
            PauseAllMarker.createMarker();
        }
    }

Pause all tasks running in FileDownloader.

Pause all tasks running in FileDownloader .


public long getSoFar(final int downloadId) {
        BaseDownloadTask.IRunningTask task = FileDownloadList.getImpl().get(downloadId);
        if (task == null) {
            return FileDownloadServiceProxy.getImpl().getSofar(downloadId);
        }

        return task.getOrigin().getLargeFileSoFarBytes();
    }

public long getSoFar ( final int downloadId ) { BaseDownloadTask . IRunningTask task = FileDownloadList . getImpl ( ) . get ( downloadId ) ; if ( task == null ) { return FileDownloadServiceProxy . getImpl ( ) . getSofar ( downloadId ) ; } return task . getOrigin ( ) . getLargeFileSoFarBytes ( ) ; }

Get downloaded bytes so far by the downloadId.

Get downloaded bytes so far by the downloadId .


public boolean unBindServiceIfIdle() {
        // check idle
        if (!isServiceConnected()) {
            return false;
        }

        if (FileDownloadList.getImpl().isEmpty()
                && FileDownloadServiceProxy.getImpl().isIdle()) {
            unBindService();
            return true;
        }

        return false;
    }

public
boolean
unBindServiceIfIdle
(
)
{
// check idle
if
(
!
isServiceConnected
(
)
)
{
return
false
;
}
if
(
FileDownloadList
.
getImpl
(
)
.
isEmpty
(
)
&&
FileDownloadServiceProxy
.
getImpl
(
)
.
isIdle
(
)
)
{
unBindService
(
)
;
return
true
;
}
return
false
;
}

Unbind and stop the downloader service when there is no task running in the FileDownloader.

@return {@code true} if unbind and stop the downloader service successfully, {@code false}
there are some tasks running in the FileDownloader.

Unbind and stop the downloader service when there is no task running in the FileDownloader .


public boolean setMaxNetworkThreadCount(final int count) {
        if (!FileDownloadList.getImpl().isEmpty()) {
            FileDownloadLog.w(this, "Can't change the max network thread count, because there "
                    + "are actively executing tasks in FileDownloader, please try again after all"
                    + " actively executing tasks are completed or invoking FileDownloader#pauseAll"
                    + " directly.");
            return false;
        }

        return FileDownloadServiceProxy.getImpl().setMaxNetworkThreadCount(count);
    }

Set the maximum count of the network thread, what is the number of simultaneous downloads in
FileDownloader.

@param count the number of simultaneous downloads, scope: [1, 12].
@return whether is successful to set the max network thread count.
If there are any actively executing tasks in FileDownloader, you will receive a warn
priority log int the logcat and this operation would be failed.

Set the maximum count of the network thread what is the number of simultaneous downloads in FileDownloader .


public void pauseAll() {
        List<Integer> list = mThreadPool.getAllExactRunningDownloadIds();

        if (FileDownloadLog.NEED_LOG) {
            FileDownloadLog.d(this, "pause all tasks %d", list.size());
        }

        for (Integer id : list) {
            pause(id);
        }
    }

public
void
pauseAll
(
)
{
List
<
Integer
>
list
=
mThreadPool
.
getAllExactRunningDownloadIds
(
)
;
if
(
FileDownloadLog
.
NEED_LOG
)
{
FileDownloadLog
.
d
(
this
,
"pause all tasks %d"
,
list
.
size
(
)
)
;
}
for
(
Integer
id
:
list
)
{
pause
(
id
)
;
}
}


public void start() {
        for (BaseDownloadTask task : tasks) {
            task.setListener(target);

            if (autoRetryTimes != null) {
                task.setAutoRetryTimes(autoRetryTimes);
            }

            if (syncCallback != null) {
                task.setSyncCallback(syncCallback);
            }

            if (isForceReDownload != null) {
                task.setForceReDownload(isForceReDownload);
            }

            if (callbackProgressTimes != null) {
                task.setCallbackProgressTimes(callbackProgressTimes);
            }

            if (callbackProgressMinIntervalMillis != null) {
                task.setCallbackProgressMinInterval(callbackProgressMinIntervalMillis);
            }

            if (tag != null) {
                task.setTag(tag);
            }

            if (taskFinishListenerList != null) {
                for (BaseDownloadTask.FinishListener finishListener : taskFinishListenerList) {
                    task.addFinishListener(finishListener);
                }
            }

            if (this.directory != null) {
                task.setPath(this.directory, true);
            }

            if (this.isWifiRequired != null) {
                task.setWifiRequired(this.isWifiRequired);
            }

            task.asInQueueTask().enqueue();
        }

        FileDownloader.getImpl().start(target, isSerial);
    }

public void start ( ) { for ( BaseDownloadTask task : tasks ) { task . setListener ( target ) ; if ( autoRetryTimes != null ) { task . setAutoRetryTimes ( autoRetryTimes ) ; } if ( syncCallback != null ) { task . setSyncCallback ( syncCallback ) ; } if ( isForceReDownload != null ) { task . setForceReDownload ( isForceReDownload ) ; } if ( callbackProgressTimes != null ) { task . setCallbackProgressTimes ( callbackProgressTimes ) ; } if ( callbackProgressMinIntervalMillis != null ) { task . setCallbackProgressMinInterval ( callbackProgressMinIntervalMillis ) ; } if ( tag != null ) { task . setTag ( tag ) ; } if ( taskFinishListenerList != null ) { for ( BaseDownloadTask . FinishListener finishListener : taskFinishListenerList ) { task . addFinishListener ( finishListener ) ; } } if ( this . directory != null ) { task . setPath ( this . directory , true ) ; } if ( this . isWifiRequired != null ) { task . setWifiRequired ( this . isWifiRequired ) ; } task . asInQueueTask ( ) . enqueue ( ) ; } FileDownloader . getImpl ( ) . start ( target , isSerial ) ; }

Start tasks in a queue.

@see #downloadSequentially(BaseDownloadTask...)
@see #downloadSequentially(List)
@see #downloadTogether(BaseDownloadTask...)
@see #downloadTogether(List)


void divertAndIgnoreDuplicate(
            @SuppressWarnings("SameParameterValue") final List<BaseDownloadTask.IRunningTask>
                    destination) {
        synchronized (mList) {
            for (BaseDownloadTask.IRunningTask iRunningTask : mList) {
                if (!destination.contains(iRunningTask)) {
                    destination.add(iRunningTask);
                }
            }
            mList.clear();
        }
    }

void divertAndIgnoreDuplicate ( @ SuppressWarnings ( "SameParameterValue" ) final List < BaseDownloadTask . IRunningTask > destination ) { synchronized ( mList ) { for ( BaseDownloadTask . IRunningTask iRunningTask : mList ) { if ( ! destination . contains ( iRunningTask ) ) { destination . add ( iRunningTask ) ; } } mList . clear ( ) ; } }

Divert all data in list 2 destination list


void addUnchecked(final BaseDownloadTask.IRunningTask task) {
        if (task.isMarkedAdded2List()) {
            return;
        }

        synchronized (mList) {
            if (mList.contains(task)) {
                FileDownloadLog.w(this, "already has %s", task);
            } else {
                task.markAdded2List();
                mList.add(task);
                if (FileDownloadLog.NEED_LOG) {
                    FileDownloadLog.v(this, "add list in all %s %d %d", task,
                            task.getOrigin().getStatus(), mList.size());
                }
            }
        }
    }

void
addUnchecked
(
final
BaseDownloadTask
.
IRunningTask
task
)
{
if
(
task
.
isMarkedAdded2List
(
)
)
{
return
;
}
synchronized
(
mList
)
{
if
(
mList
.
contains
(
task
)
)
{
FileDownloadLog
.
w
(
this
,
"already has %s"
,
task
)
;
}
else
{
task
.
markAdded2List
(
)
;
mList
.
add
(
task
)
;
if
(
FileDownloadLog
.
NEED_LOG
)
{
FileDownloadLog
.
v
(
this
,
"add list in all %s %d %d"
,
task
,
task
.
getOrigin
(
)
.
getStatus
(
)
,
mList
.
size
(
)
)
;
}
}
}
}

This method generally used for enqueuing the task which will be assembled by a queue.

@see BaseDownloadTask.InQueueTask#enqueue()

This method generally used for enqueuing the task which will be assembled by a queue .


public void pause() {
        synchronized (finishCallback) {
            if (paused) {
                FileDownloadLog.w(this, "require pause this queue(remain %d), but "
                        + "it has already been paused", mTasks.size());
                return;
            }

            paused = true;
            mTasks.drainTo(pausedList);
            if (workingTask != null) {
                workingTask.removeFinishListener(finishCallback);
                workingTask.pause();
            }
        }

    }


public void resume() {
        synchronized (finishCallback) {
            if (!paused) {
                FileDownloadLog.w(this, "require resume this queue(remain %d), but it is"
                        + " still running", mTasks.size());
                return;
            }

            paused = false;
            mTasks.addAll(pausedList);
            pausedList.clear();

            if (workingTask == null) {
                sendNext();
            } else {
                workingTask.addFinishListener(finishCallback);
                workingTask.start();
            }
        }
    }

Resume the queue if the queue is paused.

@see #pause()

Resume the queue if the queue is paused .


public static boolean isAcceptRange(int responseCode, FileDownloadConnection connection) {
        if (responseCode == HttpURLConnection.HTTP_PARTIAL
                || responseCode == FileDownloadConnection.RESPONSE_CODE_FROM_OFFSET) return true;

        final String acceptRanges = connection.getResponseHeaderField("Accept-Ranges");
        return "bytes".equals(acceptRanges);
    }

public static boolean isAcceptRange ( int responseCode , FileDownloadConnection connection ) { if ( responseCode == HttpURLConnection . HTTP_PARTIAL || responseCode == FileDownloadConnection . RESPONSE_CODE_FROM_OFFSET ) return true ; final String acceptRanges = connection . getResponseHeaderField ( "Accept-Ranges" ) ; return "bytes" . equals ( acceptRanges ) ; }

accept range is effect by  response code and Accept-Ranges header field.

accept range is effect by response code and Accept - Ranges header field .


public static long findInstanceLengthForTrial(FileDownloadConnection connection) {
        long length = findInstanceLengthFromContentRange(connection);
        if (length < 0) {
            length = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
            FileDownloadLog.w(FileDownloadUtils.class, "don't get instance length from"
                    + "Content-Range header");
        }
        // the response of HEAD method is not very canonical sometimes(it depends on server
        // implementation)
        // so that it's uncertain the content-length is the same as the response of GET method if
        // content-length=0, so we have to filter this case in here.
        if (length == 0 && FileDownloadProperties.getImpl().trialConnectionHeadMethod) {
            length = TOTAL_VALUE_IN_CHUNKED_RESOURCE;
        }

        return length;
    }


public void setAnimated(boolean animated) {
        mIsAnimated = animated;
        mOpenAnimatorSet.setDuration(animated ? ANIMATION_DURATION : 0);
        mCloseAnimatorSet.setDuration(animated ? ANIMATION_DURATION : 0);
    }

public void setAnimated ( boolean animated ) { mIsAnimated = animated ; mOpenAnimatorSet . setDuration ( animated ? ANIMATION_DURATION : 0 ) ; mCloseAnimatorSet . setDuration ( animated ? ANIMATION_DURATION : 0 ) ; }

Sets whether open and close actions should be animated

@param animated if <b>false</b> - menu items will appear/disappear instantly without any animation


@TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public void setElevationCompat(float elevation) {
        mShadowColor = 0x26000000;
        mShadowRadius = Math.round(elevation / 2);
        mShadowXOffset = 0;
        mShadowYOffset = Math.round(mFabSize == SIZE_NORMAL ? elevation : elevation / 2);

        if (Util.hasLollipop()) {
            super.setElevation(elevation);
            mUsingElevationCompat = true;
            mShowShadow = false;
            updateBackground();

            ViewGroup.LayoutParams layoutParams = getLayoutParams();
            if (layoutParams != null) {
                setLayoutParams(layoutParams);
            }
        } else {
            mShowShadow = true;
            updateBackground();
        }
    }

@ TargetApi ( Build . VERSION_CODES . LOLLIPOP ) public void setElevationCompat ( float elevation ) { mShadowColor = 0x26000000 ; mShadowRadius = Math . round ( elevation / 2 ) ; mShadowXOffset = 0 ; mShadowYOffset = Math . round ( mFabSize == SIZE_NORMAL ? elevation : elevation / 2 ) ; if ( Util . hasLollipop ( ) ) { super . setElevation ( elevation ) ; mUsingElevationCompat = true ; mShowShadow = false ; updateBackground ( ) ; ViewGroup . LayoutParams layoutParams = getLayoutParams ( ) ; if ( layoutParams != null ) { setLayoutParams ( layoutParams ) ; } } else { mShowShadow = true ; updateBackground ( ) ; } }

Sets the shadow color and radius to mimic the native elevation.

API 21+: Sets the native elevation of this view, in pixels. Updates margins to
make the view hold its position in layout across different platform versions.

Sets the shadow color and radius to mimic the native elevation .


public void setLabelColors(int colorNormal, int colorPressed, int colorRipple) {
        Label label = getLabelView();

        int left = label.getPaddingLeft();
        int top = label.getPaddingTop();
        int right = label.getPaddingRight();
        int bottom = label.getPaddingBottom();

        label.setColors(colorNormal, colorPressed, colorRipple);
        label.updateBackground();
        label.setPadding(left, top, right, bottom);
    }

public void setLabelColors ( int colorNormal , int colorPressed , int colorRipple ) { Label label = getLabelView ( ) ; int left = label . getPaddingLeft ( ) ; int top = label . getPaddingTop ( ) ; int right = label . getPaddingRight ( ) ; int bottom = label . getPaddingBottom ( ) ; label . setColors ( colorNormal , colorPressed , colorRipple ) ; label . updateBackground ( ) ; label . setPadding ( left , top , right , bottom ) ; }


@Override
    public void addConfigurationProperties(Properties properties) {
        suppressDate = isTrue(properties
                .getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));

        suppressAllComments = isTrue(properties
                .getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
    }

@ Override public void addConfigurationProperties ( Properties properties ) { suppressDate = isTrue ( properties . getProperty ( PropertyRegistry . COMMENT_GENERATOR_SUPPRESS_DATE ) ) ; suppressAllComments = isTrue ( properties . getProperty ( PropertyRegistry . COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS ) ) ; }

Adds properties for this instance from any properties configured in the
CommentGenerator configuration.

This method will be called before any of the other methods.

@param properties
All properties from the configuration

Adds properties for this instance from any properties configured in the CommentGenerator configuration .


@Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        Map<String, Object> map = new HashMap<>();
        map.put("mgb", MergeConstants.NEW_ELEMENT_TAG);
        map.put("topLevelClass", topLevelClass);
        map.put("introspectedTable", introspectedTable);

        // 添加评论
        addJavaElementComment(topLevelClass, map, EnumNode.ADD_MODEL_CLASS_COMMENT);
    }

@
Override
public
void
addModelClassComment
(
TopLevelClass
topLevelClass
,
IntrospectedTable
introspectedTable
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>
(
)
;
map
.
put
(
"mgb"
,
MergeConstants
.
NEW_ELEMENT_TAG
)
;
map
.
put
(
"topLevelClass"
,
topLevelClass
)
;
map
.
put
(
"introspectedTable"
,
introspectedTable
)
;
// 添加评论
addJavaElementComment
(
topLevelClass
,
map
,
EnumNode
.
ADD_MODEL_CLASS_COMMENT
)
;
}

Adds a comment for a model class.  The Java code merger should
be notified not to delete the entire class in case any manual
changes have been made.  So this method will always use the
"do not delete" annotation.

Because of difficulties with the Java file merger, the default implementation
of this method should NOT add comments.  Comments should only be added if
specifically requested by the user (for example, by enabling table remark comments).

@param topLevelClass
the top level class
@param introspectedTable
the introspected table

Adds a comment for a model class . The Java code merger should be notified not to delete the entire class in case any manual changes have been made . So this method will always use the do not delete annotation .


@Override
    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
        Map<String, Object> map = new HashMap<>();
        map.put("mgb", MergeConstants.NEW_ELEMENT_TAG);
        map.put("innerEnum", innerEnum);
        map.put("introspectedTable", introspectedTable);

        // 添加评论
        addJavaElementComment(innerEnum, map, EnumNode.ADD_ENUM_COMMENT);
    }

@
Override
public
void
addEnumComment
(
InnerEnum
innerEnum
,
IntrospectedTable
introspectedTable
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>
(
)
;
map
.
put
(
"mgb"
,
MergeConstants
.
NEW_ELEMENT_TAG
)
;
map
.
put
(
"innerEnum"
,
innerEnum
)
;
map
.
put
(
"introspectedTable"
,
introspectedTable
)
;
// 添加评论
addJavaElementComment
(
innerEnum
,
map
,
EnumNode
.
ADD_ENUM_COMMENT
)
;
}

Adds the enum comment.

@param innerEnum
the inner enum
@param introspectedTable
the introspected table


@Override
    public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        Map<String, Object> map = new HashMap<>();
        map.put("mgb", MergeConstants.NEW_ELEMENT_TAG);
        map.put("method", method);
        map.put("introspectedTable", introspectedTable);
        map.put("introspectedColumn", introspectedColumn);

        // 添加评论
        addJavaElementComment(method, map, EnumNode.ADD_GETTER_COMMENT);
    }

@
Override
public
void
addGetterComment
(
Method
method
,
IntrospectedTable
introspectedTable
,
IntrospectedColumn
introspectedColumn
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>
(
)
;
map
.
put
(
"mgb"
,
MergeConstants
.
NEW_ELEMENT_TAG
)
;
map
.
put
(
"method"
,
method
)
;
map
.
put
(
"introspectedTable"
,
introspectedTable
)
;
map
.
put
(
"introspectedColumn"
,
introspectedColumn
)
;
// 添加评论
addJavaElementComment
(
method
,
map
,
EnumNode
.
ADD_GETTER_COMMENT
)
;
}

Adds the getter comment.

@param method
the method
@param introspectedTable
the introspected table
@param introspectedColumn
the introspected column


@Override
    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
        Map<String, Object> map = new HashMap<>();
        map.put("mgb", MergeConstants.NEW_ELEMENT_TAG);
        map.put("method", method);
        map.put("introspectedTable", introspectedTable);

        // 添加评论
        addJavaElementComment(method, map, EnumNode.ADD_GENERAL_METHOD_COMMENT);
    }

@
Override
public
void
addGeneralMethodComment
(
Method
method
,
IntrospectedTable
introspectedTable
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>
(
)
;
map
.
put
(
"mgb"
,
MergeConstants
.
NEW_ELEMENT_TAG
)
;
map
.
put
(
"method"
,
method
)
;
map
.
put
(
"introspectedTable"
,
introspectedTable
)
;
// 添加评论
addJavaElementComment
(
method
,
map
,
EnumNode
.
ADD_GENERAL_METHOD_COMMENT
)
;
}

Adds the general method comment.

@param method
the method
@param introspectedTable
the introspected table


@Override
    public void addComment(XmlElement xmlElement) {
        Map<String, Object> map = new HashMap<>();
        map.put("mgb", MergeConstants.NEW_ELEMENT_TAG);
        map.put("xmlElement", xmlElement);

        // 添加评论
        addXmlElementComment(xmlElement, map, EnumNode.ADD_COMMENT);
    }

@
Override
public
void
addComment
(
XmlElement
xmlElement
)
{
Map
<
String
,
Object
>
map
=
new
HashMap
<>
(
)
;
map
.
put
(
"mgb"
,
MergeConstants
.
NEW_ELEMENT_TAG
)
;
map
.
put
(
"xmlElement"
,
xmlElement
)
;
// 添加评论
addXmlElementComment
(
xmlElement
,
map
,
EnumNode
.
ADD_COMMENT
)
;
}

This method should add a suitable comment as a child element of the specified xmlElement to warn users that the
element was generated and is subject to regeneration.

@param xmlElement
the xml element

This method should add a suitable comment as a child element of the specified xmlElement to warn users that the element was generated and is subject to regeneration .


@Override
    public String getFullyQualifiedName() {
        String fullyQualifiedName = super.getFullyQualifiedName();
        String before = fullyQualifiedName.substring(0, fullyQualifiedName.lastIndexOf("."));
        String end = fullyQualifiedName.substring(fullyQualifiedName.lastIndexOf("."));
        return before + "." + outerType + end;
    }

@ Override public String getFullyQualifiedName ( ) { String fullyQualifiedName = super . getFullyQualifiedName ( ) ; String before = fullyQualifiedName . substring ( 0 , fullyQualifiedName . lastIndexOf ( "." ) ) ; String end = fullyQualifiedName . substring ( fullyQualifiedName . lastIndexOf ( "." ) ) ; return before + "." + outerType + end ; }

This method returns the fully qualified name - including any generic type parameters.

@return Returns the fullyQualifiedName.

This method returns the fully qualified name - including any generic type parameters .


public static Element getSelectKey(IntrospectedColumn introspectedColumn, GeneratedKey generatedKey) {
        return getSelectKey(introspectedColumn, generatedKey, null);
    }

public static Element getSelectKey ( IntrospectedColumn introspectedColumn , GeneratedKey generatedKey ) { return getSelectKey ( introspectedColumn , generatedKey , null ) ; }

This method should return an XmlElement for the select key used to
automatically generate keys.
@param introspectedColumn the column related to the select key statement
@param generatedKey       the generated key for the current table
@return the selectKey element

This method should return an XmlElement for the select key used to automatically generate keys .


public PackageResourceTable newFrameworkResourceTable(ResourcePath resourcePath) {
    return PerfStatsCollector.getInstance()
        .measure(
            "load legacy framework resources",
            () -> {
              PackageResourceTable resourceTable = new PackageResourceTable("android");

              if (resourcePath.getRClass() != null) {
                addRClassValues(resourceTable, resourcePath.getRClass());
                addMissingStyleableAttributes(resourceTable, resourcePath.getRClass());
              }
              if (resourcePath.getInternalRClass() != null) {
                addRClassValues(resourceTable, resourcePath.getInternalRClass());
                addMissingStyleableAttributes(resourceTable, resourcePath.getInternalRClass());
              }

              parseResourceFiles(resourcePath, resourceTable);

              return resourceTable;
            });
  }

public
PackageResourceTable
newFrameworkResourceTable
(
ResourcePath
resourcePath
)
{
return
PerfStatsCollector
.
getInstance
(
)
.
measure
(
"load legacy framework resources"
,
(
)
->
{
PackageResourceTable
resourceTable
=
new
PackageResourceTable
(
"android"
)
;
if
(
resourcePath
.
getRClass
(
)
!=
)
{
addRClassValues
(
resourceTable
,
resourcePath
.
getRClass
(
)
)
;
addMissingStyleableAttributes
(
resourceTable
,
resourcePath
.
getRClass
(
)
)
;
}
if
(
resourcePath
.
getInternalRClass
(
)
!=
)
{
addRClassValues
(
resourceTable
,
resourcePath
.
getInternalRClass
(
)
)
;
addMissingStyleableAttributes
(
resourceTable
,
resourcePath
.
getInternalRClass
(
)
)
;
}
parseResourceFiles
(
resourcePath
,
resourceTable
)
;
return
resourceTable
;
}
)
;
}

Builds an Android framework resource table in the "android" package space.

Builds an Android framework resource table in the android package space .


public PackageResourceTable newResourceTable(String packageName, ResourcePath... resourcePaths) {
    return PerfStatsCollector.getInstance()
        .measure(
            "load legacy app resources",
            () -> {
              PackageResourceTable resourceTable = new PackageResourceTable(packageName);

              for (ResourcePath resourcePath : resourcePaths) {
                if (resourcePath.getRClass() != null) {
                  addRClassValues(resourceTable, resourcePath.getRClass());
                }
              }

              for (ResourcePath resourcePath : resourcePaths) {
                parseResourceFiles(resourcePath, resourceTable);
              }

              return resourceTable;
            });
  }

public
PackageResourceTable
newResourceTable
(
String
packageName
,
ResourcePath
...
resourcePaths
)
{
return
PerfStatsCollector
.
getInstance
(
)
.
measure
(
"load legacy app resources"
,
(
)
->
{
PackageResourceTable
resourceTable
=
new
PackageResourceTable
(
packageName
)
;
for
(
ResourcePath
resourcePath
:
resourcePaths
)
{
if
(
resourcePath
.
getRClass
(
)
!=
)
{
addRClassValues
(
resourceTable
,
resourcePath
.
getRClass
(
)
)
;
}
}
for
(
ResourcePath
resourcePath
:
resourcePaths
)
{
parseResourceFiles
(
resourcePath
,
resourceTable
)
;
}
return
resourceTable
;
}
)
;
}

Creates an application resource table which can be constructed with multiple resources paths
representing overlayed resource libraries.

Creates an application resource table which can be constructed with multiple resources paths representing overlayed resource libraries .