* which is equal to the local address, garbage collect all messages <= seqno at digest[P]. Update received_msgs:
* for each sender P in the digest and its highest seqno seen SEQ, garbage collect all delivered_msgs in the
* NakReceiverWindow corresponding to P which are <= seqno at digest[P].
*/
private void stable(Digest d) {
NakReceiverWindow recv_win;
long my_highest_rcvd; // highest seqno received in my digest for a sender P
long stability_highest_rcvd; // highest seqno received in the stability vector for a sender P
if(members == null || local_addr == null || d == null) {
if(warn)
log.warn("members, local_addr or digest are null !");
return;
}
if(trace) {
log.trace("received stable digest " + d);
}
Map.Entry entry;
Address sender;
org.jgroups.protocols.pbcast.Digest.Entry val;
long high_seqno_delivered, high_seqno_received;
for(Iterator it=d.senders.entrySet().iterator(); it.hasNext();) {
entry=(Map.Entry)it.next();
sender=(Address)entry.getKey();
if(sender == null)
continue;
val=(org.jgroups.protocols.pbcast.Digest.Entry)entry.getValue();
high_seqno_delivered=val.high_seqno;
high_seqno_received=val.high_seqno_seen;
// check whether the last seqno received for a sender P in the stability vector is > last seqno
// received for P in my digest. if yes, request retransmission (see "Last Message Dropped" topic
// in DESIGN)
synchronized(received_msgs) {
recv_win=(NakReceiverWindow)received_msgs.get(sender);
}
if(recv_win != null) {
my_highest_rcvd=recv_win.getHighestReceived();
stability_highest_rcvd=high_seqno_received;
if(stability_highest_rcvd >= 0 && stability_highest_rcvd > my_highest_rcvd) {
if(trace) {
log.trace("my_highest_rcvd (" + my_highest_rcvd + ") < stability_highest_rcvd (" +
stability_highest_rcvd + "): requesting retransmission of " +
sender + '#' + stability_highest_rcvd);
}
retransmit(stability_highest_rcvd, stability_highest_rcvd, sender);
}
}
high_seqno_delivered-=gc_lag;
if(high_seqno_delivered < 0) {
continue;
}
if(trace)
log.trace("deleting msgs <= " + high_seqno_delivered + " from " + sender);
// garbage collect from sent_msgs if sender was myself
if(sender.equals(local_addr)) {
synchronized(sent_msgs) {
// gets us a subset from [lowest seqno - seqno]
SortedMap stable_keys=sent_msgs.headMap(new Long(high_seqno_delivered));
if(stable_keys != null) {
stable_keys.clear(); // this will modify sent_msgs directly
}
}
}
// delete *delivered* msgs that are stable
// recv_win=(NakReceiverWindow)received_msgs.get(sender);
if(recv_win != null)
recv_win.stable(high_seqno_delivered); // delete all messages with seqnos <= seqno
}
}