summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2014-01-05 22:58:25 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2014-01-05 22:58:25 +0400
commit29036b62a5da2505862c904bc069c7b0b94129e4 (patch)
treee34734c822f525c2afbee720609ab5070146d2ac
parent8d194406c7d23e610bf5227f52ee8e04a555e85d (diff)
Implement getBitfield and genPieceInfo functions
-rw-r--r--src/Data/Torrent/Bitfield.hs13
-rw-r--r--src/System/Torrent/Storage.hs29
-rw-r--r--tests/System/Torrent/StorageSpec.hs7
3 files changed, 44 insertions, 5 deletions
diff --git a/src/Data/Torrent/Bitfield.hs b/src/Data/Torrent/Bitfield.hs
index 02a4c14f..8cdae69f 100644
--- a/src/Data/Torrent/Bitfield.hs
+++ b/src/Data/Torrent/Bitfield.hs
@@ -62,6 +62,7 @@ module Data.Torrent.Bitfield
62 , rarest 62 , rarest
63 63
64 -- * Combine 64 -- * Combine
65 , insert
65 , union 66 , union
66 , intersection 67 , intersection
67 , difference 68 , difference
@@ -196,6 +197,10 @@ findMax = S.findMax . bfSet
196isSubsetOf :: Bitfield -> Bitfield -> Bool 197isSubsetOf :: Bitfield -> Bitfield -> Bool
197isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b 198isSubsetOf a b = bfSet a `S.isSubsetOf` bfSet b
198 199
200{-----------------------------------------------------------------------
201-- Availability
202-----------------------------------------------------------------------}
203
199-- | Frequencies are needed in piece selection startegies which use 204-- | Frequencies are needed in piece selection startegies which use
200-- availability quantity to find out the optimal next piece index to 205-- availability quantity to find out the optimal next piece index to
201-- download. 206-- download.
@@ -240,6 +245,14 @@ rarest xs
240 Combine 245 Combine
241-----------------------------------------------------------------------} 246-----------------------------------------------------------------------}
242 247
248insert :: PieceIx -> Bitfield -> Bitfield
249insert pix bf @ Bitfield {..}
250 | 0 <= pix && pix < bfSize = Bitfield
251 { bfSet = S.insert pix bfSet
252 , bfSize = bfSize
253 }
254 | otherwise = bf
255
243-- | Find indices at least one peer have. 256-- | Find indices at least one peer have.
244union :: Bitfield -> Bitfield -> Bitfield 257union :: Bitfield -> Bitfield -> Bitfield
245union a b = {-# SCC union #-} Bitfield { 258union a b = {-# SCC union #-} Bitfield {
diff --git a/src/System/Torrent/Storage.hs b/src/System/Torrent/Storage.hs
index 8aa1aa99..a8b0bdc6 100644
--- a/src/System/Torrent/Storage.hs
+++ b/src/System/Torrent/Storage.hs
@@ -44,9 +44,12 @@ module System.Torrent.Storage
44 44
45import Control.Applicative 45import Control.Applicative
46import Control.Exception 46import Control.Exception
47import Control.Monad as M
47import Control.Monad.Trans 48import Control.Monad.Trans
48import Data.ByteString.Lazy as BL 49import Data.ByteString.Lazy as BL
49import Data.Conduit 50import Data.Conduit as C
51import Data.Conduit.Binary as C
52import Data.Conduit.List as C
50import Data.Typeable 53import Data.Typeable
51 54
52import Data.Torrent.Bitfield as BF 55import Data.Torrent.Bitfield as BF
@@ -156,10 +159,26 @@ sinkStorage s = do
156 awaitForever $ \ piece -> 159 awaitForever $ \ piece ->
157 liftIO $ writePiece piece s 160 liftIO $ writePiece piece s
158 161
159-- | TODO examples of use 162-- | This function can be used to generate 'InfoDict' from a set of
163-- opened files.
160genPieceInfo :: Storage -> IO PieceInfo 164genPieceInfo :: Storage -> IO PieceInfo
161genPieceInfo = undefined 165genPieceInfo s = do
166 hashes <- sourceStorage s $= C.map hashPiece $$ C.sinkLbs
167 return $ PieceInfo (pieceLen s) (HashList (BL.toStrict hashes))
162 168
163-- | TODO examples of use 169-- | Verify storage.
170--
171-- Throws 'InvalidSize' if piece info size do not match with storage
172-- piece size.
173--
164getBitfield :: Storage -> PieceInfo -> IO Bitfield 174getBitfield :: Storage -> PieceInfo -> IO Bitfield
165getBitfield = undefined \ No newline at end of file 175getBitfield s @ Storage {..} pinfo @ PieceInfo {..}
176 | pieceLen /= piPieceLength = throwIO (InvalidSize piPieceLength)
177 | otherwise = M.foldM verifyPiece (BF.haveNone total) [0..total - 1]
178 where
179 total = totalPieces s
180
181 verifyPiece :: Bitfield -> PieceIx -> IO Bitfield
182 verifyPiece bf pix = do
183 valid <- checkPieceLazy pinfo <$> readPiece pix s
184 return $ if valid then BF.insert pix bf else bf
diff --git a/tests/System/Torrent/StorageSpec.hs b/tests/System/Torrent/StorageSpec.hs
index 2e94ccf1..40eaa9c7 100644
--- a/tests/System/Torrent/StorageSpec.hs
+++ b/tests/System/Torrent/StorageSpec.hs
@@ -8,6 +8,7 @@ import System.Directory
8import System.IO.Unsafe 8import System.IO.Unsafe
9import Test.Hspec 9import Test.Hspec
10 10
11import Data.Torrent.Bitfield as BF
11import Data.Torrent.Layout 12import Data.Torrent.Layout
12import Data.Torrent.Piece 13import Data.Torrent.Piece
13import System.Torrent.Storage 14import System.Torrent.Storage
@@ -86,3 +87,9 @@ spec = before createLayout $ do
86 sourceStorage s $= C.map bzeroPiece $$ sinkStorage s 87 sourceStorage s $= C.map bzeroPiece $$ sinkStorage s
87 b <- sourceStorage s $$ C.fold (\ b p -> b && isZeroPiece p) True 88 b <- sourceStorage s $$ C.fold (\ b p -> b && isZeroPiece p) True
88 b `shouldBe` True 89 b `shouldBe` True
90
91 describe "genPieceInfo" $ do
92 it "" $ do
93 withStorage ReadWrite psize layout $ \ s -> do
94 bf <- genPieceInfo s >>= getBitfield s
95 bf `shouldSatisfy` BF.full \ No newline at end of file