summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Network/BitTorrent/Core/Node.hs22
1 files changed, 22 insertions, 0 deletions
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
25 , testIdBit 25 , testIdBit
26 , genNodeId 26 , genNodeId
27 27
28 -- ** Node distance
29 , NodeDistance
30 , distance
31
28 -- * Node address 32 -- * Node address
29 , NodeAddr (..) 33 , NodeAddr (..)
30 34
31 -- * Node info 35 -- * Node info
32 , NodeInfo (..) 36 , NodeInfo (..)
37 , rank
33 ) where 38 ) where
34 39
35import Control.Applicative 40import Control.Applicative
@@ -112,6 +117,19 @@ genNodeId :: IO NodeId
112genNodeId = NodeId <$> getEntropy nodeIdSize 117genNodeId = NodeId <$> getEntropy nodeIdSize
113 118
114{----------------------------------------------------------------------- 119{-----------------------------------------------------------------------
120-- Node distance
121-----------------------------------------------------------------------}
122
123-- | In Kademlia, the distance metric is XOR and the result is
124-- interpreted as an unsigned integer.
125newtype NodeDistance = NodeDistance BS.ByteString
126 deriving (Eq, Ord)
127
128-- | distance(A,B) = |A xor B| Smaller values are closer.
129distance :: NodeId -> NodeId -> NodeDistance
130distance (NodeId a) (NodeId b) = NodeDistance (BS.pack (BS.zipWith xor a b))
131
132{-----------------------------------------------------------------------
115-- Node address 133-- Node address
116-----------------------------------------------------------------------} 134-----------------------------------------------------------------------}
117 135
@@ -194,3 +212,7 @@ instance Pretty ip => Pretty (NodeInfo ip) where
194 212
195instance Pretty ip => Pretty [NodeInfo ip] where 213instance Pretty ip => Pretty [NodeInfo ip] where
196 pretty = PP.vcat . PP.punctuate "," . L.map pretty 214 pretty = PP.vcat . PP.punctuate "," . L.map pretty
215
216-- | Order by closeness: nearest nodes first.
217rank :: Eq ip => NodeId -> [NodeInfo ip] -> [NodeInfo ip]
218rank nid = L.sortBy (comparing (distance nid . nodeId))