/// <summary> /// Returns the closest successor preceding id. /// </summary> /// <param name="id">The id for which the closest finger should be found</param> /// <returns>The successor node of the closest finger to id in the current node's finger table</returns> private ChordNode FindClosestPrecedingFinger(UInt64 id) { // iterate downward through the finger table looking for the right finger in the right range. if the finger is // in the range but not valid, keep moving. if the entire finger table is checked without success, check the successor // cache - if that fails, return the local node as the closest preceding finger. for (int i = this.FingerTable.Length - 1; i >= 0; i--) { // if the finger is more closely between the local node and id and that finger corresponds to a valid node, return the finger if (this.FingerTable.Successors[i] != null && this.FingerTable.Successors[i] != ChordServer.LocalNode) { if (ChordServer.FingerInRange(this.FingerTable.Successors[i].ID, this.ID, id)) { ChordInstance instance = ChordServer.GetInstance(this.FingerTable.Successors[i]); if (ChordServer.IsInstanceValid(instance)) { return(this.FingerTable.Successors[i]); } } } } // at this point, not even the successor is any good so go through the successor cache and run the same test for (int i = 0; i < this.SuccessorCache.Length; i++) { if (this.SuccessorCache[i] != null && this.SuccessorCache[i] != ChordServer.LocalNode) { if (ChordServer.FingerInRange(this.SuccessorCache[i].ID, this.ID, id)) { ChordInstance instance = ChordServer.GetInstance(this.SuccessorCache[i]); if (ChordServer.IsInstanceValid(instance)) { return(this.SuccessorCache[i]); } } } } // otherwise, if there is nothing closer, the local node is the closest preceding finger return(ChordServer.LocalNode); }