From 71a3ffda743f14da3a9828ddc20b69b4f185e1f4 Mon Sep 17 00:00:00 2001 From: Sam Truzjan Date: Thu, 9 Jan 2014 04:31:32 +0400 Subject: Add NodeDistance newtype --- src/Network/BitTorrent/Core/Node.hs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/Network/BitTorrent/Core/Node.hs b/src/Network/BitTorrent/Core/Node.hs index 82f05de4..febaacac 100644 --- a/src/Network/BitTorrent/Core/Node.hs +++ b/src/Network/BitTorrent/Core/Node.hs @@ -25,11 +25,16 @@ module Network.BitTorrent.Core.Node , testIdBit , genNodeId + -- ** Node distance + , NodeDistance + , distance + -- * Node address , NodeAddr (..) -- * Node info , NodeInfo (..) + , rank ) where import Control.Applicative @@ -111,6 +116,19 @@ testIdBit (NodeId bs) i genNodeId :: IO NodeId genNodeId = NodeId <$> getEntropy nodeIdSize +{----------------------------------------------------------------------- +-- Node distance +-----------------------------------------------------------------------} + +-- | In Kademlia, the distance metric is XOR and the result is +-- interpreted as an unsigned integer. +newtype NodeDistance = NodeDistance BS.ByteString + deriving (Eq, Ord) + +-- | distance(A,B) = |A xor B| Smaller values are closer. +distance :: NodeId -> NodeId -> NodeDistance +distance (NodeId a) (NodeId b) = NodeDistance (BS.pack (BS.zipWith xor a b)) + {----------------------------------------------------------------------- -- Node address -----------------------------------------------------------------------} @@ -194,3 +212,7 @@ instance Pretty ip => Pretty (NodeInfo ip) where instance Pretty ip => Pretty [NodeInfo ip] where pretty = PP.vcat . PP.punctuate "," . L.map pretty + +-- | Order by closeness: nearest nodes first. +rank :: Eq ip => NodeId -> [NodeInfo ip] -> [NodeInfo ip] +rank nid = L.sortBy (comparing (distance nid . nodeId)) -- cgit v1.2.3