DistributedFileSystem.ChunkFlags.NumCompletedChunks C# (CSharp) Method

NumCompletedChunks() public method

Returns the number of completed chunk
public NumCompletedChunks ( ) : byte
return byte
        public byte NumCompletedChunks()
        {
            return (byte)(LongBitCount.CountBits(flags0) + LongBitCount.CountBits(flags1) + LongBitCount.CountBits(flags2) + LongBitCount.CountBits(flags3));
        }

Usage Example

        /// <summary>
        /// Adds or updates a peer to the local availability list. Useful for when a peer informs us of an updated availability.
        /// </summary>
        /// <param name="connectionInfo">The connectionInfo of the remote peer</param>
        /// <param name="latestChunkFlags">The new chunk flags</param>
        /// <param name="superPeer">True if this peer is a superPeer</param>
        /// <param name="setIPEndPointOnline">Set the relevant IPEndPoint online as a result of updating chunk flags</param>
        public void AddOrUpdateCachedPeerChunkFlags(ConnectionInfo connectionInfo, ChunkFlags latestChunkFlags, bool superPeer = false, bool setIPEndPointOnline = true)
        {
            if (connectionInfo.NetworkIdentifier == ShortGuid.Empty) throw new Exception("networkIdentifier should not be empty.");

            lock (peerLocker)
            {
                if (connectionInfo.ConnectionType != ConnectionType.TCP) throw new Exception("Only the TCP side of a DFS peer should be tracked.");

                //Extract the correct endpoint from the provided connectionInfo
                //If this is taken from a connection we are after the remoteEndPoint
                IPEndPoint endPointToUse = null;
                if (((IPEndPoint)connectionInfo.RemoteEndPoint).Address == IPAddress.Any ||
                    ((IPEndPoint)connectionInfo.RemoteEndPoint).Address == IPAddress.IPv6Any)
                    endPointToUse = (IPEndPoint)connectionInfo.LocalEndPoint;
                else
                    endPointToUse = (IPEndPoint)connectionInfo.RemoteEndPoint;

                string endPointToUseString = endPointToUse.ToString();
                //We can only add a peer if it is listening correctly
                if (endPointToUse.Port <= DFS.MaxTargetLocalPort && endPointToUse.Port >= DFS.MinTargetLocalPort)
                {
                    //Ensure the endpoint is correctly recorded
                    RemoveOldPeerAtEndPoint(connectionInfo.NetworkIdentifier, endPointToUse);

                    //If we have an existing record of this peer
                    if (peerAvailabilityByNetworkIdentifierDict.ContainsKey(connectionInfo.NetworkIdentifier))
                    {
                        //If the existing peerInfo is not aware of this endPoint
                        if (!peerAvailabilityByNetworkIdentifierDict[connectionInfo.NetworkIdentifier].PeerContainsIPEndPoint(connectionInfo.NetworkIdentifier, endPointToUse))
                        {
                            //Add the information to the peerInfo and local index
                            peerAvailabilityByNetworkIdentifierDict[connectionInfo.NetworkIdentifier].AddPeerIPEndPoint(connectionInfo.NetworkIdentifier, endPointToUse);
                            peerEndPointToNetworkIdentifier[endPointToUseString] = connectionInfo.NetworkIdentifier;
                        }

                        //Finally update the chunk flags
                        peerAvailabilityByNetworkIdentifierDict[connectionInfo.NetworkIdentifier].PeerChunkFlags.UpdateFlags(latestChunkFlags);

                        if (DFS.loggingEnabled) DFS.Logger.Trace("Updated existing chunk flags for " + connectionInfo + " [" + latestChunkFlags.NumCompletedChunks() + "].");
                    }
                    else
                    {
                        //If we don't know anything about this peer we add it to our local swarm availability
                        //We used comms to get any existing connections to the peer
                        //We have to create new ConnectionInfo in the select as we need to correctly set the "LOCAL IPEndPoint" when passing to new PeerInfo()
                        List<ConnectionInfo> peerConnectionInfos = (from current in NetworkComms.GetExistingConnection(connectionInfo.NetworkIdentifier, ConnectionType.TCP) select new ConnectionInfo(ConnectionType.TCP, current.ConnectionInfo.NetworkIdentifier, current.ConnectionInfo.RemoteEndPoint, true)).ToList();
                        
                        //Don't forget to add the originating info if it was not pulled out from above
                        ConnectionInfo originatingConnectionInfo = new ConnectionInfo(ConnectionType.TCP, connectionInfo.NetworkIdentifier, endPointToUse, true);
                        if (!peerConnectionInfos.Contains(originatingConnectionInfo)) peerConnectionInfos.Add(originatingConnectionInfo);
                        
                        peerAvailabilityByNetworkIdentifierDict.Add(connectionInfo.NetworkIdentifier, new PeerInfo(peerConnectionInfos, latestChunkFlags, superPeer));

                        //We finish by adding the endPoint references
                        foreach (ConnectionInfo connInfo in peerConnectionInfos)
                            peerEndPointToNetworkIdentifier[connInfo.LocalEndPoint.ToString()] = connectionInfo.NetworkIdentifier;

                        if (DFS.loggingEnabled) DFS.Logger.Trace("Added new chunk flags for " + connectionInfo);
                    }

                    if (setIPEndPointOnline)
                        //By updating cached peer chunk flags we set the peer as being online
                        peerAvailabilityByNetworkIdentifierDict[connectionInfo.NetworkIdentifier].SetPeerIPEndPointOnlineStatus(connectionInfo.NetworkIdentifier, endPointToUse, true);

                    //We will trigger the alive peers event when we have at least a third of the existing peers
                    if (!alivePeersReceivedEvent.WaitOne(0))
                    {
                        int numOnlinePeers = (from current in peerAvailabilityByNetworkIdentifierDict.Values where current.HasAtleastOneOnlineIPEndPoint() select current).Count();
                        if (numOnlinePeers >= DFS.MaxTotalItemRequests || numOnlinePeers > peerAvailabilityByNetworkIdentifierDict.Count / 3.0)
                            alivePeersReceivedEvent.Set();
                    }
                }
                else
                    throw new Exception("Attempted to AddOrUpdateCachedPeerChunkFlags for client which was not listening or was using port outside the valid DFS range. Provided connectionInfo: " + connectionInfo + ". EndPointToUse:" + endPointToUse);
                    //LogTools.LogException("Attempted to AddOrUpdateCachedPeerChunkFlags for client which was not listening or was using port outside the valid DFS range.", "PeerChunkFlagsUpdateError", "IP:" + endPointToUse.Address.ToString() + ", Port:" + endPointToUse.Port);
            }
        }