/** * Returns <code>true</code> if the bucket needs to, AND can be split * so a given <code>Destination</code> can be added. */ boolean shouldSplit(Destination destination) { return isFull() && !contains(destination) && canSplit(destination); }
/** * Adds a peer to the tail of the bucket if it is locked, or to the * head of the bucket if it isn't locked. * The bucket cannot be full when calling this method. * @param peer */ private void add(KademliaPeer peer) { if (isFull()) log.error("Error: adding a node to a full k-bucket. Bucket needs to be split first. Size=" + size() + ", capacity=" + capacity); if (peer.isLocked()) peers.add(peer); else peers.add(0, peer); }
/** * Updates a known peer, or adds the peer if it isn't known. If the bucket * is full and the replacement cache is not empty, the oldest peer is removed * before adding the new peer. * If the bucket is full and the replacement cache is empty, the peer is * added to the replacement cache. * @param peer */ void addOrUpdate(KademliaPeer peer) { // TODO log an error if peer outside bucket's range int index = getPeerIndex(peer); if (index >= 0) { KademliaPeer existingPeer = peers.remove(index); existingPeer.responseReceived(); add(existingPeer); } else { if (!isFull()) add(peer); else addOrUpdateReplacement(peer); } }
@Test public void testIsFull() { for (KBucket bucket: buckets) { Destination[] destinations = destinationMap.get(bucket); for (int i=0; i<K-1; i++) { bucket.addOrUpdate(new KademliaPeer(destinations[i])); assertFalse(bucket.isFull()); } bucket.addOrUpdate(new KademliaPeer(destinations[K-1])); assertTrue(bucket.isFull()); } }