public DatanodeInfo [ ] bestNode ( LocatedBlocks blks ) throws IOException { // insert all known replica locations into a tree map where the // key is the DatanodeInfo TreeMap < DatanodeInfo , NodeRecord > map = new TreeMap < DatanodeInfo , NodeRecord > ( ) ; for ( int i = 0 ; i < blks . getLocatedBlocks ( ) . size ( ) ; i ++ ) { DatanodeInfo [ ] nodes = blks . get ( i ) . getLocations ( ) ; for ( int j = 0 ; j < nodes . length ; j ++ ) { NodeRecord obj = map . get ( nodes [ j ] ) ; if ( obj != null ) { obj . frequency ++ ; } else { map . put ( nodes [ j ] , new NodeRecord ( nodes [ j ] , 1 ) ) ; } } } // sort all locations by their frequency of occurance Collection < NodeRecord > values = map . values ( ) ; NodeRecord [ ] nodes = ( NodeRecord [ ] ) values . toArray ( new NodeRecord [ values . size ( ) ] ) ; Arrays . sort ( nodes , new NodeRecordComparator ( ) ) ; try { List < NodeRecord > candidates = bestNode ( nodes , false ) ; return candidates . toArray ( new DatanodeInfo [ candidates . size ( ) ] ) ; } catch ( IOException e ) { return new DatanodeInfo [ ] { randomNode ( ) } ; } }
Get an array of nodes that can serve the streaming request The best one is the first in the array which has maximum local copies of all blocks