handlePeerMsgs
) where
-import Prelude hiding (lookup, concat, replicate, splitAt, take)
+import Prelude hiding (lookup, concat, replicate, splitAt, take, filter)
import System.IO (Handle, BufferMode(..), hSetBuffering)
import Data.ByteString (ByteString, unpack, concat, hGet, hPut, take, empty)
import Control.Monad.State
import Data.Bits
import Data.Word (Word8)
-import Data.Map (Map, fromList, toList, (!), mapWithKey, adjust)
+import Data.Map (Map, fromList, toList, (!), mapWithKey, adjust, filter)
import qualified Crypto.Hash.SHA1 as SHA1 (hash)
+import Safe (headMay)
import FuncTorrent.Metainfo (Info(..), Metainfo(..))
import FuncTorrent.Utils (splitN, splitNum)
| Have
deriving (Show, Eq)
--- todo - map with index to a new data structure (peers who have that piece amd state)
+-- todo - map with index to a new data structure (peers who have that piece and state)
data PieceData = PieceData { peers :: [Peer] -- ^ list of peers who have this piece
, dlstate :: PieceDlState -- ^ state of the piece from download perspective.
, hash :: ByteString -- ^ piece hash
-- simple algorithm to pick piece.
-- pick the first piece from 0 that is not downloaded yet.
pickPiece :: PieceMap -> Maybe Integer
-pickPiece m =
- let pieceList = toList m
- allPending = filter (\(_, v) -> dlstate v == Pending) pieceList
- in
- case allPending of
- [] -> Nothing
- ((i, _):_) -> Just i
+pickPiece =
+ (fst `liftM`) . headMay . toList . filter (\v -> dlstate v == Pending)
+
+bytesDownloaded :: PieceMap -> Integer
+bytesDownloaded =
+ sum . (map (len . snd)) . toList . filter (\v -> dlstate v == Have)
updatePieceAvailability :: PieceMap -> Peer -> [Integer] -> PieceMap
updatePieceAvailability pieceStatus p pieceList =