StringBuffer sb=new StringBuffer("added missing msg "); sb.append(msg.getSrc()).append('#').append(seqno); log.trace(sb.toString());
log.trace(new StringBuffer("added missing msg ").append(msg.getSrc()).append('#').append(seqno));
    public void add(long seqno, Message msg) {        long old_tail;        try {            lock.writeLock().acquire();            try {                old_tail=tail;                if(seqno < head) {                    if(log.isTraceEnabled()) {                        StringBuffer sb=new StringBuffer("seqno ");                        sb.append(seqno).append(" is smaller than ").append(head).append("); discarding message");                        log.trace(sb.toString());                    }                    return;                }                // add at end (regular expected msg)                if(seqno == tail) {                    received_msgs.put(new Long(seqno), msg);                    tail++;                    highest_seen=seqno;                }                // gap detected                // i. add placeholders, creating gaps                // ii. add real msg                // iii. tell retransmitter to retrieve missing msgs                else if(seqno > tail) {                    for(long i=tail; i < seqno; i++) {                        received_msgs.put(new Long(i), null);                        // XmitEntry xmit_entry=new XmitEntry();                        //xmits.put(new Long(i), xmit_entry);                        tail++;                    }                    received_msgs.put(new Long(seqno), msg);                    tail=seqno + 1;                    if(retransmitter != null) {                        retransmitter.add(old_tail, seqno - 1);                    }                }                else if(seqno < tail) { // finally received missing message                    if(log.isTraceEnabled()) {                        StringBuffer sb=new StringBuffer("added missing msg ");                        sb.append(msg.getSrc()).append('#').append(seqno);                        log.trace(sb.toString());                    }                    if(listener != null) {                        try {listener.missingMessageReceived(seqno, msg);} catch(Throwable t) {}                    }                    Object val=received_msgs.get(new Long(seqno));                    if(val == null) {                        // only set message if not yet received (bela July 23 2003)                        received_msgs.put(new Long(seqno), msg);                        if(highest_seen +1 == seqno || seqno == head)                            updateHighestSeen();                        //XmitEntry xmit_entry=(XmitEntry)xmits.get(new Long(seqno));                        //if(xmit_entry != null)                        //  xmit_entry.received=System.currentTimeMillis();                        //long xmit_diff=xmit_entry == null? -1 : xmit_entry.received - xmit_entry.created;                        //NAKACK.addXmitResponse(msg.getSrc(), seqno);                        if(retransmitter != null) retransmitter.remove(seqno);                    }                }                updateLowestSeen();            }            finally {                lock.writeLock().release();            }        }        catch(InterruptedException e) {            log.error("failed acquiring write lock", e);        }    }