/** * Offer this key to all the nodes that have requested it, and all the nodes it has been requested * from. Called after a) the data has been stored, and b) this entry has been removed from the FT */ public void offer() { HashSet<PeerNodeUnlocked> set = new HashSet<PeerNodeUnlocked>(); final boolean logMINOR = FailureTableEntry.logMINOR; if (logMINOR) Logger.minor( this, "Sending offers to nodes which requested the key from us: (" + requestorNodes.length + ") for " + key); synchronized (this) { for (int i = 0; i < requestorNodes.length; i++) { WeakReference<? extends PeerNodeUnlocked> ref = requestorNodes[i]; if (ref == null) continue; PeerNodeUnlocked pn = ref.get(); if (pn == null) continue; if (pn.getBootID() != requestorBootIDs[i]) continue; if (!set.add(pn)) { Logger.error(this, "Node is in requestorNodes twice: " + pn); } } if (logMINOR) Logger.minor( this, "Sending offers to nodes which we sent the key to: (" + requestedNodes.length + ") for " + key); for (int i = 0; i < requestedNodes.length; i++) { WeakReference<? extends PeerNodeUnlocked> ref = requestedNodes[i]; if (ref == null) continue; PeerNodeUnlocked pn = ref.get(); if (pn == null) continue; if (pn.getBootID() != requestedBootIDs[i]) continue; if (!set.add(pn)) continue; } } // Do the offers outside the lock. // We do not need to hold it, offer() doesn't do anything that affects us. for (PeerNodeUnlocked pn : set) { if (logMINOR) Logger.minor(this, "Offering to " + pn); pn.offer(key); } }