summaryrefslogtreecommitdiff
path: root/Kademlia.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2017-07-22 01:15:44 -0400
committerjoe <joe@jerkface.net>2017-07-22 01:15:44 -0400
commit77f6b96492223e7d7b147dac8d026e0b6f6a651b (patch)
tree661e2115a814de82ba251bccf0ab21ae4dfd1ff1 /Kademlia.hs
parent7f1eb53d34ea6dda02cae1934b5011e38de248a6 (diff)
Implemented bucket refresh for Mainline.
Diffstat (limited to 'Kademlia.hs')
-rw-r--r--Kademlia.hs38
1 files changed, 32 insertions, 6 deletions
diff --git a/Kademlia.hs b/Kademlia.hs
index 9316f135..bcddfab1 100644
--- a/Kademlia.hs
+++ b/Kademlia.hs
@@ -18,7 +18,6 @@ import GHC.Conc (labelThread)
18import Control.Concurrent.Lifted 18import Control.Concurrent.Lifted
19#endif 19#endif
20import Data.Bits 20import Data.Bits
21
22import Text.PrettyPrint as PP hiding ((<>), ($$)) 21import Text.PrettyPrint as PP hiding ((<>), ($$))
23import Text.PrettyPrint.HughesPJClass hiding ((<>),($$)) 22import Text.PrettyPrint.HughesPJClass hiding ((<>),($$))
24import Data.IP 23import Data.IP
@@ -28,6 +27,11 @@ import Data.Monoid
28import Data.Time.Clock.POSIX (POSIXTime) 27import Data.Time.Clock.POSIX (POSIXTime)
29import Data.Wrapper.PSQInt ( pattern (:->) ) 28import Data.Wrapper.PSQInt ( pattern (:->) )
30import qualified Data.Wrapper.PSQInt as Int 29import qualified Data.Wrapper.PSQInt as Int
30import Network.BitTorrent.DHT.Search
31import Network.DatagramServer.Types (genBucketSample)
32import Network.Address (bucketRange)
33import Data.Serialize (Serialize)
34import Data.Hashable
31 35
32-- | The status of a given node with respect to a given routint table. 36-- | The status of a given node with respect to a given routint table.
33data RoutingStatus 37data RoutingStatus
@@ -206,15 +210,16 @@ insertNode (Kademlia reporter space io) node = do
206-- It might also be better to pass the timestamp of the transition here and 210-- It might also be better to pass the timestamp of the transition here and
207-- keep the refresh queue in better sync with the routing table by updating it 211-- keep the refresh queue in better sync with the routing table by updating it
208-- within the STM monad. 212-- within the STM monad.
209touchBucket :: POSIXTime -> (ni -> Int) -> TVar (Int.PSQ POSIXTime) -> RoutingTransition ni -> STM (IO ()) 213touchBucket :: KademliaSpace nid ni -> POSIXTime -> TVar (BucketList ni) -> TVar (Int.PSQ POSIXTime) -> RoutingTransition ni -> STM (IO ())
210touchBucket interval bktnum psq tr 214touchBucket space interval bkts psq tr
211 | (transitionedTo tr == Applicant) 215 | (transitionedTo tr == Applicant)
212 = return $ return () 216 = return $ return ()
213 | otherwise = return $ do 217 | otherwise = return $ do
214 now <- getPOSIXTime 218 now <- getPOSIXTime
215 atomically $ modifyTVar' psq 219 atomically $ do
216 $ Int.insert (bktnum $ transitioningNode tr) 220 let nid = kademliaLocation space (transitioningNode tr)
217 (now + interval) 221 num <- R.bucketNumber space nid <$> readTVar bkts
222 modifyTVar' psq $ Int.insert num (now + interval)
218 223
219-- | > pollForRefresh interval queue refresh 224-- | > pollForRefresh interval queue refresh
220-- 225--
@@ -250,3 +255,24 @@ pollForRefresh interval psq refresh = do
250 return () 255 return ()
251 seconds -> threadDelay ( seconds * 1000000 ) 256 seconds -> threadDelay ( seconds * 1000000 )
252 again 257 again
258
259refreshBucket :: forall nid ni addr.
260 ( FiniteBits nid, Serialize nid, Ord nid, Ord ni, Hashable nid, Hashable ni, Ord addr ) =>
261 Search nid addr ni ni -> TVar (BucketList ni) -> nid -> Int -> IO ()
262refreshBucket sch var nid n = do
263 tbl <- atomically (readTVar var)
264 sample <- genBucketSample nid (bucketRange (n) (n + 1 < bktCount tbl))
265 resultCounter <- atomically $ newTVar 0
266 let fullcount = R.defaultBucketSize
267 let checkBucketFull :: ni -> STM Bool
268 checkBucketFull found_node = do
269 tbl <- readTVar var
270 let counts = R.shape tbl
271 when (n == R.bucketNumber (searchSpace sch) (kademliaLocation (searchSpace sch) found_node) tbl)
272 $ modifyTVar resultCounter (+ 1)
273 resultCount <- readTVar resultCounter
274 case drop (n - 1) counts of
275 (cnt:_) | cnt < fullcount -> return True
276 _ | resultCount + 3 < fullcount -> return True -- +3 because maybe duplicates.
277 _ -> return False
278 search sch tbl sample checkBucketFull