src/java/org/apache/cassandra/service/StorageService.java
/**
     * Seed data to the endpoints that will be responsible for it at the future
     *
     * @param rangesToStreamByTable tables and data ranges with endpoints included for each
     * @return latch to count down
     */
Seed data to the endpoints that will be responsible for it at the future
@param rangesToStreamByTable tables and data ranges with endpoints included for each
@return latch to count down
Seed data to the endpoints that will be responsible for it at the future @param rangesToStreamByTable tables and data ranges with endpoints included for each @return latch to count down
private CountDownLatch streamRanges(final Map<String, Multimap<Range<Token>, InetAddress>> rangesToStreamByTable)
    {
        final CountDownLatch latch = new CountDownLatch(rangesToStreamByTable.keySet().size());
        for (final String table : rangesToStreamByTable.keySet())
        {
            Multimap<Range<Token>, InetAddress> rangesWithEndpoints = rangesToStreamByTable.get(table);
            if (rangesWithEndpoints.isEmpty())
            {
                latch.countDown();
                continue;
            }
            final Set<Map.Entry<Range<Token>, InetAddress>> pending = new HashSet<Map.Entry<Range<Token>, InetAddress>>(rangesWithEndpoints.entries());
            for (final Map.Entry<Range<Token>, InetAddress> entry : rangesWithEndpoints.entries())
            {
                final Range<Token> range = entry.getKey();
                final InetAddress newEndpoint = entry.getValue();
                final Runnable callback = new Runnable()
                {
                    @Override
                    public void run()
                    {
                        synchronized (pending)
                        {
                            pending.remove(entry);
                            if (pending.isEmpty())
                                latch.countDown();
                        }
                    }
                };
                StageManager.getStage(Stage.STREAM).execute(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        StreamOut.transferRanges(newEndpoint, Table.open(table), Arrays.asList(range), callback, OperationType.UNBOOTSTRAP);
                    }
                });
            }
        }
        return latch;
    }
private CountDownLatch streamRanges ( final Map < String , Multimap < Range < Token > , InetAddress > > rangesToStreamByTable ) { final CountDownLatch latch = new CountDownLatch ( rangesToStreamByTable . keySet ( ) . size ( ) ) ; for ( final String table : rangesToStreamByTable . keySet ( ) ) { Multimap < Range < Token > , InetAddress > rangesWithEndpoints = rangesToStreamByTable . get ( table ) ; if ( rangesWithEndpoints . isEmpty ( ) ) { latch . countDown ( ) ; continue ; } final Set < Map . Entry < Range < Token > , InetAddress > > pending = new HashSet < Map . Entry < Range < Token > , InetAddress > > ( rangesWithEndpoints . entries ( ) ) ; for ( final Map . Entry < Range < Token > , InetAddress > entry : rangesWithEndpoints . entries ( ) ) { final Range < Token > range = entry . getKey ( ) ; final InetAddress newEndpoint = entry . getValue ( ) ; final Runnable callback = new Runnable ( ) { @ Override public void run ( ) { synchronized ( pending ) { pending . remove ( entry ) ; if ( pending . isEmpty ( ) ) latch . countDown ( ) ; } } } ; StageManager . getStage ( Stage . STREAM ) . execute ( new Runnable ( ) { @ Override public void run ( ) { StreamOut . transferRanges ( newEndpoint , Table . open ( table ) , Arrays . asList ( range ) , callback , OperationType . UNBOOTSTRAP ) ; } } ) ; } } return latch ; }
Seed data to the endpoints that will be responsible for it at the future
 @param rangesToStreamByTable tables and data ranges with endpoints included for each
 @return latch to count down
Seed data to the endpoints that will be responsible for it at the future @param rangesToStreamByTable tables and data ranges with endpoints included for each @return latch to count down
// TODO each call to transferRanges re-flushes, this is potentially a lot of waste