public static void record_IOclose( long start_ns, long start_io_ms, int r_w, long size, int flavor ) { long block_ns = System.nanoTime() - start_ns; long io_ms = System.currentTimeMillis() - start_io_ms; // First long word going out has sender-port and a 'bad' control packet long b0 = UDP.udp.i_o.ordinal(); // Special flag to indicate io-record and not a rpc-record b0 |= H2O.SELF._key.udp_port()<<8; b0 |= flavor<<24; // I/O flavor; one of the Value.persist backends b0 |= io_ms<<32; // msec from start-to-finish, including non-i/o overheads record2(H2O.SELF,block_ns,true,r_w,0,b0,size); }
private static void record2( H2ONode h2o, long ns, boolean tcp, int sr, int drop, long b0, long b8 ) { final long ms = System.currentTimeMillis(); // Read first, in case we're slow storing values long deltams = ms-JVM_BOOT_MSEC; assert deltams < 0x0FFFFFFFFL; // No daily overflow final long[] tl = TIMELINE; // Read once, in case the whole array shifts out from under us final int idx = next_idx(tl); // Next free index tl[idx*WORDS_PER_EVENT+0+1] = (deltams)<<32 | (h2o.ip4()&0x0FFFFFFFFL); tl[idx*WORDS_PER_EVENT+1+1] = (ns&~7)| (tcp?4:0)|sr|drop; // More complexities: record the *receiver* port in the timeline - but not // in the outgoing UDP packet! The outgoing packet always has the sender's // port (that's us!) - which means the recorded timeline packet normally // never carries the *receiver* port - meaning the sender's timeline does // not record who he sent to! With this hack the Timeline record always // contains the info about "the other guy": inet+port for the receiver in // the sender's Timeline, and vice-versa for the receiver's Timeline. if( sr==0 ) b0 = (b0 & ~0xFFFF00) | (h2o._key.udp_port()<<8); tl[idx*WORDS_PER_EVENT+2+1] = b0; tl[idx*WORDS_PER_EVENT+3+1] = b8; }
AutoBuffer write( AutoBuffer ab ) { return ab.put4(_ipv4).put2((char)udp_port()); } static H2Okey read( AutoBuffer ab ) {
public static void record_IOclose( AutoBuffer b, int flavor ) { H2ONode h2o = b._h2o==null ? H2O.SELF : b._h2o; // First long word going out has sender-port and a 'bad' control packet long b0 = UDP.udp.i_o.ordinal(); // Special flag to indicate io-record and not a rpc-record b0 |= H2O.SELF._key.udp_port()<<8; b0 |= flavor<<24; // I/O flavor; one of the Value.persist backends long iotime = b._time_start_ms > 0 ? (b._time_close_ms - b._time_start_ms) : 0; b0 |= iotime<<32; // msec from start-to-finish, including non-i/o overheads long b8 = b._size; // byte's transfered in this I/O long ns = b._time_io_ns; // nano's blocked doing I/O record2(h2o,ns,true,b.readMode()?1:0,0,b0,b8); }
@Override public int compareTo( Object x ) { if( x == null ) return -1; // Always before null if( x == this ) return 0; H2Okey key = (H2Okey)x; // Must be unsigned long-math, or overflow will make a broken sort long res = (_ipv4&0xFFFFFFFFL) - (key._ipv4&0xFFFFFFFFL); if( res != 0 ) return res < 0 ? -1 : 1; return udp_port() - key.udp_port(); } }