summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Data/Torrent/Bitfield.hs13
-rw-r--r--src/System/Torrent/Storage.hs14
2 files changed, 23 insertions, 4 deletions
diff --git a/src/Data/Torrent/Bitfield.hs b/src/Data/Torrent/Bitfield.hs
index 8cdae69f..b65f058b 100644
--- a/src/Data/Torrent/Bitfield.hs
+++ b/src/Data/Torrent/Bitfield.hs
@@ -57,6 +57,7 @@ module Data.Torrent.Bitfield
57 , isSubsetOf 57 , isSubsetOf
58 58
59 -- ** Availability 59 -- ** Availability
60 , complement
60 , Frequency 61 , Frequency
61 , frequencies 62 , frequencies
62 , rarest 63 , rarest
@@ -194,8 +195,20 @@ findMax :: Bitfield -> PieceIx
194findMax = S.findMax . bfSet 195findMax = S.findMax . bfSet
195{-# INLINE findMax #-} 196{-# INLINE findMax #-}
196 197
198-- | Check if all pieces from first bitfield present if the second bitfield
197isSubsetOf :: Bitfield -> Bitfield -> Bool 199isSubsetOf :: Bitfield -> Bitfield -> Bool
198isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b 200isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b
201{-# INLINE isSubsetOf #-}
202
203-- | Resulting bitfield includes only missing pieces.
204complement :: Bitfield -> Bitfield
205complement Bitfield {..} = Bitfield
206 { bfSet = uni `S.difference` bfSet
207 , bfSize = bfSize
208 }
209 where
210 Bitfield _ uni = haveAll bfSize
211{-# INLINE complement #-}
199 212
200{----------------------------------------------------------------------- 213{-----------------------------------------------------------------------
201-- Availability 214-- Availability
diff --git a/src/System/Torrent/Storage.hs b/src/System/Torrent/Storage.hs
index a8b0bdc6..b5092b2e 100644
--- a/src/System/Torrent/Storage.hs
+++ b/src/System/Torrent/Storage.hs
@@ -28,6 +28,8 @@ module System.Torrent.Storage
28 , withStorage 28 , withStorage
29 29
30 -- * Query 30 -- * Query
31 , totalPieces
32 , verifyPiece
31 , genPieceInfo 33 , genPieceInfo
32 , getBitfield 34 , getBitfield
33 35
@@ -166,6 +168,10 @@ genPieceInfo s = do
166 hashes <- sourceStorage s $= C.map hashPiece $$ C.sinkLbs 168 hashes <- sourceStorage s $= C.map hashPiece $$ C.sinkLbs
167 return $ PieceInfo (pieceLen s) (HashList (BL.toStrict hashes)) 169 return $ PieceInfo (pieceLen s) (HashList (BL.toStrict hashes))
168 170
171-- | Verify specific piece using infodict hash list.
172verifyPiece :: Storage -> PieceInfo -> PieceIx -> IO Bool
173verifyPiece s pinfo pix = checkPieceLazy pinfo <$> readPiece pix s
174
169-- | Verify storage. 175-- | Verify storage.
170-- 176--
171-- Throws 'InvalidSize' if piece info size do not match with storage 177-- Throws 'InvalidSize' if piece info size do not match with storage
@@ -174,11 +180,11 @@ genPieceInfo s = do
174getBitfield :: Storage -> PieceInfo -> IO Bitfield 180getBitfield :: Storage -> PieceInfo -> IO Bitfield
175getBitfield s @ Storage {..} pinfo @ PieceInfo {..} 181getBitfield s @ Storage {..} pinfo @ PieceInfo {..}
176 | pieceLen /= piPieceLength = throwIO (InvalidSize piPieceLength) 182 | pieceLen /= piPieceLength = throwIO (InvalidSize piPieceLength)
177 | otherwise = M.foldM verifyPiece (BF.haveNone total) [0..total - 1] 183 | otherwise = M.foldM checkPiece (BF.haveNone total) [0..total - 1]
178 where 184 where
179 total = totalPieces s 185 total = totalPieces s
180 186
181 verifyPiece :: Bitfield -> PieceIx -> IO Bitfield 187 checkPiece :: Bitfield -> PieceIx -> IO Bitfield
182 verifyPiece bf pix = do 188 checkPiece bf pix = do
183 valid <- checkPieceLazy pinfo <$> readPiece pix s 189 valid <- verifyPiece s pinfo pix
184 return $ if valid then BF.insert pix bf else bf 190 return $ if valid then BF.insert pix bf else bf