diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2014-01-09 04:31:32 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2014-01-09 04:31:32 +0400 |
commit | 71a3ffda743f14da3a9828ddc20b69b4f185e1f4 (patch) | |
tree | 33e32035543f2728fa9213f36214abf23f044e98 /src | |
parent | f1cea56f6077e563458c8075faf3ca592290b6d9 (diff) |
Add NodeDistance newtype
Diffstat (limited to 'src')
-rw-r--r-- | src/Network/BitTorrent/Core/Node.hs | 22 |
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 | ||
35 | import Control.Applicative | 40 | import Control.Applicative |
@@ -112,6 +117,19 @@ genNodeId :: IO NodeId | |||
112 | genNodeId = NodeId <$> getEntropy nodeIdSize | 117 | genNodeId = 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. | ||
125 | newtype NodeDistance = NodeDistance BS.ByteString | ||
126 | deriving (Eq, Ord) | ||
127 | |||
128 | -- | distance(A,B) = |A xor B| Smaller values are closer. | ||
129 | distance :: NodeId -> NodeId -> NodeDistance | ||
130 | distance (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 | ||
195 | instance Pretty ip => Pretty [NodeInfo ip] where | 213 | instance 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. | ||
217 | rank :: Eq ip => NodeId -> [NodeInfo ip] -> [NodeInfo ip] | ||
218 | rank nid = L.sortBy (comparing (distance nid . nodeId)) | ||