question: private void prepare0 ( ) { if ( log . isDebugEnabled ( ) ) log . debug ( "Preparing eviction future [futId=" + id + ", localNode=" + cctx . nodeId ( ) + ", infos=" + evictInfos + ']' ) ; assert evictInfos != null && ! evictInfos . isEmpty ( ) ; topVer = lockTopology ( ) ; try { Collection < EvictionInfo > locals = null ; for ( EvictionInfo info : evictInfos ) { Node < EvictionInfo > queueNode = info . entry ( ) . removeMeta ( META_KEY ) ; if ( queueNode != null ) bufEvictQ . unlinkx ( queueNode ) ; IgniteBiTuple < Collection < ClusterNode > , Collection < ClusterNode > > tup ; try { tup = remoteNodes ( info . entry ( ) , topVer ) ; } catch ( GridCacheEntryRemovedException ignored ) { if ( log . isDebugEnabled ( ) ) log . debug ( "Entry got removed while preparing eviction future (ignoring) [entry=" + info . entry ( ) + ", nodeId=" + cctx . nodeId ( ) + ']' ) ; continue ; } Collection < ClusterNode > entryReaders = F . addIfAbsent ( readers , info . entry ( ) . key ( ) , new GridConcurrentHashSet < ClusterNode > ( ) ) ; assert entryReaders != null ; entryReaders . addAll ( tup . get2 ( ) ) ; Collection < ClusterNode > nodes = F . concat ( true , tup . get1 ( ) , tup . get2 ( ) ) ; if ( ! nodes . isEmpty ( ) ) { entries . put ( info . entry ( ) . key ( ) , info ) ; for ( ClusterNode node : nodes ) { GridCacheEvictionRequest req = F . addIfAbsent ( reqMap , node . id ( ) , new GridCacheEvictionRequest ( cctx . cacheId ( ) , id , evictInfos . size ( ) , topVer , cctx . deploymentEnabled ( ) ) ) ; assert req != null ; req . addKey ( info . entry ( ) . key ( ) , info . version ( ) , entryReaders . contains ( node ) ) ; } } else { if ( locals == null ) locals = new HashSet < > ( evictInfos . size ( ) , 1.0f ) ; locals . add ( info ) ; } } if ( locals != null ) { GridCacheVersion obsoleteVer = cctx . versions ( ) . next ( ) ; for ( EvictionInfo info : locals ) { if ( log . isDebugEnabled ( ) ) log . debug ( "Evicting key without remote participant nodes: " + info ) ; try { if ( ! evict0 ( cctx . cache ( ) , info . entry ( ) , obsoleteVer , versionFilter ( info ) , false ) && plcEnabled ) touch0 ( info . entry ( ) ) ; } catch ( IgniteCheckedException e ) { U . error ( log , "Failed to evict entry: " + info . entry ( ) , e ) ; } } } if ( entries . isEmpty ( ) ) { complete ( false ) ; return ; } } finally { unlockTopology ( ) ; } for ( Map . Entry < UUID , GridCacheEvictionRequest > e : reqMap . entrySet ( ) ) { UUID nodeId = e . getKey ( ) ; GridCacheEvictionRequest req = e . getValue ( ) ; if ( log . isDebugEnabled ( ) ) log . debug ( "Sending eviction request [node=" + nodeId + ", req=" + req + ']' ) ; try { cctx . io ( ) . send ( nodeId , req , cctx . ioPolicy ( ) ) ; } catch ( ClusterTopologyCheckedException ignored ) { onNodeLeft ( nodeId ) ; } catch ( IgniteCheckedException ex ) { U . error ( log , "Failed to send eviction request to node [node=" + nodeId + ", req=" + req + ']' , ex ) ; rejectEntries ( nodeId ) ; } } registerTimeoutObject ( ) ; }
target:  Prepares future (sends all required requests).