/* * Copyright 2013 Thomas Bocek * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package net.tomp2p.peers; import java.util.ArrayList; import java.util.Collection; import net.tomp2p.p2p.DefaultPeerStatisticComparator; import net.tomp2p.p2p.PeerStatisticComparator; /** * The class that holds configuration settings for the {@link PeerMap}. * * @author Thomas Bocek */ public class PeerMapConfiguration { private final Number160 self; private int[] bagSizesVerified = new int[Number160.BITS]; private int[] bagSizesOverflow = new int[Number160.BITS]; private int offlineTimeout; private int shutdownTimeout; private int exceptionTimeout; private int offlineCount; //we'll add 1-2 filters private Collection<PeerMapFilter> peerMapFilters = new ArrayList<PeerMapFilter>(2); private Maintenance maintenance; private boolean peerVerification; private PeerStatisticComparator peerStatisticComparator; /** * Constructor with reasonable defaults. * * @param self * The peer ID of this peer */ public PeerMapConfiguration(final Number160 self) { this.self = self; setDoublingVerifiedBagSizes(); setDoublingOverflowBagSizes(); offlineTimeout = 60; shutdownTimeout = 20; exceptionTimeout = 120; offlineCount = 3; maintenance = new DefaultMaintenance(4, new int[] { 2, 4, 8, 16, 32, 64 }); peerVerification = true; setPeerStatisticComparator(new DefaultPeerStatisticComparator()); } /** * @return The peer ID of this peer */ public Number160 self() { return self; } /** * Each distance bit has its own bag. * This is the size of the verified peers that are known to be online. * @return */ public int getVerifiedBagSize(final int bag) { return bagSizesVerified[bag]; } /** * Each distance bit has its own bag this is the size of the verified peers are know to be online * @return this class */ public int[] getVerifiedBagSizes() { return bagSizesVerified; } /** * Sets the bag size for the verified peers to a fixed number * * @param fixedVerifiedBagSize The size for each bag to be set * @return This PeerMapConfiguration object */ public PeerMapConfiguration setFixedVerifiedBagSizes(final int fixedVerifiedBagSize) { for (int i=0; i<this.bagSizesVerified.length; i++) { this.bagSizesVerified[i] = fixedVerifiedBagSize; } return this; } /** * Sets the bag sizes for the verified peers to (8, 8, 8, ... 8, 16, 32, 64, 128) * @return This PeerMapConfiguration object */ public PeerMapConfiguration setDoublingVerifiedBagSizes() { for (int i = 0; i < Number160.BITS; i++) { if (i < Number160.BITS - 4) { bagSizesVerified[i] = 8; }else { bagSizesVerified[i] = 128 / (int)Math.pow(2,Number160.BITS - i - 1); } } return this; } /** * Allows to define custom bag sizes for the verified peers * @param bagSizesVerified Array of length Number160.BITS, specifying the size * for each bag. bagSizesVerified[0] is the closest bag, * bagSizesVerified[159] is the most distant bag. * @return This PeerMapConfiguration object */ public PeerMapConfiguration setBagSizesVerified(final int[] bagSizesVerified) { if (bagSizesVerified.length != Number160.BITS) throw new IllegalArgumentException("The array of bag sizes must have length of " + Number160.BITS); this.bagSizesVerified = bagSizesVerified; return this; } /** * @param bag The bit distance with 0 being the closest, 159 being the most distant * @return The size of the bag of the given bit distance. */ public int getOverflowBagSize(final int bag) { return bagSizesOverflow[bag]; } /** * @return The array of sizes for the overflow peer bags */ public int[] getOverflowBagSizes() { return bagSizesOverflow; } /** * Sets the bag size for the overflow peers to a fixed number * * @param fixedOverflowBagSize The size for each bag to be set * @return This PeerMapConfiguration object */ public PeerMapConfiguration setFixedOverflowBagSizes(final int fixedOverflowBagSize) { for (int i=0; i<this.bagSizesOverflow.length; i++) { this.bagSizesOverflow[i] = fixedOverflowBagSize; } return this; } /** * Sets the bag sizes for the overflow peers to (8, 8, 8, ... 8, 16, 32, 64, 128) * @return This PeerMapConfiguration object */ public PeerMapConfiguration setDoublingOverflowBagSizes() { for (int i = 0; i < Number160.BITS; i++) { if (i < Number160.BITS - 4) { bagSizesOverflow[i] = 8; }else { bagSizesOverflow[i] = 128 / (int)Math.pow(2,Number160.BITS - i - 1); } } return this; } /** * Allows to define custom bag sizes for the overflow peers * @param bagSizesOverflow Array of length Number160.BITS, specifying the size * for each bag. bagSizesOverflow[0] is the closest bag, * bagSizesOverflow[159] is the most distant bag. * @return This PeerMapConfiguration object */ public PeerMapConfiguration setBagSizesOverflow(final int[] bagSizesOverflow) { if (bagSizesOverflow.length != Number160.BITS) throw new IllegalArgumentException("The array of bag sizes must have length of " + Number160.BITS); this.bagSizesOverflow = bagSizesOverflow; return this; } /** * @return The time a peer is considered offline in seconds. This is important, since we see that a peer is offline * and an other peer reports this peer, we don't want to add it into our map. Thus, there is a map that * keeps track of such peers. This also means that a fast reconnect is not possible and a peer has to wait * until the timeout to rejoin */ public int offlineTimeout() { return offlineTimeout; } /** * @param offlineTimeout * The time a peer is considered offline in seconds. This is important, since we see that a peer is * offline and an other peer reports this peer, we don't want to add it into our map. Thus, there is a * map that keeps track of such peers. This also means that a fast reconnect is not possible and a peer * has to wait until the timeout to rejoin * @return this class */ public PeerMapConfiguration offlineTimeout(final int offlineTimeout) { this.offlineTimeout = offlineTimeout; return this; } /** * @return The number of times that the peer is not reachable. After that, the peer is considered offline */ public int offlineCount() { return offlineCount; } /** * @param offlineCount * The number of times that the peer is not reachabel. After that the peer is considered offline * @return this class */ public PeerMapConfiguration offlineCount(final int offlineCount) { this.offlineCount = offlineCount; return this; } /** * @return These filters can be set to not accept certain peers */ public Collection<PeerMapFilter> peerMapFilters() { return peerMapFilters; } /** * @param peerMapFilter * This filter can be set to not accept certain peers * @return this class */ public PeerMapConfiguration addMapPeerFilter(final PeerMapFilter peerMapFilter) { peerMapFilters.add(peerMapFilter); return this; } /** * @return The instance that is responsible for maintenance */ public Maintenance maintenance() { return maintenance; } /** * @param maintenance * The class that is responsible for maintenance * @return this class */ public PeerMapConfiguration maintenance(final Maintenance maintenance) { this.maintenance = maintenance; return this; } /** * @return The time a peer is considered offline (shutdown) in seconds. This is important, since we see that a peer is * offline and an other peer reports this peer, we don't want to add it into our map. Thus, there is a * map that keeps track of such peers. This also means that a fast reconnect is not possible and a peer * has to wait until the timeout to rejoin */ public int shutdownTimeout() { return shutdownTimeout; } /** * @param shutdownTimeout * The time a peer is considered offline (shutdown) in seconds. This is important, since we see that a peer is * offline and an other peer reports this peer, we don't want to add it into our map. Thus, there is a * map that keeps track of such peers. This also means that a fast reconnect is not possible and a peer * has to wait until the timeout to rejoin * @return this class */ public PeerMapConfiguration shutdownTimeout(final int shutdownTimeout) { this.shutdownTimeout = shutdownTimeout; return this; } /** * @return The time, in seconds, a peer is considered offline (exception). This is important, since we see that a peer is offline * and an other peer reports this peer, we don't want to add it into our map. Thus, there is a map that * keeps track of such peers. This also means that a fast reconnect is not possible and a peer has to wait * until the timeout to rejoin */ public int exceptionTimeout() { return exceptionTimeout; } /** * @param exceptionTimeout * The time, in seconds, a peer is considered offline (exception). This is important, since we see that a peer is * offline and an other peer reports this peer, we don't want to add it into our map. Thus, there is a * map that keeps track of such peers. This also means that a fast reconnect is not possible and a peer * has to wait until the timeout to rejoin * @return this class */ public PeerMapConfiguration exceptionTimeout(final int exceptionTimeout) { this.exceptionTimeout = exceptionTimeout; return this; } public boolean isPeerVerification() { return peerVerification; } public PeerMapConfiguration peerNoVerification() { peerVerification = false; return this; } public PeerMapConfiguration peerVerification(boolean reerVerification) { this.peerVerification = reerVerification; return this; } public PeerStatisticComparator getPeerStatisticComparator() { return peerStatisticComparator; } public PeerMapConfiguration setPeerStatisticComparator(PeerStatisticComparator peerStatisticComparator) { this.peerStatisticComparator = peerStatisticComparator; return this; } }