diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-11-20 22:32:38 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-11-20 22:32:38 +0400 |
commit | 025a04ff3a3d9e936a27692b214e8c871260a3e7 (patch) | |
tree | 95b8b67072b9ba7465651b63a92845cdbd00b4c8 | |
parent | 05c444079632946807e5311e24b06e13c4205515 (diff) |
Use Word64 instead of Integer in Progress datatype.
Also add documentation.
-rw-r--r-- | src/Data/Torrent/Progress.hs | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/src/Data/Torrent/Progress.hs b/src/Data/Torrent/Progress.hs index 9abf0380..bbfe6e47 100644 --- a/src/Data/Torrent/Progress.hs +++ b/src/Data/Torrent/Progress.hs | |||
@@ -1,14 +1,28 @@ | |||
1 | -- | | ||
2 | -- Copyright : (c) Sam Truzjan 2013 | ||
3 | -- License : BSD3 | ||
4 | -- Maintainer : pxqr.sta@gmail.com | ||
5 | -- Stability : experimental | ||
6 | -- Portability : portable | ||
7 | -- | ||
8 | -- 'Progress' used to track amount downloaded\/left\/upload bytes | ||
9 | -- either on per client or per torrent basis. This value is used to | ||
10 | -- notify the tracker and usually shown to the user. To aggregate | ||
11 | -- total progress you can use the Monoid instance. | ||
12 | -- | ||
1 | {-# LANGUAGE TemplateHaskell #-} | 13 | {-# LANGUAGE TemplateHaskell #-} |
2 | {-# LANGUAGE ViewPatterns #-} | 14 | {-# LANGUAGE ViewPatterns #-} |
3 | module Data.Torrent.Progress | 15 | module Data.Torrent.Progress |
4 | ( -- * Progress | 16 | ( -- * Progress |
5 | Progress (..) | 17 | Progress (..) |
18 | |||
19 | -- * Lens | ||
6 | , left | 20 | , left |
7 | , uploaded | 21 | , uploaded |
8 | , downloaded | 22 | , downloaded |
9 | 23 | ||
24 | -- * Construction | ||
10 | , startProgress | 25 | , startProgress |
11 | |||
12 | , downloadedProgress | 26 | , downloadedProgress |
13 | , enqueuedProgress | 27 | , enqueuedProgress |
14 | , uploadedProgress | 28 | , uploadedProgress |
@@ -18,26 +32,22 @@ module Data.Torrent.Progress | |||
18 | import Control.Applicative | 32 | import Control.Applicative |
19 | import Control.Lens | 33 | import Control.Lens |
20 | import Data.Aeson.TH | 34 | import Data.Aeson.TH |
21 | import Data.List as L | ||
22 | import Data.Default | 35 | import Data.Default |
36 | import Data.List as L | ||
37 | import Data.Monoid | ||
23 | import Data.Serialize as S | 38 | import Data.Serialize as S |
39 | import Data.Word | ||
24 | 40 | ||
25 | 41 | ||
26 | -- TODO: Use Word64? | 42 | -- | Progress data is considered as dynamic within one client |
27 | -- TODO: Use atomic bits? | ||
28 | |||
29 | -- | 'Progress' contains upload/download/left stats about | ||
30 | -- current client state and used to notify the tracker. | ||
31 | -- | ||
32 | -- Progress data is considered as dynamic within one client | ||
33 | -- session. This data also should be shared across client application | 43 | -- session. This data also should be shared across client application |
34 | -- sessions (e.g. files), otherwise use 'startProgress' to get initial | 44 | -- sessions (e.g. files), otherwise use 'startProgress' to get initial |
35 | -- 'Progress'. | 45 | -- 'Progress' value. |
36 | -- | 46 | -- |
37 | data Progress = Progress | 47 | data Progress = Progress |
38 | { _downloaded :: !Integer -- ^ Total amount of bytes downloaded; | 48 | { _downloaded :: {-# UNPACK #-} !Word64 -- ^ Total amount of bytes downloaded; |
39 | , _left :: !Integer -- ^ Total amount of bytes left; | 49 | , _left :: {-# UNPACK #-} !Word64 -- ^ Total amount of bytes left; |
40 | , _uploaded :: !Integer -- ^ Total amount of bytes uploaded. | 50 | , _uploaded :: {-# UNPACK #-} !Word64 -- ^ Total amount of bytes uploaded. |
41 | } deriving (Show, Read, Eq) | 51 | } deriving (Show, Read, Eq) |
42 | 52 | ||
43 | $(makeLenses ''Progress) | 53 | $(makeLenses ''Progress) |
@@ -58,7 +68,16 @@ instance Default Progress where | |||
58 | def = Progress 0 0 0 | 68 | def = Progress 0 0 0 |
59 | {-# INLINE def #-} | 69 | {-# INLINE def #-} |
60 | 70 | ||
61 | -- TODO Monoid instance | 71 | instance Monoid Progress where |
72 | mempty = def | ||
73 | {-# INLINE mempty #-} | ||
74 | |||
75 | mappend (Progress da la ua) (Progress db lb ub) = Progress | ||
76 | { _downloaded = da + db | ||
77 | , _left = la + lb | ||
78 | , _uploaded = ua + ub | ||
79 | } | ||
80 | {-# INLINE mappend #-} | ||
62 | 81 | ||
63 | -- | Initial progress is used when there are no session before. | 82 | -- | Initial progress is used when there are no session before. |
64 | -- | 83 | -- |
@@ -67,7 +86,7 @@ instance Default Progress where | |||
67 | -- client sessions to avoid that. | 86 | -- client sessions to avoid that. |
68 | -- | 87 | -- |
69 | startProgress :: Integer -> Progress | 88 | startProgress :: Integer -> Progress |
70 | startProgress = Progress 0 0 | 89 | startProgress = Progress 0 0 . fromIntegral |
71 | {-# INLINE startProgress #-} | 90 | {-# INLINE startProgress #-} |
72 | 91 | ||
73 | -- | Used when the client download some data from /any/ peer. | 92 | -- | Used when the client download some data from /any/ peer. |
@@ -84,11 +103,11 @@ uploadedProgress (fromIntegral -> amount) = uploaded +~ amount | |||
84 | 103 | ||
85 | -- | Used when leecher join client session. | 104 | -- | Used when leecher join client session. |
86 | enqueuedProgress :: Integer -> Progress -> Progress | 105 | enqueuedProgress :: Integer -> Progress -> Progress |
87 | enqueuedProgress amount = left +~ amount | 106 | enqueuedProgress amount = left +~ fromIntegral amount |
88 | {-# INLINE enqueuedProgress #-} | 107 | {-# INLINE enqueuedProgress #-} |
89 | 108 | ||
90 | -- | Used when leecher leave client session. | 109 | -- | Used when leecher leave client session. |
91 | -- (e.g. user deletes not completed torrent) | 110 | -- (e.g. user deletes not completed torrent) |
92 | dequeuedProgress :: Integer -> Progress -> Progress | 111 | dequeuedProgress :: Integer -> Progress -> Progress |
93 | dequeuedProgress amount = left -~ amount | 112 | dequeuedProgress amount = left -~ fromIntegral amount |
94 | {-# INLINE dequeuedProgress #-} | 113 | {-# INLINE dequeuedProgress #-} |