public Entry next() { if(index >= capacity()) throw new NoSuchElementException("index=" + index + ", capacity=" + capacity()); Address mbr=members != null? members[index] : null; long hd=seqnos != null? seqnos[index*2] : 0, hr=seqnos != null? seqnos[index*2+1] : 0; Entry entry=new Entry(mbr, hd, hr); index++; return entry; }
Address member=entry.getMember(); long[] my_entry=my_digest.get(member); if(my_entry == null) continue; long their_high=entry.getHighest();
Address member=entry.getMember(); if(member == null) continue; long highest_delivered_seqno=entry.getHighestDeliveredSeqno();
if(digest != null) for(Digest.Entry entry: digest) digest_membership.add(entry.getMember());
Address member=entry.getMember(); long[] my_entry=my_digest.get(member); if(my_entry == null) continue; long their_high=entry.getHighest();
continue; val=entry.getValue(); high_seqno_delivered=val.getHighestDeliveredSeqno(); high_seqno_received=val.getHighestReceivedSeqno();
if(my_entry == null) continue; their_high=their_entry.getHighest(); my_high=my_entry.getHighest(); if(their_high > my_high) { if(log.isTraceEnabled())
highest_delivered=win.getHighestDelivered(), highest_received=win.getHighestReceived(); return new Digest.Entry(low, highest_delivered, highest_received);
mbr=entry.getKey(); val=entry.getValue(); low=val.getLow(); highest_seqno=val.getHighestDeliveredSeqno(); // highest *delivered* seqno highest_seen_seqno=val.getHighestReceivedSeqno(); // highest *received* seqno
Address member=entry.getMember(); if(member == null) continue; long highest_delivered_seqno=entry.getHighestDeliveredSeqno();
Entry e1=this.get(address); Entry e2=other.get(address); if(e1.getHighestDeliveredSeqno() != e2.getHighestDeliveredSeqno()) { long low=Math.min(e1.highest_delivered_seqno, e2.highest_delivered_seqno); long high=max(e1.highest_delivered_seqno, e2.highest_delivered_seqno); Entry r=new Entry(low, high); resultMap.put(address, r); thisMinusInteresection.removeAll(intersection); for(Address address : thisMinusInteresection) { resultMap.put(address, new Entry(this.get(address))); otherMinusInteresection.removeAll(intersection); for(Address address : otherMinusInteresection) { resultMap.put(address, new Entry(other.get(address)));
Entry r=new Entry(0, high); resultMap.put(address, r); thisMinusInteresection.removeAll(intersection); for(Address address : thisMinusInteresection) { resultMap.put(address, new Entry(this.get(address))); otherMinusInteresection.removeAll(intersection); for(Address address : otherMinusInteresection) { resultMap.put(address, new Entry(other.get(address)));
highest_delivered_seqno=val.getHighestDeliveredSeqno(); low_seqno=val.getLow();
Address member=entry.getMember(); if(member == null) continue; long hd=entry.getHighestDeliveredSeqno(); long hr=entry.getHighestReceivedSeqno();
Address member=entry.getMember(); if(member == null) continue; long highest_delivered_seqno=entry.getHighestDeliveredSeqno();
initial_seqno=val.getHighestDeliveredSeqno(); win=createNakReceiverWindow(sender, initial_seqno, val.getLow()); xmit_table.put(sender, win);
/** * Returns true if all senders of the current digest have their seqnos >= the ones from other * @param other * @return */ public boolean isGreaterThanOrEqual(Digest other) { if(other == null) return true; Map<Address,Entry> our_map=getSenders(); Address sender; Entry my_entry, their_entry; long my_highest, their_highest; for(Map.Entry<Address,Entry> entry: our_map.entrySet()) { sender=entry.getKey(); my_entry=entry.getValue(); their_entry=other.get(sender); if(their_entry == null) continue; my_highest=my_entry.getHighest(); their_highest=their_entry.getHighest(); if(my_highest < their_highest) return false; } return true; }
/** Update my own digest from a digest received by somebody else. Returns whether the update was successful. * Needs to be called with a lock on digest */ @GuardedBy("lock") protected void updateLocalDigest(Digest d, Address sender) { StringBuilder sb=null; if(log.isTraceEnabled()) sb=new StringBuilder().append(local_addr).append(": handling digest from ").append(sender).append(":\nmine: ") .append(printDigest(digest)).append("\nother: ").append(printDigest(d)); for(Digest.Entry entry: d) { Address mbr=entry.getMember(); long hd=entry.getHighestDeliveredSeqno(), hr=entry.getHighestReceivedSeqno(); // compute the minimum of the highest seqnos deliverable (for garbage collection) long[] seqnos=digest.get(mbr); if(seqnos == null) continue; long my_hd=seqnos[0]; long my_hr=seqnos[1]; // (for retransmission of last missing message) if(my_hd == -1) // -1 means the seqno hasn't been set yet my_hd=hd; long new_hd=Math.min(my_hd, hd); long new_hr=Math.max(my_hr, hr); digest.set(mbr, new_hd, new_hr); } if(sb != null) // implies log.isTraceEnabled() == true log.trace(sb.append("\nresult: ").append(printDigest(digest)).append("\n")); }
/** * Similar to add(), but if the sender already exists, its seqnos will be modified (no new entry) as follows: * <ol> * <li>this.low_seqno=min(this.low_seqno, low_seqno) * <li>this.highest_delivered_seqno=max(this.highest_delivered_seqno, highest_delivered_seqno) * <li>this.highest_received_seqno=max(this.highest_received_seqno, highest_received_seqno) * </ol> * If the sender doesn not exist, a new entry will be added (provided there is enough space) */ public void merge(Address sender, long low_seqno, long highest_delivered_seqno, long highest_received_seqno) { if(sender == null) { if(log.isErrorEnabled()) log.error("sender == null"); return; } checkSealed(); Entry entry=senders.get(sender); if(entry == null) { add(sender, low_seqno, highest_delivered_seqno, highest_received_seqno); } else { Entry new_entry=new Entry(Math.min(entry.getLow(), low_seqno), Math.max(entry.getHighestDeliveredSeqno(), highest_delivered_seqno), Math.max(entry.getHighestReceivedSeqno(), highest_received_seqno)); senders.put(sender, new_entry); } }
/** * Adds a digest to this digest. This digest must have enough space to add the other digest; otherwise an error * message will be written. For each sender in the other digest, the merge() method will be called. */ public void merge(Digest digest) { if(digest == null) { if(log.isErrorEnabled()) log.error("digest to be merged with is null"); return; } checkSealed(); Map.Entry<Address,Entry> entry; Address sender; Entry val; for(Iterator<Map.Entry<Address,Entry>> it=digest.senders.entrySet().iterator(); it.hasNext();) { entry=it.next(); sender=entry.getKey(); val=entry.getValue(); if(val != null) { merge(sender, val.getLow(), val.getHighestDeliveredSeqno(), val.getHighestReceivedSeqno()); } } }