private int sendChunks ( ByteBuffer pkt , int maxChunks , OutputStream out ) throws IOException { // Sends multiple chunks in one packet with a single write(). int len = ( int ) Math . min ( endOffset - offset , ( ( ( long ) bytesPerChecksum ) * ( ( long ) maxChunks ) ) ) ; // truncate len so that any partial chunks will be sent as a final packet. // this is not necessary for correctness, but partial chunks are // ones that may be recomputed and sent via buffer copy, so try to minimize // those bytes if ( len > bytesPerChecksum && len % bytesPerChecksum != 0 ) { len -= len % bytesPerChecksum ; } if ( len == 0 ) { return 0 ; } int numChunks = ( len + bytesPerChecksum - 1 ) / bytesPerChecksum ; int packetLen = len + numChunks * checksumSize + 4 ; pkt . clear ( ) ; // The packet format is documented in DFSOuputStream.Packet.getBuffer(). // Here we need to use the exact packet format since it can be received // by both of DFSClient, or BlockReceiver in the case of replication, which // uses the same piece of codes as receiving data from DFSOutputStream. // // write packet header pkt . putInt ( packetLen ) ; if ( pktIncludeVersion ) { pkt . putInt ( packetVersion ) ; } pkt . putLong ( offset ) ; pkt . putLong ( seqno ) ; pkt . put ( ( byte ) ( ( offset + len >= endOffset ) ? 1 : 0 ) ) ; //why no ByteBuf.putBoolean()? pkt . putInt ( len ) ; int checksumOff = pkt . position ( ) ; byte [ ] buf = pkt . array ( ) ; blockReader . sendChunks ( out , buf , offset , checksumOff , numChunks , len , crcUpdater , packetVersion ) ; if ( throttler != null ) { // rebalancing so throttle throttler . throttle ( packetLen ) ; } return len ; }
Sends upto maxChunks chunks of data .