summaryrefslogtreecommitdiff
path: root/src/Network
diff options
context:
space:
mode:
authorSam T <pxqr.sta@gmail.com>2013-06-02 05:01:46 +0400
committerSam T <pxqr.sta@gmail.com>2013-06-02 05:01:46 +0400
commit01f51b51af8a67516238bc7264079601a7e2ece5 (patch)
tree13b346ad0ba930e7d964a3de9988365f6cc6ba4f /src/Network
parent5e92eec501e0a1ca6d09a01e078cf54ff3277273 (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.hs18
-rw-r--r--src/Network/BitTorrent/PeerWire/Selection.hs22
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
35import Data.Bitfield 35import Data.Bitfield
36import Data.Ratio
36import Network.BitTorrent.PeerWire.Block 37import 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
45type PieceThreshold = Int
46
47selector :: Selector -- ^ Selector to use at the start. 46selector :: 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.
51selector start pt ready h a xs = 50selector 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
63endThreshold :: PieceThreshold
64endThreshold = 1
65 62
66strategyClass :: PieceThreshold -> Bitfield -> StartegyClass 63strategyClass :: Ratio PieceCount -> Bitfield -> StartegyClass
67strategyClass pt = classify . completeness 64strategyClass 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-- |
84rarestFirst :: Selector 81rarestFirst :: Selector
85rarestFirst h a xs = rarest (frequencies (map (intersection want) xs)) 82rarestFirst 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.