diff options
author | Sam T <pxqr.sta@gmail.com> | 2013-06-02 05:01:46 +0400 |
---|---|---|
committer | Sam T <pxqr.sta@gmail.com> | 2013-06-02 05:01:46 +0400 |
commit | 01f51b51af8a67516238bc7264079601a7e2ece5 (patch) | |
tree | 13b346ad0ba930e7d964a3de9988365f6cc6ba4f /src/Network | |
parent | 5e92eec501e0a1ca6d09a01e078cf54ff3277273 (diff) |
~ Use IntSet instead of ByteString for bitfields.
There are several reasons for this:
* IntSet is stored in ordinary heap, while ByteStrings in pinned memory;
* Our IntSet's should be much faster 90% time. (in typical BT client)
Hovewer in worst case IntSet is slower, but difference should is not
so big. (We should measure this although)
* It's pure, tested, error-free and much more convenient.
Moreover we have kill a lot of ugly code!
Diffstat (limited to 'src/Network')
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Message.hs | 18 | ||||
-rw-r--r-- | src/Network/BitTorrent/PeerWire/Selection.hs | 22 |
2 files changed, 18 insertions, 22 deletions
diff --git a/src/Network/BitTorrent/PeerWire/Message.hs b/src/Network/BitTorrent/PeerWire/Message.hs index 5544dca7..f5ad2693 100644 --- a/src/Network/BitTorrent/PeerWire/Message.hs +++ b/src/Network/BitTorrent/PeerWire/Message.hs | |||
@@ -28,27 +28,27 @@ data Message = KeepAlive | |||
28 | 28 | ||
29 | -- | Zero-based index of a piece that has just been | 29 | -- | Zero-based index of a piece that has just been |
30 | -- successfully downloaded and verified via the hash. | 30 | -- successfully downloaded and verified via the hash. |
31 | | Have PieceIx | 31 | | Have !PieceIx |
32 | 32 | ||
33 | -- | The bitfield message may only be sent immediately | 33 | -- | The bitfield message may only be sent immediately |
34 | -- after the handshaking sequence is complete, and | 34 | -- after the handshaking sequence is complete, and |
35 | -- before any other message are sent. If client have no | 35 | -- before any other message are sent. If client have no |
36 | -- pieces then bitfield need not to be sent. | 36 | -- pieces then bitfield need not to be sent. |
37 | | Bitfield Bitfield | 37 | | Bitfield !Bitfield |
38 | 38 | ||
39 | -- | Request for a particular block. If a client is | 39 | -- | Request for a particular block. If a client is |
40 | -- requested a block that another peer do not have the | 40 | -- requested a block that another peer do not have the |
41 | -- peer might not answer at all. | 41 | -- peer might not answer at all. |
42 | | Request BlockIx | 42 | | Request !BlockIx |
43 | 43 | ||
44 | -- | Response for a request for a block. | 44 | -- | Response for a request for a block. |
45 | | Piece Block | 45 | | Piece !Block |
46 | 46 | ||
47 | -- | Used to cancel block requests. It is typically | 47 | -- | Used to cancel block requests. It is typically |
48 | -- used during "End Game". | 48 | -- used during "End Game". |
49 | | Cancel BlockIx | 49 | | Cancel !BlockIx |
50 | 50 | ||
51 | | Port PortNumber | 51 | | Port !PortNumber |
52 | 52 | ||
53 | -- | BEP 6: Then peer have all pieces it might send the | 53 | -- | BEP 6: Then peer have all pieces it might send the |
54 | -- 'HaveAll' message instead of 'Bitfield' | 54 | -- 'HaveAll' message instead of 'Bitfield' |
@@ -63,16 +63,16 @@ data Message = KeepAlive | |||
63 | -- | BEP 6: This is an advisory message meaning "you | 63 | -- | BEP 6: This is an advisory message meaning "you |
64 | -- might like to download this piece." Used to avoid | 64 | -- might like to download this piece." Used to avoid |
65 | -- excessive disk seeks and amount of IO. | 65 | -- excessive disk seeks and amount of IO. |
66 | | SuggestPiece PieceIx | 66 | | SuggestPiece !PieceIx |
67 | 67 | ||
68 | -- | BEP 6: Notifies a requesting peer that its request | 68 | -- | BEP 6: Notifies a requesting peer that its request |
69 | -- will not be satisfied. | 69 | -- will not be satisfied. |
70 | | RejectRequest BlockIx | 70 | | RejectRequest !BlockIx |
71 | 71 | ||
72 | -- | BEP 6: This is an advisory messsage meaning "if | 72 | -- | BEP 6: This is an advisory messsage meaning "if |
73 | -- you ask for this piece, I'll give it to you even if | 73 | -- you ask for this piece, I'll give it to you even if |
74 | -- you're choked." Used to shorten starting phase. | 74 | -- you're choked." Used to shorten starting phase. |
75 | | AllowedFast PieceIx | 75 | | AllowedFast !PieceIx |
76 | deriving (Show, Eq) | 76 | deriving (Show, Eq) |
77 | 77 | ||
78 | 78 | ||
diff --git a/src/Network/BitTorrent/PeerWire/Selection.hs b/src/Network/BitTorrent/PeerWire/Selection.hs index 9d154613..63cca15d 100644 --- a/src/Network/BitTorrent/PeerWire/Selection.hs +++ b/src/Network/BitTorrent/PeerWire/Selection.hs | |||
@@ -33,6 +33,7 @@ module Network.BitTorrent.PeerWire.Selection | |||
33 | ) where | 33 | ) where |
34 | 34 | ||
35 | import Data.Bitfield | 35 | import Data.Bitfield |
36 | import Data.Ratio | ||
36 | import Network.BitTorrent.PeerWire.Block | 37 | import Network.BitTorrent.PeerWire.Block |
37 | 38 | ||
38 | 39 | ||
@@ -42,10 +43,8 @@ type Selector = Bitfield -- ^ Indices of client /have/ pieces. | |||
42 | -> Maybe PieceIx -- ^ Zero-based index of piece to request | 43 | -> Maybe PieceIx -- ^ Zero-based index of piece to request |
43 | -- to, if any. | 44 | -- to, if any. |
44 | 45 | ||
45 | type PieceThreshold = Int | ||
46 | |||
47 | selector :: Selector -- ^ Selector to use at the start. | 46 | selector :: Selector -- ^ Selector to use at the start. |
48 | -> PieceThreshold | 47 | -> Ratio PieceCount |
49 | -> Selector -- ^ Selector to use after the client have the C pieces. | 48 | -> Selector -- ^ Selector to use after the client have the C pieces. |
50 | -> Selector -- ^ Selector that changes behaviour based on completeness. | 49 | -> Selector -- ^ Selector that changes behaviour based on completeness. |
51 | selector start pt ready h a xs = | 50 | selector start pt ready h a xs = |
@@ -60,16 +59,14 @@ data StartegyClass | |||
60 | | SCEnd | 59 | | SCEnd |
61 | deriving (Show, Eq, Ord, Enum, Bounded) | 60 | deriving (Show, Eq, Ord, Enum, Bounded) |
62 | 61 | ||
63 | endThreshold :: PieceThreshold | ||
64 | endThreshold = 1 | ||
65 | 62 | ||
66 | strategyClass :: PieceThreshold -> Bitfield -> StartegyClass | 63 | strategyClass :: Ratio PieceCount -> Bitfield -> StartegyClass |
67 | strategyClass pt = classify . completeness | 64 | strategyClass threshold = classify . completeness |
68 | where | 65 | where |
69 | classify (have, total) | 66 | classify have |
70 | | have < pt = SCBeginning | 67 | | have < threshold = SCBeginning |
71 | | total - have > endThreshold = SCReady | 68 | | have + 1 % numerator have < 1 = SCReady -- FIXME numerator have is not total count |
72 | | otherwise = SCEnd | 69 | | otherwise = SCEnd |
73 | 70 | ||
74 | 71 | ||
75 | -- | Select the first available piece. | 72 | -- | Select the first available piece. |
@@ -82,10 +79,9 @@ strictLast h a _ = findMax (difference a h) | |||
82 | 79 | ||
83 | -- | | 80 | -- | |
84 | rarestFirst :: Selector | 81 | rarestFirst :: Selector |
85 | rarestFirst h a xs = rarest (frequencies (map (intersection want) xs)) | 82 | rarestFirst h a xs = rarest (map (intersection want) xs) |
86 | where | 83 | where |
87 | want = difference h a | 84 | want = difference h a |
88 | rarest = Just . head | ||
89 | 85 | ||
90 | -- | In average random first is faster than rarest first strategy but | 86 | -- | In average random first is faster than rarest first strategy but |
91 | -- only if all pieces are available. | 87 | -- only if all pieces are available. |