Class GridDhtPartitionsExchangeFuture
- java.lang.Object
-
- org.apache.ignite.internal.util.future.GridFutureAdapter<AffinityTopologyVersion>
-
- org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFutureAdapter
-
- org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture
-
- All Implemented Interfaces:
Comparable<GridDhtPartitionsExchangeFuture>,IgniteDiagnosticAware,IgniteInternalFuture<AffinityTopologyVersion>,CachePartitionExchangeWorkerTask,GridDhtTopologyFuture
public class GridDhtPartitionsExchangeFuture extends GridDhtTopologyFutureAdapter implements Comparable<GridDhtPartitionsExchangeFuture>, CachePartitionExchangeWorkerTask, IgniteDiagnosticAware
Future for exchanging partition maps.Note, that by default cache requests mapped to a stale topology version can be executed even if PME is in still in progress on back-up nodes but is finished on primary node. If this behaviour is unacceptable see
ExchangeContext.remapStaleCacheRequests()flag for more details.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classGridDhtPartitionsExchangeFuture.ExchangeType-
Nested classes/interfaces inherited from class org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFutureAdapter
GridDhtTopologyFutureAdapter.CacheGroupValidation
-
-
Field Summary
Fields Modifier and Type Field Description static intDFLT_LONG_OPERATIONS_DUMP_TIMEOUT_LIMITstatic intDFLT_PARTITION_RELEASE_FUTURE_DUMP_THRESHOLDstatic StringEXCHANGE_LATCH_IDstatic StringEXCHANGE_LOGstatic StringPARTITION_STATE_FAILED_MSGPartition state failed message.-
Fields inherited from class org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFutureAdapter
clusterIsActive, grpValidRes
-
-
Constructor Summary
Constructors Constructor Description GridDhtPartitionsExchangeFuture(GridCacheSharedContext cctx, ReadWriteLock busyLock, GridDhtPartitionExchangeId exchId, ExchangeActions exchActions, CacheAffinityChangeMessage affChangeMsg)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description booleanactivateCluster()voidaddClearingPartition(CacheGroupContext grp, int part)Marks a partition for clearing before rebalance.voidaddDiagnosticRequest(IgniteDiagnosticPrepareContext diagCtx)booleanaddOrMergeDelayedFullMessage(ClusterNode node, GridDhtPartitionsFullMessage fullMsg)Add or merge updates received from coordinator while exchange in progress.voidaffinityChangeMessage(CacheAffinityChangeMessage affChangeMsg)Sets affinity change message associated with the exchange.booleanaffinityReassign()booleancacheAddedOnExchange(int cacheId, UUID rcvdFrom)booleancacheGroupAddedOnExchange(int grpId, UUID rcvdFrom)booleanchangedAffinity()booleanchangedBaseline()voidcleanUp()Cleans up resources to avoid excessive memory usage.intcompareTo(GridDhtPartitionsExchangeFuture fut)ExchangeContextcontext()voidcopyInapplicableNodesFrom(GridDhtPartitionsExchangeFuture fut)Marks nodes as not applicable for full and historical rebalancing.longcurrentPMEDuration(boolean blocked)booleandynamicCacheGroupStarted(int grpId)booleanequals(Object o)ExchangeDiscoveryEventsevents()@Nullable ExchangeActionsexchangeActions()Gets exchanges actions (such as cache start or stop) associated with the exchange future.voidexchangeActions(ExchangeActions exchActions)Sets exchange actions associated with the exchange future (such as cache start or stop).booleanexchangeDone()Ready affinity future (GridCachePartitionExchangeManager.affinityReadyFuture(AffinityTopologyVersion)is completed beforeGridFutureAdapter.onDone(Object, Throwable)is called onGridDhtPartitionsExchangeFuture, it is guaranteed that this method will returntrueif affinity ready future is finished.GridDhtPartitionExchangeIdexchangeId()@Nullable GridDhtPartitionsExchangeFuture.ExchangeTypeexchangeType()booleanfastReplyOnSingleMessage(ClusterNode node, GridDhtPartitionsSingleMessage msg)Tries to fast reply withGridDhtPartitionsFullMessageon received single message in case of exchange future has already completed.booleanfinalizeCounters()voidfinishMerged(AffinityTopologyVersion resVer, GridDhtPartitionsExchangeFuture exchFut)Finish merged future to allow GridCachePartitionExchangeManager.ExchangeFutureSet cleanup.DiscoveryEventfirstEvent()DiscoCachefirstEventCache()voidforceClientReconnect(ClusterNode node, GridDhtPartitionsSingleMessage msg)Method is called on coordinator in situation when initial ExchangeFuture created on client join event was preempted from exchange history because of IGNITE_EXCHANGE_HISTORY_SIZE property.booleanhasCachesToStart()inthashCode()booleanhasInapplicableNodesForFullRebalance()booleanhasInapplicableNodesForHistoricalRebalance()booleanhasInapplicableNodesForRebalance()voidinit(boolean newCrd)Starts activity.AffinityTopologyVersioninitialVersion()Gets the affinity topology version for which this exchange was created.booleanisBaselineNodeFailed()booleanisClearingPartition(CacheGroupContext grp, int part)booleanisMerged()booleanisNodeApplicableForFullRebalance(UUID nodeId, int grpId, int p)booleanlocalJoinExchange()voidmarkAffinityReassign()Marks this future as affinity reassign.voidmarkNodeAsInapplicableForFullRebalance(UUID nodeId, int grpId, int p)Marks the given node as not applicable for full rebalancing for the given group and partition.voidmarkNodeAsInapplicableForHistoricalRebalance(UUID nodeId)Marks the given node as not applicable for historical rebalancing.booleanmergeJoinExchange(GridDhtPartitionsExchangeFuture fut)Merges this exchange with given one.@Nullable GridDhtPartitionsSingleMessagemergeJoinExchangeOnDone(GridDhtPartitionsExchangeFuture fut)Objectmutex()static longnextDumpTimeout(int step, long timeout)booleanonAdded()voidonAffinityChangeMessage(ClusterNode node, CacheAffinityChangeMessage msg)Affinity change message callback, processed from the same thread asonNodeLeft(org.apache.ignite.cluster.ClusterNode).booleanonDone(@Nullable AffinityTopologyVersion res, @Nullable Throwable err)Callback to notify that future is finished.voidonDynamicCacheChangeFail(ClusterNode node, DynamicCacheChangeFailureMessage msg)Cache change failure message callback, processed from the discovery thread.voidonEvent(GridDhtPartitionExchangeId exchId, DiscoveryEvent discoEvt, DiscoCache discoCache)Event callback.voidonNodeLeft(ClusterNode node)Node left callback, processed from the same thread asonAffinityChangeMessage(org.apache.ignite.cluster.ClusterNode, org.apache.ignite.internal.processors.cache.CacheAffinityChangeMessage).voidonReceiveFullMessage(ClusterNode node, GridDhtPartitionsFullMessage msg)voidonReceivePartitionRequest(ClusterNode node, GridDhtPartitionsSingleRequest msg)voidonReceiveSingleMessage(ClusterNode node, GridDhtPartitionsSingleMessage msg)Processing of received single message.List<UUID>partitionHistorySupplier(int grpId, int partId, long cntrSince)Retreives the node which has WAL history sincecntrSince.booleanrebalanced()booleanreconnectOnError(Throwable e)booleanresetLostPartitionFor(String cacheOrGroupName)@Nullable SecurityContextsecurityContext()booleanserverNodeDiscoveryEvent()GridCacheSharedContextsharedContext()StringshortInfo()booleanskipForExchangeMerge()Spanspan()Gets span instance.voidspan(Span span)Set span.TimeBagtimeBag()AffinityTopologyVersiontopologyVersion()Gets result topology version of this future.StringtoString()voidvalidate(CacheGroupContext grp)voidwaitAndReplyToNode(UUID nodeId, GridDhtPartitionsSingleMessage msg)booleanwasRebalanced()-
Methods inherited from class org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtTopologyFutureAdapter
hasLostPartitions, validateCache, validateCacheGroup
-
Methods inherited from class org.apache.ignite.internal.util.future.GridFutureAdapter
cancel, chain, chain, chain, chain, chainCompose, chainCompose, error, get, get, get, getUninterruptibly, ignoreInterrupts, isCancelled, isDone, isFailed, listen, listen, logger, onCancelled, onDone, onDone, onDone, onDone, reset, result
-
Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
-
Methods inherited from interface org.apache.ignite.internal.IgniteInternalFuture
cancel, chain, chain, chain, chain, chainCompose, chainCompose, error, get, get, get, getUninterruptibly, isCancelled, isDone, listen, listen, result
-
-
-
-
Field Detail
-
EXCHANGE_LOG
public static final String EXCHANGE_LOG
- See Also:
- Constant Field Values
-
PARTITION_STATE_FAILED_MSG
public static final String PARTITION_STATE_FAILED_MSG
Partition state failed message.- See Also:
- Constant Field Values
-
DFLT_PARTITION_RELEASE_FUTURE_DUMP_THRESHOLD
public static final int DFLT_PARTITION_RELEASE_FUTURE_DUMP_THRESHOLD
-
EXCHANGE_LATCH_ID
public static final String EXCHANGE_LATCH_ID
- See Also:
- Constant Field Values
-
DFLT_LONG_OPERATIONS_DUMP_TIMEOUT_LIMIT
public static final int DFLT_LONG_OPERATIONS_DUMP_TIMEOUT_LIMIT
-
-
Constructor Detail
-
GridDhtPartitionsExchangeFuture
public GridDhtPartitionsExchangeFuture(GridCacheSharedContext cctx, ReadWriteLock busyLock, GridDhtPartitionExchangeId exchId, ExchangeActions exchActions, CacheAffinityChangeMessage affChangeMsg)
- Parameters:
cctx- Cache context.busyLock- Busy lock.exchId- Exchange ID.exchActions- Cache change requests.affChangeMsg- Affinity change message.
-
-
Method Detail
-
span
public void span(Span span)
Set span.- Parameters:
span- Span.
-
span
public Span span()
Gets span instance.- Returns:
- Span.
-
mutex
public Object mutex()
- Returns:
- Future mutex.
-
sharedContext
public GridCacheSharedContext sharedContext()
- Returns:
- Shared cache context.
-
skipForExchangeMerge
public boolean skipForExchangeMerge()
- Specified by:
skipForExchangeMergein interfaceCachePartitionExchangeWorkerTask- Returns:
Falseif exchange merge should stop if this task is found in exchange worker queue.
-
securityContext
@Nullable public @Nullable SecurityContext securityContext()
- Specified by:
securityContextin interfaceCachePartitionExchangeWorkerTask- Returns:
- Security context in which current task must be executed.
nullmeans that the task is to run in the context of a local node,
-
context
public ExchangeContext context()
- Returns:
- Exchange context.
-
exchangeActions
public void exchangeActions(ExchangeActions exchActions)
Sets exchange actions associated with the exchange future (such as cache start or stop). Exchange actions is created from discovery event, so the actions must be set before the event is processed, thus the setter requires thatevtLatchbe armed.- Parameters:
exchActions- Exchange actions.
-
exchangeActions
@Nullable public @Nullable ExchangeActions exchangeActions()
Gets exchanges actions (such as cache start or stop) associated with the exchange future. Exchange actions can benull(for example, if the exchange is created for topology change event).- Returns:
- Exchange actions.
-
affinityChangeMessage
public void affinityChangeMessage(CacheAffinityChangeMessage affChangeMsg)
Sets affinity change message associated with the exchange. Affinity change message is required when centralized affinity change is performed.- Parameters:
affChangeMsg- Affinity change message.
-
initialVersion
public AffinityTopologyVersion initialVersion()
Gets the affinity topology version for which this exchange was created. If several exchanges were merged, initial version is the version of the earliest merged exchange.- Specified by:
initialVersionin interfaceGridDhtTopologyFuture- Returns:
- Initial exchange version.
-
topologyVersion
public AffinityTopologyVersion topologyVersion()
Gets result topology version of this future. Result version can differ from initial exchange version if exchanges for multiple discovery events are merged, in this case result version is version of last discovery event.This method should be called only for finished topology future since result version is not known before exchange finished.
- Specified by:
topologyVersionin interfaceGridDhtTopologyFuture- Returns:
- Result topology version.
-
exchangeType
@Nullable public @Nullable GridDhtPartitionsExchangeFuture.ExchangeType exchangeType()
- Returns:
- Exchange type or
nullif not determined yet.
-
partitionHistorySupplier
public List<UUID> partitionHistorySupplier(int grpId, int partId, long cntrSince)
Retreives the node which has WAL history sincecntrSince.- Parameters:
grpId- Cache group ID.partId- Partition ID.cntrSince- Partition update counter since history supplying is requested.- Returns:
- List of IDs of history supplier nodes or empty list if these doesn't exist.
-
markNodeAsInapplicableForHistoricalRebalance
public void markNodeAsInapplicableForHistoricalRebalance(UUID nodeId)
Marks the given node as not applicable for historical rebalancing.- Parameters:
nodeId- Node id that should not be used for wal rebalancing (aka historical supplier).
-
copyInapplicableNodesFrom
public void copyInapplicableNodesFrom(GridDhtPartitionsExchangeFuture fut)
Marks nodes as not applicable for full and historical rebalancing.- Parameters:
fut- Exchange future that is used for getting nodes that are not applicable for rebalancing.
-
markNodeAsInapplicableForFullRebalance
public void markNodeAsInapplicableForFullRebalance(UUID nodeId, int grpId, int p)
Marks the given node as not applicable for full rebalancing for the given group and partition.- Parameters:
nodeId- Node id that should not be used for full rebalancing.grpId- Cache group id.p- Partition id.
-
hasInapplicableNodesForHistoricalRebalance
public boolean hasInapplicableNodesForHistoricalRebalance()
- Returns:
trueif there are nodes which are inapplicable for historical rebalancing.
-
hasInapplicableNodesForFullRebalance
public boolean hasInapplicableNodesForFullRebalance()
- Returns:
trueif there are nodes which are inapplicable for full rebalancing.
-
hasInapplicableNodesForRebalance
public boolean hasInapplicableNodesForRebalance()
- Returns:
trueif there are nodes which are inapplicable for rebalancing.
-
isNodeApplicableForFullRebalance
public boolean isNodeApplicableForFullRebalance(UUID nodeId, int grpId, int p)
- Parameters:
nodeId- Node id to check.grpId- Cache group id.p- Partition id.- Returns:
trueif the node is applicable for full rebalancing.
-
cacheAddedOnExchange
public boolean cacheAddedOnExchange(int cacheId, UUID rcvdFrom)- Parameters:
cacheId- Cache ID.rcvdFrom- Node ID cache was received from.- Returns:
Trueif cache was added during this exchange.
-
cacheGroupAddedOnExchange
public boolean cacheGroupAddedOnExchange(int grpId, UUID rcvdFrom)- Parameters:
grpId- Cache group ID.rcvdFrom- Node ID cache group was received from.- Returns:
Trueif cache group was added during this exchange.
-
dynamicCacheGroupStarted
public boolean dynamicCacheGroupStarted(int grpId)
- Parameters:
grpId- Cache group ID.- Returns:
Trueif non-client cache group was added during this exchange.
-
currentPMEDuration
public long currentPMEDuration(boolean blocked)
- Parameters:
blocked-Trueif take into account only cache operations blocked PME.- Returns:
- Gets execution duration for current partition map exchange in milliseconds.
0If there is no running PME orblockedwas set totrueand current PME don't block cache operations.
-
onAdded
public boolean onAdded()
- Returns:
True
-
onEvent
public void onEvent(GridDhtPartitionExchangeId exchId, DiscoveryEvent discoEvt, DiscoCache discoCache)
Event callback.- Parameters:
exchId- Exchange ID.discoEvt- Discovery event.discoCache- Discovery data cache.
-
resetLostPartitionFor
public boolean resetLostPartitionFor(String cacheOrGroupName)
- Parameters:
cacheOrGroupName- Group or cache name for reset lost partitions.- Returns:
Trueif reset lost partition exchange.
-
finalizeCounters
public boolean finalizeCounters()
- Returns:
Trueif update counters finalization exchange.
-
activateCluster
public boolean activateCluster()
- Returns:
Trueif activate cluster exchange.
-
changedBaseline
public boolean changedBaseline()
-
changedAffinity
public boolean changedAffinity()
- Specified by:
changedAffinityin interfaceGridDhtTopologyFuture- Returns:
Trueif this exchange changed affinity.
-
hasCachesToStart
public boolean hasCachesToStart()
- Returns:
Trueif there are caches to start.
-
firstEvent
public DiscoveryEvent firstEvent()
- Returns:
- First event discovery event.
-
firstEventCache
public DiscoCache firstEventCache()
- Returns:
- Discovery cache for first event.
-
events
public ExchangeDiscoveryEvents events()
- Returns:
- Events processed in this exchange.
-
exchangeId
public GridDhtPartitionExchangeId exchangeId()
- Returns:
- Exchange ID.
-
timeBag
public TimeBag timeBag()
- Returns:
- Object to collect exchange timings.
-
init
public void init(boolean newCrd) throws IgniteInterruptedCheckedExceptionStarts activity.- Parameters:
newCrd-Trueif node become coordinator on this exchange.- Throws:
IgniteInterruptedCheckedException- If interrupted.
-
isBaselineNodeFailed
public boolean isBaselineNodeFailed()
- Returns:
Trueif event node is in baseline and failed andfalseotherwise.
-
localJoinExchange
public boolean localJoinExchange()
- Returns:
Trueif exchange for local node join.
-
serverNodeDiscoveryEvent
public boolean serverNodeDiscoveryEvent()
- Returns:
Trueif exchange triggered by server node join or fail.
-
exchangeDone
public boolean exchangeDone()
Ready affinity future (GridCachePartitionExchangeManager.affinityReadyFuture(AffinityTopologyVersion)is completed beforeGridFutureAdapter.onDone(Object, Throwable)is called onGridDhtPartitionsExchangeFuture, it is guaranteed that this method will returntrueif affinity ready future is finished.Also this method returns
falsefor merged exchange futures.- Specified by:
exchangeDonein interfaceGridDhtTopologyFuture- Returns:
Trueif exchange is finished and result topology version can be used.
-
finishMerged
public void finishMerged(AffinityTopologyVersion resVer, GridDhtPartitionsExchangeFuture exchFut)
Finish merged future to allow GridCachePartitionExchangeManager.ExchangeFutureSet cleanup.
-
isMerged
public boolean isMerged()
- Returns:
Trueif future was merged.
-
onDone
public boolean onDone(@Nullable @Nullable AffinityTopologyVersion res, @Nullable @Nullable Throwable err)Callback to notify that future is finished. Note that if non-nullexception is passed in the result value will be ignored.- Overrides:
onDonein classGridFutureAdapter<AffinityTopologyVersion>- Parameters:
res- Optional result.err- Optional error.- Returns:
Trueif result was set by this call.
-
validate
public void validate(CacheGroupContext grp)
- Parameters:
grp- Cache group.
-
cleanUp
public void cleanUp()
Cleans up resources to avoid excessive memory usage.
-
mergeJoinExchange
public boolean mergeJoinExchange(GridDhtPartitionsExchangeFuture fut)
Merges this exchange with given one. Invoked under synchronization onmuxof thefut. All futures being merged are merged under a single synchronized section.- Parameters:
fut- Current exchange to merge with.- Returns:
Trueif need wait for message from joined server node.
-
mergeJoinExchangeOnDone
@Nullable public @Nullable GridDhtPartitionsSingleMessage mergeJoinExchangeOnDone(GridDhtPartitionsExchangeFuture fut)
- Parameters:
fut- Current future.- Returns:
- Pending join request if any.
-
forceClientReconnect
public void forceClientReconnect(ClusterNode node, GridDhtPartitionsSingleMessage msg)
Method is called on coordinator in situation when initial ExchangeFuture created on client join event was preempted from exchange history because of IGNITE_EXCHANGE_HISTORY_SIZE property.- Parameters:
node- Client node that should try to reconnect to the cluster.msg- Single message received from the client which didn't find original ExchangeFuture.
-
onReceiveSingleMessage
public void onReceiveSingleMessage(ClusterNode node, GridDhtPartitionsSingleMessage msg)
Processing of received single message. Actual processing in future may be delayed if init method was not completed, seeinitDone()- Parameters:
node- Sender node.msg- Single partition info.
-
fastReplyOnSingleMessage
public boolean fastReplyOnSingleMessage(ClusterNode node, GridDhtPartitionsSingleMessage msg)
Tries to fast reply withGridDhtPartitionsFullMessageon received single message in case of exchange future has already completed.- Parameters:
node- Cluster node which sent single message.msg- Single message.- Returns:
trueif fast reply succeed.
-
waitAndReplyToNode
public void waitAndReplyToNode(UUID nodeId, GridDhtPartitionsSingleMessage msg)
- Parameters:
nodeId- Node ID.msg- Client's message.
-
onReceiveFullMessage
public void onReceiveFullMessage(ClusterNode node, GridDhtPartitionsFullMessage msg)
- Parameters:
node- Sender node.msg- Full partition info.
-
onReceivePartitionRequest
public void onReceivePartitionRequest(ClusterNode node, GridDhtPartitionsSingleRequest msg)
- Parameters:
node- Sender node.msg- Message with full partition info.
-
onDynamicCacheChangeFail
public void onDynamicCacheChangeFail(ClusterNode node, DynamicCacheChangeFailureMessage msg)
Cache change failure message callback, processed from the discovery thread.- Parameters:
node- Message sender node.msg- Failure message.
-
onAffinityChangeMessage
public void onAffinityChangeMessage(ClusterNode node, CacheAffinityChangeMessage msg)
Affinity change message callback, processed from the same thread asonNodeLeft(org.apache.ignite.cluster.ClusterNode).- Parameters:
node- Message sender node.msg- Message.
-
onNodeLeft
public void onNodeLeft(ClusterNode node)
Node left callback, processed from the same thread asonAffinityChangeMessage(org.apache.ignite.cluster.ClusterNode, org.apache.ignite.internal.processors.cache.CacheAffinityChangeMessage).- Parameters:
node- Left node.
-
reconnectOnError
public boolean reconnectOnError(Throwable e)
- Parameters:
e- Exception.- Returns:
Trueif local node should try reconnect in case of error.
-
rebalanced
public boolean rebalanced()
- Returns:
Trueif cluster fully rebalanced.
-
wasRebalanced
public boolean wasRebalanced()
- Returns:
Trueif cluster was fully rebalanced on previous topology.
-
markAffinityReassign
public void markAffinityReassign()
Marks this future as affinity reassign.
-
affinityReassign
public boolean affinityReassign()
- Returns:
- True if some owned partition was reassigned, false otherwise.
-
addOrMergeDelayedFullMessage
public boolean addOrMergeDelayedFullMessage(ClusterNode node, GridDhtPartitionsFullMessage fullMsg)
Add or merge updates received from coordinator while exchange in progress.- Parameters:
fullMsg- Full message with exchangeId = null.- Returns:
Trueif message should be ignored and processed after exchange is done.
-
compareTo
public int compareTo(GridDhtPartitionsExchangeFuture fut)
- Specified by:
compareToin interfaceComparable<GridDhtPartitionsExchangeFuture>
-
addDiagnosticRequest
public void addDiagnosticRequest(IgniteDiagnosticPrepareContext diagCtx)
- Specified by:
addDiagnosticRequestin interfaceIgniteDiagnosticAware- Parameters:
diagCtx- Context.
-
shortInfo
public String shortInfo()
- Returns:
- Short information string.
-
toString
public String toString()
- Overrides:
toStringin classGridFutureAdapter<AffinityTopologyVersion>
-
nextDumpTimeout
public static long nextDumpTimeout(int step, long timeout)- Parameters:
step- Exponent coefficient.timeout- Base timeout.- Returns:
- Time to wait before next debug dump.
-
isClearingPartition
public boolean isClearingPartition(CacheGroupContext grp, int part)
- Parameters:
grp- Group.part- Partition.- Returns:
Trueif partition has to be cleared before rebalance.
-
addClearingPartition
public void addClearingPartition(CacheGroupContext grp, int part)
Marks a partition for clearing before rebalance. Fully cleared partitions should never be historically rebalanced.- Parameters:
grp- Group.part- Partition.
-
-