summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2014-01-09 04:31:32 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2014-01-09 04:31:32 +0400
commit71a3ffda743f14da3a9828ddc20b69b4f185e1f4 (patch)
tree33e32035543f2728fa9213f36214abf23f044e98
parentf1cea56f6077e563458c8075faf3ca592290b6d9 (diff)
Add NodeDistance newtype
-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))