diff options
-rw-r--r-- | bittorrent.cabal | 1 | ||||
-rw-r--r-- | src/Network/BitTorrent/Internal.hs | 40 |
2 files changed, 41 insertions, 0 deletions
diff --git a/bittorrent.cabal b/bittorrent.cabal index 5f39d3ea..01e45c96 100644 --- a/bittorrent.cabal +++ b/bittorrent.cabal | |||
@@ -80,6 +80,7 @@ library | |||
80 | , bytestring >= 0.10.0.0 | 80 | , bytestring >= 0.10.0.0 |
81 | 81 | ||
82 | , containers >= 0.4 | 82 | , containers >= 0.4 |
83 | , unordered-containers | ||
83 | , intset >= 0.1 | 84 | , intset >= 0.1 |
84 | , IntervalMap >= 0.3 | 85 | , IntervalMap >= 0.3 |
85 | 86 | ||
diff --git a/src/Network/BitTorrent/Internal.hs b/src/Network/BitTorrent/Internal.hs index bd20aa16..fffd4727 100644 --- a/src/Network/BitTorrent/Internal.hs +++ b/src/Network/BitTorrent/Internal.hs | |||
@@ -89,6 +89,7 @@ import Data.IORef | |||
89 | import Data.Default | 89 | import Data.Default |
90 | import Data.Function | 90 | import Data.Function |
91 | import Data.Foldable (mapM_) | 91 | import Data.Foldable (mapM_) |
92 | import Data.HashMap.Strict as HM | ||
92 | import Data.Ord | 93 | import Data.Ord |
93 | import Data.Set as S | 94 | import Data.Set as S |
94 | import Data.Typeable | 95 | import Data.Typeable |
@@ -182,6 +183,33 @@ type ThreadCount = Int | |||
182 | defaultThreadCount :: ThreadCount | 183 | defaultThreadCount :: ThreadCount |
183 | defaultThreadCount = 1000 | 184 | defaultThreadCount = 1000 |
184 | 185 | ||
186 | {- PERFORMANCE NOTE: keeping torrent metafiles in memory is a _bad_ | ||
187 | idea: for 1TB of data we need at least 100MB of metadata. (using 256KB | ||
188 | piece size). This solution do not scale further. Solution with | ||
189 | TorrentLoc is much better and takes much more less space, moreover it | ||
190 | depends on count of torrents but not on count of data itself. To scale | ||
191 | further, in future we might add something like database (for | ||
192 | e.g. sqlite) for this kind of things.-} | ||
193 | |||
194 | -- | Identifies location of | ||
195 | data TorrentLoc = TorrentLoc { | ||
196 | metafilePath :: FilePath | ||
197 | , dataPath :: FilePath | ||
198 | } | ||
199 | |||
200 | validateTorrent :: TorrentLoc -> IO () | ||
201 | validateTorrent = error "validateTorrent: not implemented" | ||
202 | |||
203 | -- | TorrentMap is used to keep track all known torrents for the | ||
204 | -- client. When some peer trying to connect to us it's necessary to | ||
205 | -- dispatch appropriate 'SwarmSession' (or start new one if there are | ||
206 | -- none) in the listener loop: we only know 'InfoHash' from | ||
207 | -- 'Handshake' but nothing more. So to accept new 'PeerSession' we | ||
208 | -- need to lookup torrent metainfo and content files (if there are | ||
209 | -- some) by the 'InfoHash' and only after that enter exchange loop. | ||
210 | -- | ||
211 | type TorrentMap = HashMap InfoHash TorrentLoc | ||
212 | |||
185 | {- NOTE: basically, client session should contain options which user | 213 | {- NOTE: basically, client session should contain options which user |
186 | app store in configuration files. (related to the protocol) Moreover | 214 | app store in configuration files. (related to the protocol) Moreover |
187 | it should contain the all client identification info. (e.g. DHT) -} | 215 | it should contain the all client identification info. (e.g. DHT) -} |
@@ -226,6 +254,9 @@ data ClientSession = ClientSession { | |||
226 | 254 | ||
227 | -- | Used to keep track global client progress. | 255 | -- | Used to keep track global client progress. |
228 | , currentProgress :: !(TVar Progress) | 256 | , currentProgress :: !(TVar Progress) |
257 | |||
258 | -- | Used to keep track available torrents. | ||
259 | , torrentMap :: !(TVar TorrentMap) | ||
229 | } | 260 | } |
230 | 261 | ||
231 | -- currentProgress field is reduntant: progress depends on the all swarm bitfields | 262 | -- currentProgress field is reduntant: progress depends on the all swarm bitfields |
@@ -272,6 +303,15 @@ newClient n exts = do | |||
272 | <*> newTVarIO S.empty | 303 | <*> newTVarIO S.empty |
273 | <*> pure mgr | 304 | <*> pure mgr |
274 | <*> newTVarIO (startProgress 0) | 305 | <*> newTVarIO (startProgress 0) |
306 | <*> newTVarIO HM.empty | ||
307 | |||
308 | registerTorrent :: ClientSession -> InfoHash -> TorrentLoc -> STM () | ||
309 | registerTorrent ClientSession {..} ih tl = do | ||
310 | modifyTVar' torrentMap $ HM.insert ih tl | ||
311 | |||
312 | unregisterTorrent :: ClientSession -> InfoHash -> STM () | ||
313 | unregisterTorrent ClientSession {..} ih = do | ||
314 | modifyTVar' torrentMap $ HM.delete ih | ||
275 | 315 | ||
276 | {----------------------------------------------------------------------- | 316 | {----------------------------------------------------------------------- |
277 | Swarm session | 317 | Swarm session |