diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Data/Torrent/Bitfield.hs | 13 | ||||
-rw-r--r-- | src/System/Torrent/Storage.hs | 14 |
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 | |||
194 | findMax = S.findMax . bfSet | 195 | findMax = S.findMax . bfSet |
195 | {-# INLINE findMax #-} | 196 | {-# INLINE findMax #-} |
196 | 197 | ||
198 | -- | Check if all pieces from first bitfield present if the second bitfield | ||
197 | isSubsetOf :: Bitfield -> Bitfield -> Bool | 199 | isSubsetOf :: Bitfield -> Bitfield -> Bool |
198 | isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b | 200 | isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b |
201 | {-# INLINE isSubsetOf #-} | ||
202 | |||
203 | -- | Resulting bitfield includes only missing pieces. | ||
204 | complement :: Bitfield -> Bitfield | ||
205 | complement 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. | ||
172 | verifyPiece :: Storage -> PieceInfo -> PieceIx -> IO Bool | ||
173 | verifyPiece 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 | |||
174 | getBitfield :: Storage -> PieceInfo -> IO Bitfield | 180 | getBitfield :: Storage -> PieceInfo -> IO Bitfield |
175 | getBitfield s @ Storage {..} pinfo @ PieceInfo {..} | 181 | getBitfield 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 |