diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-07-16 20:25:43 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-07-16 20:25:43 +0400 |
commit | 412919e88e1d60303f7a14134e37f27becf5f959 (patch) | |
tree | 89711599f2ca1101c1d905e65516b2778c50fd07 /src/System/Torrent/Storage.hs | |
parent | 8c6e5818ee6b901efd975392c54aff5cf2721ae4 (diff) |
~ Move client bitfield to storage.
We localize bitfield mutation in storage module this way.
Also fix some warnings.
Diffstat (limited to 'src/System/Torrent/Storage.hs')
-rw-r--r-- | src/System/Torrent/Storage.hs | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/src/System/Torrent/Storage.hs b/src/System/Torrent/Storage.hs index dd7258a0..c355d697 100644 --- a/src/System/Torrent/Storage.hs +++ b/src/System/Torrent/Storage.hs | |||
@@ -24,6 +24,7 @@ module System.Torrent.Storage | |||
24 | 24 | ||
25 | -- * Construction | 25 | -- * Construction |
26 | , openStorage, closeStorage, withStorage | 26 | , openStorage, closeStorage, withStorage |
27 | , getCompleteBitfield | ||
27 | 28 | ||
28 | -- * Modification | 29 | -- * Modification |
29 | , getBlk, putBlk, selBlk | 30 | , getBlk, putBlk, selBlk |
@@ -51,19 +52,20 @@ import Data.Bitfield as BF | |||
51 | import Data.Torrent | 52 | import Data.Torrent |
52 | import Network.BitTorrent.Exchange.Protocol | 53 | import Network.BitTorrent.Exchange.Protocol |
53 | import System.IO.MMap.Fixed as Fixed | 54 | import System.IO.MMap.Fixed as Fixed |
54 | import Debug.Trace | ||
55 | |||
56 | 55 | ||
56 | -- TODO merge piece validation and Sessions.available into one transaction. | ||
57 | data Storage = Storage { | 57 | data Storage = Storage { |
58 | -- | | 58 | -- | |
59 | metainfo:: !Torrent | 59 | metainfo :: !Torrent |
60 | 60 | ||
61 | -- | | 61 | -- | Bitmask of complete and verified _pieces_. |
62 | , blocks :: !(TVar Bitfield) | 62 | , complete :: !(TVar Bitfield) |
63 | |||
64 | -- | Bitmask of complete _blocks_. | ||
65 | , blocks :: !(TVar Bitfield) | ||
63 | -- TODO use bytestring for fast serialization | 66 | -- TODO use bytestring for fast serialization |
64 | -- because we need to write this bitmap to disc periodically | 67 | -- because we need to write this bitmap to disc periodically |
65 | 68 | ||
66 | |||
67 | , blockSize :: !Int | 69 | , blockSize :: !Int |
68 | 70 | ||
69 | -- | Used to map linear block addresses to disjoint | 71 | -- | Used to map linear block addresses to disjoint |
@@ -76,19 +78,23 @@ ppStorage Storage {..} = pp <$> readTVarIO blocks | |||
76 | where | 78 | where |
77 | pp bf = int blockSize | 79 | pp bf = int blockSize |
78 | 80 | ||
81 | getCompleteBitfield :: Storage -> STM Bitfield | ||
82 | getCompleteBitfield Storage {..} = readTVar complete | ||
83 | |||
79 | {----------------------------------------------------------------------- | 84 | {----------------------------------------------------------------------- |
80 | Construction | 85 | Construction |
81 | -----------------------------------------------------------------------} | 86 | -----------------------------------------------------------------------} |
82 | 87 | ||
83 | -- TODO doc args | 88 | -- TODO doc args |
84 | openStorage :: Torrent -> FilePath -> IO Storage | 89 | openStorage :: Torrent -> FilePath -> Bitfield -> IO Storage |
85 | openStorage t @ Torrent {..} contentPath = do | 90 | openStorage t @ Torrent {..} contentPath bf = do |
86 | let content_paths = contentLayout contentPath tInfo | 91 | let content_paths = contentLayout contentPath tInfo |
87 | mapM_ (mkDir . fst) content_paths | 92 | mapM_ (mkDir . fst) content_paths |
88 | 93 | ||
89 | let blockSize = defaultBlockSize `min` ciPieceLength tInfo | 94 | let blockSize = defaultBlockSize `min` ciPieceLength tInfo |
90 | print $ "content length " ++ show (contentLength tInfo) | 95 | print $ "content length " ++ show (contentLength tInfo) |
91 | Storage t <$> newTVarIO (haveNone (blockCount blockSize tInfo)) | 96 | Storage t <$> newTVarIO bf |
97 | <*> newTVarIO (haveNone (blockCount blockSize tInfo)) | ||
92 | <*> pure blockSize | 98 | <*> pure blockSize |
93 | <*> coalesceFiles content_paths | 99 | <*> coalesceFiles content_paths |
94 | where | 100 | where |
@@ -103,8 +109,8 @@ closeStorage :: Storage -> IO () | |||
103 | closeStorage st = return () | 109 | closeStorage st = return () |
104 | 110 | ||
105 | 111 | ||
106 | withStorage :: Torrent -> FilePath -> (Storage -> IO a) -> IO a | 112 | withStorage :: Torrent -> FilePath -> Bitfield -> (Storage -> IO a) -> IO a |
107 | withStorage se path = bracket (openStorage se path) closeStorage | 113 | withStorage se path bf = bracket (openStorage se path bf) closeStorage |
108 | 114 | ||
109 | {----------------------------------------------------------------------- | 115 | {----------------------------------------------------------------------- |
110 | Modification | 116 | Modification |
@@ -191,7 +197,9 @@ validatePiece pix st @ Storage {..} = {-# SCC validatePiece #-} do | |||
191 | else do | 197 | else do |
192 | piece <- getPiece pix st | 198 | piece <- getPiece pix st |
193 | if checkPiece (tInfo metainfo) pix piece | 199 | if checkPiece (tInfo metainfo) pix piece |
194 | then return True | 200 | then do |
201 | atomically $ modifyTVar' complete (BF.have pix) | ||
202 | return True | ||
195 | else do | 203 | else do |
196 | print $ "----------------------------- invalid " ++ show pix | 204 | print $ "----------------------------- invalid " ++ show pix |
197 | -- resetPiece pix st | 205 | -- resetPiece pix st |