コード例 #1
0
 /** Have we asked this peer for the key? */
 public synchronized boolean askedFromPeer(PeerNodeUnlocked peer, long now) {
   boolean anyValid = false;
   boolean ret = false;
   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) {
       requestedNodes[i] = null;
       continue;
     }
     long bootID = pn.getBootID();
     if (bootID != requestedBootIDs[i]) {
       requestedNodes[i] = null;
       continue;
     }
     anyValid = true;
     if (now - requestedTimes[i] < MAX_TIME_BETWEEN_REQUEST_AND_OFFER) {
       if (pn == peer) ret = true;
       anyValid = true;
     }
   }
   if (!anyValid) {
     requestedNodes = EMPTY_WEAK_REFERENCE;
     requestedTimes =
         requestedBootIDs = requestedTimeoutsRF = requestedTimeoutsFT = EMPTY_LONG_ARRAY;
     requestedTimeoutHTLs = EMPTY_SHORT_ARRAY;
   }
   return ret;
 }
コード例 #2
0
 public synchronized short minRequestorHTL(short htl) {
   long now = System.currentTimeMillis();
   boolean anyValid = false;
   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) {
       requestorNodes[i] = null;
       continue;
     }
     long bootID = pn.getBootID();
     if (bootID != requestorBootIDs[i]) {
       requestorNodes[i] = null;
       continue;
     }
     if (now - requestorTimes[i] < MAX_TIME_BETWEEN_REQUEST_AND_OFFER) {
       if (requestorHTLs[i] < htl) htl = requestorHTLs[i];
     }
     anyValid = true;
   }
   if (!anyValid) {
     requestorNodes = EMPTY_WEAK_REFERENCE;
     requestorTimes = requestorBootIDs = EMPTY_LONG_ARRAY;
     ;
     requestorHTLs = EMPTY_SHORT_ARRAY;
   }
   return htl;
 }
コード例 #3
0
  private boolean cleanupRequestor(long now) {
    boolean empty = true;
    int x = 0;
    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;
      long bootID = pn.getBootID();
      if (bootID != requestorBootIDs[i]) continue;
      if (!pn.isConnected()) continue;
      if (now - requestorTimes[i] > MAX_TIME_BETWEEN_REQUEST_AND_OFFER) continue;
      empty = false;
      requestorNodes[x] = requestorNodes[i];
      requestorTimes[x] = requestorTimes[i];
      requestorBootIDs[x] = requestorBootIDs[i];
      requestorHTLs[x] = requestorHTLs[i];
      x++;
    }
    if (x < requestorNodes.length) {
      requestorNodes = Arrays.copyOf(requestorNodes, x);
      ;
      requestorTimes = Arrays.copyOf(requestorTimes, x);
      ;
      requestorBootIDs = Arrays.copyOf(requestorBootIDs, x);
      ;
      requestorHTLs = Arrays.copyOf(requestorHTLs, x);
      ;
    }

    return empty;
  }
コード例 #4
0
 /**
  * A request failed to a specific peer.
  *
  * @param routedTo The peer we routed to.
  * @param rfTimeout The time until we can route to the node again, for purposes of RecentlyFailed.
  * @param ftTimeout The time until we can route to the node again, for purposes of per-node
  *     failure tables.
  * @param now The current time.
  * @param htl The HTL of the request. Note that timeouts only apply to the same HTL.
  */
 public synchronized void failedTo(
     PeerNodeUnlocked routedTo, int rfTimeout, int ftTimeout, long now, short htl) {
   if (logMINOR) {
     Logger.minor(
         this,
         "Failed sending request to "
             + routedTo.shortToString()
             + " : timeout "
             + rfTimeout
             + " / "
             + ftTimeout);
   }
   int idx = addRequestedFrom(routedTo, htl, now);
   if (rfTimeout > 0) {
     long curTimeoutTime = requestedTimeoutsRF[idx];
     long newTimeoutTime = now + rfTimeout;
     if (newTimeoutTime > curTimeoutTime) {
       requestedTimeoutsRF[idx] = newTimeoutTime;
       requestedTimeoutHTLs[idx] = htl;
     }
   }
   if (ftTimeout > 0) {
     long curTimeoutTime = requestedTimeoutsFT[idx];
     long newTimeoutTime = now + ftTimeout;
     if (newTimeoutTime > curTimeoutTime) {
       requestedTimeoutsFT[idx] = newTimeoutTime;
       requestedTimeoutHTLs[idx] = htl;
     }
   }
 }
コード例 #5
0
 private boolean cleanupRequested(long now) {
   boolean empty = true;
   int x = 0;
   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;
     long bootID = pn.getBootID();
     if (bootID != requestedBootIDs[i]) continue;
     if (!pn.isConnected()) continue;
     if (now - requestedTimes[i] > MAX_TIME_BETWEEN_REQUEST_AND_OFFER) continue;
     empty = false;
     requestedNodes[x] = requestedNodes[i];
     requestedTimes[x] = requestedTimes[i];
     requestedBootIDs[x] = requestedBootIDs[i];
     requestedLocs[x] = requestedLocs[i];
     if (now < requestedTimeoutsRF[x] || now < requestedTimeoutsFT[x]) {
       requestedTimeoutsRF[x] = requestedTimeoutsRF[i];
       requestedTimeoutsFT[x] = requestedTimeoutsFT[i];
       requestedTimeoutHTLs[x] = requestedTimeoutHTLs[i];
     } else {
       requestedTimeoutsRF[x] = -1;
       requestedTimeoutsFT[x] = -1;
       requestedTimeoutHTLs[x] = (short) -1;
     }
     x++;
   }
   if (x < requestedNodes.length) {
     requestedNodes = Arrays.copyOf(requestedNodes, x);
     ;
     requestedTimes = Arrays.copyOf(requestedTimes, x);
     ;
     requestedBootIDs = Arrays.copyOf(requestedBootIDs, x);
     ;
     requestedLocs = Arrays.copyOf(requestedLocs, x);
     ;
     requestedTimeoutsRF = Arrays.copyOf(requestedTimeoutsRF, x);
     ;
     requestedTimeoutsFT = Arrays.copyOf(requestedTimeoutsFT, x);
     ;
     requestedTimeoutHTLs = Arrays.copyOf(requestedTimeoutHTLs, x);
     ;
   }
   return empty;
 }
コード例 #6
0
 /** Has any node asked for this key? */
 public synchronized boolean othersWant(PeerNodeUnlocked peer) {
   boolean anyValid = false;
   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) {
       requestorNodes[i] = null;
       continue;
     }
     long bootID = pn.getBootID();
     if (bootID != requestorBootIDs[i]) {
       requestorNodes[i] = null;
       continue;
     }
     anyValid = true;
   }
   if (!anyValid) {
     requestorNodes = EMPTY_WEAK_REFERENCE;
     requestorTimes = requestorBootIDs = EMPTY_LONG_ARRAY;
     requestorHTLs = EMPTY_SHORT_ARRAY;
   }
   return anyValid;
 }
コード例 #7
0
 /**
  * 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);
   }
 }
コード例 #8
0
  /**
   * Add a requested from entry to the node. If there already is one reuse it but only if the HTL
   * matches. Return the index so we can update timeouts etc.
   *
   * @param requestedFrom The node we have routed the request to.
   * @param htl The HTL at which the request was sent.
   * @param now The current time.
   * @return The index of the new or old entry.
   */
  private synchronized int addRequestedFrom(PeerNodeUnlocked requestedFrom, short htl, long now) {
    if (logMINOR) Logger.minor(this, "Adding requested from: " + requestedFrom + " at " + now);
    sentTime = now;
    boolean includedAlready = false;
    int nulls = 0;
    int ret = -1;
    for (int i = 0; i < requestedNodes.length; i++) {
      PeerNodeUnlocked got = requestedNodes[i] == null ? null : requestedNodes[i].get();
      if (got == requestedFrom
          && (requestedTimeoutsRF[i] == -1
              || requestedTimeoutsFT[i] == -1
              || requestedTimeoutHTLs[i] == htl)) {
        includedAlready = true;
        requestedLocs[i] = requestedFrom.getLocation();
        requestedBootIDs[i] = requestedFrom.getBootID();
        requestedTimes[i] = now;
        ret = i;
      } else if (got != null
          && (got.getBootID() != requestedBootIDs[i]
              || now - requestedTimes[i] > MAX_TIME_BETWEEN_REQUEST_AND_OFFER)) {
        requestedNodes[i] = null;
        got = null;
      }
      if (got == null) nulls++;
    }
    if (includedAlready && nulls == 0) return ret;
    int notIncluded = includedAlready ? 0 : 1;
    // Because weak, these can become null; doesn't matter, but we want to minimise memory usage
    if (nulls == 1 && !includedAlready) {
      // Nice special case
      for (int i = 0; i < requestedNodes.length; i++) {
        if (requestedNodes[i] == null || requestedNodes[i].get() == null) {
          requestedNodes[i] = requestedFrom.getWeakRef();
          requestedLocs[i] = requestedFrom.getLocation();
          requestedBootIDs[i] = requestedFrom.getBootID();
          requestedTimes[i] = now;
          requestedTimeoutsRF[i] = -1;
          requestedTimeoutsFT[i] = -1;
          requestedTimeoutHTLs[i] = (short) -1;
          return i;
        }
      }
    }
    @SuppressWarnings("unchecked")
    WeakReference<? extends PeerNodeUnlocked>[] newRequestedNodes =
        new WeakReference[requestedNodes.length + notIncluded - nulls];
    double[] newRequestedLocs = new double[requestedNodes.length + notIncluded - nulls];
    long[] newRequestedBootIDs = new long[requestedNodes.length + notIncluded - nulls];
    long[] newRequestedTimes = new long[requestedNodes.length + notIncluded - nulls];
    long[] newRequestedTimeoutsFT = new long[requestedNodes.length + notIncluded - nulls];
    long[] newRequestedTimeoutsRF = new long[requestedNodes.length + notIncluded - nulls];
    short[] newRequestedTimeoutHTLs = new short[requestedNodes.length + notIncluded - nulls];

    int toIndex = 0;
    for (int i = 0; i < requestedNodes.length; i++) {
      WeakReference<? extends PeerNodeUnlocked> ref = requestedNodes[i];
      PeerNodeUnlocked pn = ref == null ? null : ref.get();
      if (pn == null) continue;
      if (pn == requestedFrom) ret = toIndex;
      newRequestedNodes[toIndex] = requestedNodes[i];
      newRequestedTimes[toIndex] = requestedTimes[i];
      newRequestedBootIDs[toIndex] = requestedBootIDs[i];
      newRequestedLocs[toIndex] = requestedLocs[i];
      newRequestedTimeoutsFT[toIndex] = requestedTimeoutsFT[i];
      newRequestedTimeoutsRF[toIndex] = requestedTimeoutsRF[i];
      newRequestedTimeoutHTLs[toIndex] = requestedTimeoutHTLs[i];
      toIndex++;
    }

    if (!includedAlready) {
      ret = toIndex;
      newRequestedNodes[toIndex] = requestedFrom.getWeakRef();
      newRequestedTimes[toIndex] = now;
      newRequestedBootIDs[toIndex] = requestedFrom.getBootID();
      newRequestedLocs[toIndex] = requestedFrom.getLocation();
      newRequestedTimeoutsFT[toIndex] = -1;
      newRequestedTimeoutsRF[toIndex] = -1;
      newRequestedTimeoutHTLs[toIndex] = (short) -1;
      ret = toIndex;
      toIndex++;
    }

    for (int i = toIndex; i < newRequestedNodes.length; i++) newRequestedNodes[i] = null;
    if (toIndex > newRequestedNodes.length + 2) {
      newRequestedNodes = Arrays.copyOf(newRequestedNodes, toIndex);
      ;
      newRequestedLocs = Arrays.copyOf(newRequestedLocs, toIndex);
      ;
      newRequestedBootIDs = Arrays.copyOf(newRequestedBootIDs, toIndex);
      ;
      newRequestedTimes = Arrays.copyOf(newRequestedTimes, toIndex);
      ;
      newRequestedTimeoutsRF = Arrays.copyOf(newRequestedTimeoutsRF, toIndex);
      ;
      newRequestedTimeoutsFT = Arrays.copyOf(newRequestedTimeoutsFT, toIndex);
      ;
      newRequestedTimeoutHTLs = Arrays.copyOf(newRequestedTimeoutHTLs, toIndex);
      ;
    }
    requestedNodes = newRequestedNodes;
    requestedLocs = newRequestedLocs;
    requestedBootIDs = newRequestedBootIDs;
    requestedTimes = newRequestedTimes;
    requestedTimeoutsRF = newRequestedTimeoutsRF;
    requestedTimeoutsFT = newRequestedTimeoutsFT;
    requestedTimeoutHTLs = newRequestedTimeoutHTLs;

    return ret;
  }
コード例 #9
0
  synchronized int addRequestor(PeerNodeUnlocked requestor, long now, short origHTL) {
    if (logMINOR) Logger.minor(this, "Adding requestors: " + requestor + " at " + now);
    receivedTime = now;
    boolean includedAlready = false;
    int nulls = 0;
    int ret = -1;
    for (int i = 0; i < requestorNodes.length; i++) {
      PeerNodeUnlocked got = requestorNodes[i] == null ? null : requestorNodes[i].get();
      // No longer subscribed if they have rebooted, or expired
      if (got == requestor) {
        // Update existing entry
        includedAlready = true;
        requestorTimes[i] = now;
        requestorBootIDs[i] = requestor.getBootID();
        requestorHTLs[i] = origHTL;
        ret = i;
        break;
      } else if (got != null
          && (got.getBootID() != requestorBootIDs[i]
              || now - requestorTimes[i] > MAX_TIME_BETWEEN_REQUEST_AND_OFFER)) {
        requestorNodes[i] = null;
        got = null;
      }
      if (got == null) nulls++;
    }
    if (nulls == 0 && includedAlready) return ret;
    int notIncluded = includedAlready ? 0 : 1;
    // Because weak, these can become null; doesn't matter, but we want to minimise memory usage
    if (nulls == 1 && !includedAlready) {
      // Nice special case
      for (int i = 0; i < requestorNodes.length; i++) {
        if (requestorNodes[i] == null || requestorNodes[i].get() == null) {
          requestorNodes[i] = requestor.getWeakRef();
          requestorTimes[i] = now;
          requestorBootIDs[i] = requestor.getBootID();
          requestorHTLs[i] = origHTL;
          return i;
        }
      }
    }
    @SuppressWarnings("unchecked")
    WeakReference<? extends PeerNodeUnlocked>[] newRequestorNodes =
        new WeakReference[requestorNodes.length + notIncluded - nulls];
    long[] newRequestorTimes = new long[requestorNodes.length + notIncluded - nulls];
    long[] newRequestorBootIDs = new long[requestorNodes.length + notIncluded - nulls];
    short[] newRequestorHTLs = new short[requestorNodes.length + notIncluded - nulls];
    int toIndex = 0;

    for (int i = 0; i < requestorNodes.length; i++) {
      WeakReference<? extends PeerNodeUnlocked> ref = requestorNodes[i];
      PeerNodeUnlocked pn = ref == null ? null : ref.get();
      if (pn == null) continue;
      if (pn == requestor) ret = toIndex;
      newRequestorNodes[toIndex] = requestorNodes[i];
      newRequestorTimes[toIndex] = requestorTimes[i];
      newRequestorBootIDs[toIndex] = requestorBootIDs[i];
      newRequestorHTLs[toIndex] = requestorHTLs[i];
      toIndex++;
    }

    if (!includedAlready) {
      newRequestorNodes[toIndex] = requestor.getWeakRef();
      newRequestorTimes[toIndex] = now;
      newRequestorBootIDs[toIndex] = requestor.getBootID();
      newRequestorHTLs[toIndex] = origHTL;
      ret = toIndex;
      toIndex++;
    }

    for (int i = toIndex; i < newRequestorNodes.length; i++) newRequestorNodes[i] = null;
    if (toIndex > newRequestorNodes.length + 2) {
      newRequestorNodes = Arrays.copyOf(newRequestorNodes, toIndex);
      newRequestorTimes = Arrays.copyOf(newRequestorTimes, toIndex);
      newRequestorBootIDs = Arrays.copyOf(newRequestorBootIDs, toIndex);
      newRequestorHTLs = Arrays.copyOf(newRequestorHTLs, toIndex);
    }
    requestorNodes = newRequestorNodes;
    requestorTimes = newRequestorTimes;
    requestorBootIDs = newRequestorBootIDs;
    requestorHTLs = newRequestorHTLs;

    return ret;
  }