Esempio n. 1
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;
  }