summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Data/Bitfield.hs12
-rw-r--r--src/Network/BitTorrent.hs4
-rw-r--r--src/Network/BitTorrent/Exchange.hs39
-rw-r--r--src/Network/BitTorrent/Internal.hs5
-rw-r--r--src/System/Torrent/Storage.hs18
5 files changed, 43 insertions, 35 deletions
diff --git a/src/Data/Bitfield.hs b/src/Data/Bitfield.hs
index 89461fd2..acfca0d0 100644
--- a/src/Data/Bitfield.hs
+++ b/src/Data/Bitfield.hs
@@ -236,28 +236,28 @@ rarest xs
236 236
237-- | Find indices at least one peer have. 237-- | Find indices at least one peer have.
238union :: Bitfield -> Bitfield -> Bitfield 238union :: Bitfield -> Bitfield -> Bitfield
239union a b = Bitfield { 239union a b = {-# SCC union #-} Bitfield {
240 bfSize = bfSize a `max` bfSize b 240 bfSize = bfSize a `max` bfSize b
241 , bfSet = bfSet a `S.union` bfSet b 241 , bfSet = bfSet a `S.union` bfSet b
242 } 242 }
243 243
244-- | Find indices both peers have. 244-- | Find indices both peers have.
245intersection :: Bitfield -> Bitfield -> Bitfield 245intersection :: Bitfield -> Bitfield -> Bitfield
246intersection a b = Bitfield { 246intersection a b = {-# SCC intersection #-} Bitfield {
247 bfSize = bfSize a `min` bfSize b 247 bfSize = bfSize a `min` bfSize b
248 , bfSet = bfSet a `S.intersection` bfSet b 248 , bfSet = bfSet a `S.intersection` bfSet b
249 } 249 }
250 250
251-- | Find indices which have first peer but do not have the second peer. 251-- | Find indices which have first peer but do not have the second peer.
252difference :: Bitfield -> Bitfield -> Bitfield 252difference :: Bitfield -> Bitfield -> Bitfield
253difference a b = Bitfield { 253difference a b = {-# SCC difference #-} Bitfield {
254 bfSize = bfSize a -- FIXME is it reasonable? 254 bfSize = bfSize a -- FIXME is it reasonable?
255 , bfSet = bfSet a `S.difference` bfSet b 255 , bfSet = bfSet a `S.difference` bfSet b
256 } 256 }
257 257
258-- | Find indices the any of the peers have. 258-- | Find indices the any of the peers have.
259unions :: [Bitfield] -> Bitfield 259unions :: [Bitfield] -> Bitfield
260unions = foldl' union (haveNone 0) 260unions = {-# SCC unions #-} foldl' union (haveNone 0)
261 261
262{----------------------------------------------------------------------- 262{-----------------------------------------------------------------------
263 Serialization 263 Serialization
@@ -270,7 +270,7 @@ toList Bitfield {..} = S.toList bfSet
270-- | Unpack 'Bitfield' from tightly packed bit array. Note resulting 270-- | Unpack 'Bitfield' from tightly packed bit array. Note resulting
271-- size might be more than real bitfield size, use 'adjustSize'. 271-- size might be more than real bitfield size, use 'adjustSize'.
272fromBitmap :: ByteString -> Bitfield 272fromBitmap :: ByteString -> Bitfield
273fromBitmap bs = Bitfield { 273fromBitmap bs = {-# SCC fromBitmap #-} Bitfield {
274 bfSize = B.length bs * 8 274 bfSize = B.length bs * 8
275 , bfSet = S.fromByteString bs 275 , bfSet = S.fromByteString bs
276 } 276 }
@@ -278,7 +278,7 @@ fromBitmap bs = Bitfield {
278 278
279-- | Pack a 'Bitfield' to tightly packed bit array. 279-- | Pack a 'Bitfield' to tightly packed bit array.
280toBitmap :: Bitfield -> Lazy.ByteString 280toBitmap :: Bitfield -> Lazy.ByteString
281toBitmap Bitfield {..} = Lazy.fromChunks [intsetBM, alignment] 281toBitmap Bitfield {..} = {-# SCC toBitmap #-} Lazy.fromChunks [intsetBM, alignment]
282 where 282 where
283 byteSize = bfSize `div` 8 + if bfSize `mod` 8 == 0 then 0 else 1 283 byteSize = bfSize `div` 8 + if bfSize `mod` 8 == 0 then 0 else 1
284 alignment = B.replicate (byteSize - B.length intsetBM) 0 284 alignment = B.replicate (byteSize - B.length intsetBM) 0
diff --git a/src/Network/BitTorrent.hs b/src/Network/BitTorrent.hs
index b6e2eadf..95a4c4e3 100644
--- a/src/Network/BitTorrent.hs
+++ b/src/Network/BitTorrent.hs
@@ -102,7 +102,7 @@ defaultClient = newClient defaultThreadCount defaultExtensions
102-- thus we can obtain an unified interface 102-- thus we can obtain an unified interface
103 103
104discover :: SwarmSession -> P2P () -> IO () 104discover :: SwarmSession -> P2P () -> IO ()
105discover swarm action = do 105discover swarm action = {-# SCC discover #-} do
106 port <- forkListener (error "discover") 106 port <- forkListener (error "discover")
107 107
108 let conn = TConnection (tAnnounce (torrentMeta swarm)) 108 let conn = TConnection (tAnnounce (torrentMeta swarm))
@@ -134,7 +134,7 @@ discover swarm action = do
134 134
135-- | Default P2P action. 135-- | Default P2P action.
136exchange :: Storage -> P2P () 136exchange :: Storage -> P2P ()
137exchange storage = awaitEvent >>= handler 137exchange storage = {-# SCC exchange #-} (awaitEvent >>= handler)
138 where 138 where
139 handler (Available bf) = do 139 handler (Available bf) = do
140 liftIO (print (completeness bf)) 140 liftIO (print (completeness bf))
diff --git a/src/Network/BitTorrent/Exchange.hs b/src/Network/BitTorrent/Exchange.hs
index 66112f14..9f119d13 100644
--- a/src/Network/BitTorrent/Exchange.hs
+++ b/src/Network/BitTorrent/Exchange.hs
@@ -110,17 +110,21 @@ runPeerWire sock p2p =
110 sinkSocket sock 110 sinkSocket sock
111 111
112awaitMessage :: P2P Message 112awaitMessage :: P2P Message
113awaitMessage = P2P $ ReaderT $ const go 113awaitMessage = P2P $ ReaderT $ const $ {-# SCC awaitMessage #-} go
114 where 114 where
115 go = await >>= maybe (monadThrow PeerDisconnected) return 115 go = await >>= maybe (monadThrow PeerDisconnected) return
116{-# INLINE awaitMessage #-} 116{-# INLINE awaitMessage #-}
117 117
118yieldMessage :: Message -> P2P () 118yieldMessage :: Message -> P2P ()
119yieldMessage msg = P2P $ ReaderT $ const (C.yield msg) 119yieldMessage msg = P2P $ ReaderT $ const $ {-# SCC yieldMessage #-} C.yield msg
120{-# INLINE yieldMessage #-} 120{-# INLINE yieldMessage #-}
121 121
122flushPending :: P2P () 122flushPending :: P2P ()
123flushPending = ask >>= liftIO . getPending >>= mapM_ yieldMessage 123flushPending = {-# SCC flushPending #-} do
124 se <- ask
125 q <- liftIO (getPending se)
126 -- TODO send vectored
127 mapM_ yieldMessage q
124 128
125{----------------------------------------------------------------------- 129{-----------------------------------------------------------------------
126 P2P monad 130 P2P monad
@@ -321,7 +325,7 @@ data Event
321-- forall (Fragment block). isPiece block == True 325-- forall (Fragment block). isPiece block == True
322-- 326--
323awaitEvent :: P2P Event 327awaitEvent :: P2P Event
324awaitEvent = awaitMessage >>= go 328awaitEvent = {-# SCC awaitEvent #-} awaitMessage >>= go
325 where 329 where
326 go KeepAlive = awaitEvent 330 go KeepAlive = awaitEvent
327 go Choke = do 331 go Choke = do
@@ -439,22 +443,21 @@ awaitEvent = awaitMessage >>= go
439-- most likely will be ignored without any network IO. 443-- most likely will be ignored without any network IO.
440-- 444--
441yieldEvent :: Event -> P2P () 445yieldEvent :: Event -> P2P ()
442yieldEvent (Available ixs) = asks swarmSession >>= liftIO . available ixs 446yieldEvent e = {-# SCC yieldEvent #-} go e
443yieldEvent (Want bix) = do 447 where
444 offer <- peerOffer 448 go (Available ixs) = asks swarmSession >>= liftIO . available ixs
445 if ixPiece bix `BF.member` offer 449 go (Want bix) = do
446 then yieldMessage (Request bix) 450 offer <- peerOffer
447 else return () 451 if ixPiece bix `BF.member` offer
452 then yieldMessage (Request bix)
453 else return ()
448 454
449yieldEvent (Fragment blk) = do 455 go (Fragment blk) = do
450 offer <- clientOffer 456 offer <- clientOffer
451 if blkPiece blk `BF.member` offer 457 if blkPiece blk `BF.member` offer
452 then yieldMessage (Piece blk) 458 then yieldMessage (Piece blk)
453 else return () 459 else return ()
454 460
455 461
456handleEvent :: (Event -> P2P Event) -> P2P () 462handleEvent :: (Event -> P2P Event) -> P2P ()
457handleEvent action = awaitEvent >>= action >>= yieldEvent 463handleEvent action = awaitEvent >>= action >>= yieldEvent
458
459checkPiece :: PieceLIx -> {-ByteString -> -} P2P Bool
460checkPiece = undefined
diff --git a/src/Network/BitTorrent/Internal.hs b/src/Network/BitTorrent/Internal.hs
index eaeb04e8..5a7e493f 100644
--- a/src/Network/BitTorrent/Internal.hs
+++ b/src/Network/BitTorrent/Internal.hs
@@ -538,7 +538,7 @@ findPieceCount = pieceCount . tInfo . torrentMeta . swarmSession
538-- 3. Signal to the all other peer about this. 538-- 3. Signal to the all other peer about this.
539 539
540available :: Bitfield -> SwarmSession -> IO () 540available :: Bitfield -> SwarmSession -> IO ()
541available bf se @ SwarmSession {..} = do 541available bf se @ SwarmSession {..} = {-# SCC available #-} do
542 mark >> atomically broadcast 542 mark >> atomically broadcast
543 where 543 where
544 mark = do 544 mark = do
@@ -561,7 +561,8 @@ available bf se @ SwarmSession {..} = do
561-- changed client state. Resulting queue should be sent to a peer 561-- changed client state. Resulting queue should be sent to a peer
562-- immediately. 562-- immediately.
563getPending :: PeerSession -> IO [Message] 563getPending :: PeerSession -> IO [Message]
564getPending PeerSession {..} = atomically (readAvail pendingMessages) 564getPending PeerSession {..} = {-# SCC getPending #-} do
565 atomically (readAvail pendingMessages)
565 566
566readAvail :: TChan a -> STM [a] 567readAvail :: TChan a -> STM [a]
567readAvail chan = do 568readAvail chan = do
diff --git a/src/System/Torrent/Storage.hs b/src/System/Torrent/Storage.hs
index cb0494e8..8a884196 100644
--- a/src/System/Torrent/Storage.hs
+++ b/src/System/Torrent/Storage.hs
@@ -110,7 +110,8 @@ withStorage se path = bracket (se `bindTo` path) unbind
110-- TODO make block_payload :: Lazy.ByteString 110-- TODO make block_payload :: Lazy.ByteString
111 111
112selBlk :: MonadIO m => PieceIx -> Storage -> m [BlockIx] 112selBlk :: MonadIO m => PieceIx -> Storage -> m [BlockIx]
113selBlk pix st @ Storage {..} = liftIO $ atomically $ do 113selBlk pix st @ Storage {..}
114 = liftIO $ {-# SCC selBlk #-} atomically $ do
114 mask <- pieceMask pix st 115 mask <- pieceMask pix st
115 select mask <$> readTVar blocks 116 select mask <$> readTVar blocks
116 where 117 where
@@ -137,7 +138,8 @@ selBlk pix st @ Storage {..} = liftIO $ atomically $ do
137-- 138--
138-- 139--
139putBlk :: MonadIO m => Block -> Storage -> m Bool 140putBlk :: MonadIO m => Block -> Storage -> m Bool
140putBlk blk @ Block {..} st @ Storage {..} = liftIO $ do 141putBlk blk @ Block {..} st @ Storage {..}
142 = liftIO $ {-# SCC putBlk #-} do
141-- let blkIx = undefined 143-- let blkIx = undefined
142-- bm <- readTVarIO blocks 144-- bm <- readTVarIO blocks
143-- unless (member blkIx bm) $ do 145-- unless (member blkIx bm) $ do
@@ -149,7 +151,7 @@ putBlk blk @ Block {..} st @ Storage {..} = liftIO $ do
149 validatePiece blkPiece st 151 validatePiece blkPiece st
150 152
151markBlock :: Block -> Storage -> IO () 153markBlock :: Block -> Storage -> IO ()
152markBlock Block {..} Storage {..} = do 154markBlock Block {..} Storage {..} = {-# SCC markBlock #-} do
153 let piLen = pieceLength session 155 let piLen = pieceLength session
154 let glIx = (piLen `div` blockSize) * blkPiece + (blkOffset `div` blockSize) 156 let glIx = (piLen `div` blockSize) * blkPiece + (blkOffset `div` blockSize)
155 atomically $ modifyTVar' blocks (have glIx) 157 atomically $ modifyTVar' blocks (have glIx)
@@ -160,25 +162,27 @@ markBlock Block {..} Storage {..} = do
160-- Do not block. 162-- Do not block.
161-- 163--
162getBlk :: MonadIO m => BlockIx -> Storage -> m Block 164getBlk :: MonadIO m => BlockIx -> Storage -> m Block
163getBlk ix @ BlockIx {..} st @ Storage {..} = liftIO $ do 165getBlk ix @ BlockIx {..} st @ Storage {..}
166 = liftIO $ {-# SCC getBlk #-} do
164 -- TODO check if __piece__ is available 167 -- TODO check if __piece__ is available
165 bs <- readBytes (ixInterval (pieceLength session) ix) payload 168 bs <- readBytes (ixInterval (pieceLength session) ix) payload
166 return $ Block ixPiece ixOffset (Lazy.toStrict bs) 169 return $ Block ixPiece ixOffset (Lazy.toStrict bs)
167 170
168getPiece :: PieceIx -> Storage -> IO ByteString 171getPiece :: PieceIx -> Storage -> IO ByteString
169getPiece pix st @ Storage {..} = do 172getPiece pix st @ Storage {..} = {-# SCC getPiece #-} do
170 let pieceLen = pieceLength session 173 let pieceLen = pieceLength session
171 let bix = BlockIx pix 0 (pieceLength session) 174 let bix = BlockIx pix 0 (pieceLength session)
172 bs <- readBytes (ixInterval pieceLen bix) payload 175 bs <- readBytes (ixInterval pieceLen bix) payload
173 return (Lazy.toStrict bs) 176 return (Lazy.toStrict bs)
174 177
175resetPiece :: PieceIx -> Storage -> IO () 178resetPiece :: PieceIx -> Storage -> IO ()
176resetPiece pix st @ Storage {..} = atomically $ do 179resetPiece pix st @ Storage {..}
180 = {-# SCC resetPiece #-} atomically $ do
177 mask <- pieceMask pix st 181 mask <- pieceMask pix st
178 modifyTVar' blocks (`difference` mask) 182 modifyTVar' blocks (`difference` mask)
179 183
180validatePiece :: PieceIx -> Storage -> IO Bool 184validatePiece :: PieceIx -> Storage -> IO Bool
181validatePiece pix st @ Storage {..} = do 185validatePiece pix st @ Storage {..} = {-# SCC validatePiece #-} do
182 downloaded <- atomically $ isDownloaded pix st 186 downloaded <- atomically $ isDownloaded pix st
183 if not downloaded then return False 187 if not downloaded then return False
184 else do 188 else do