summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-12-05 04:22:32 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-12-05 04:22:32 +0400
commit36d3f9b1d3e536035a02bf0afd33c2f0efa6e892 (patch)
tree5f24d419e9b6dfbccfb2557124b698a4ed2e0327
parent74df228e2d8cbe27049f65a70253a59e67c7acc0 (diff)
Move piece selection algorithms to separate module
-rw-r--r--bittorrent.cabal7
-rw-r--r--src/Data/Torrent/Bitfield.hs72
-rw-r--r--src/Network/BitTorrent/Exchange/Selection.hs85
3 files changed, 90 insertions, 74 deletions
diff --git a/bittorrent.cabal b/bittorrent.cabal
index e4dbd626..5bca228c 100644
--- a/bittorrent.cabal
+++ b/bittorrent.cabal
@@ -42,7 +42,7 @@ library
42 , RecordWildCards 42 , RecordWildCards
43 hs-source-dirs: src 43 hs-source-dirs: src
44 exposed-modules: Data.Torrent 44 exposed-modules: Data.Torrent
45-- Data.Torrent.Bitfield 45 Data.Torrent.Bitfield
46 Data.Torrent.Client 46 Data.Torrent.Client
47 Data.Torrent.InfoHash 47 Data.Torrent.InfoHash
48 Data.Torrent.Layout 48 Data.Torrent.Layout
@@ -62,12 +62,13 @@ library
62-- Network.BitTorrent.Exchange.Assembler 62-- Network.BitTorrent.Exchange.Assembler
63 Network.BitTorrent.Exchange.Block 63 Network.BitTorrent.Exchange.Block
64 Network.BitTorrent.Exchange.Message 64 Network.BitTorrent.Exchange.Message
65 Network.BitTorrent.Exchange.Selection
65-- Network.BitTorrent.Exchange.Session 66-- Network.BitTorrent.Exchange.Session
66 Network.BitTorrent.Exchange.Status 67 Network.BitTorrent.Exchange.Status
67-- Network.BitTorrent.Exchange.Wire 68 Network.BitTorrent.Exchange.Wire
68-- Network.BitTorrent.Tracker 69-- Network.BitTorrent.Tracker
69-- Network.BitTorrent.Tracker.RPC
70 Network.BitTorrent.Tracker.Message 70 Network.BitTorrent.Tracker.Message
71-- Network.BitTorrent.Tracker.RPC
71 Network.BitTorrent.Tracker.RPC.HTTP 72 Network.BitTorrent.Tracker.RPC.HTTP
72 Network.BitTorrent.Tracker.RPC.UDP 73 Network.BitTorrent.Tracker.RPC.UDP
73 Network.BitTorrent.Tracker.Wai 74 Network.BitTorrent.Tracker.Wai
diff --git a/src/Data/Torrent/Bitfield.hs b/src/Data/Torrent/Bitfield.hs
index c7ef0998..17278a2c 100644
--- a/src/Data/Torrent/Bitfield.hs
+++ b/src/Data/Torrent/Bitfield.hs
@@ -55,13 +55,6 @@ module Data.Torrent.Bitfield
55 , fromBitmap, toBitmap 55 , fromBitmap, toBitmap
56 , toList 56 , toList
57 57
58 -- * Selection
59 , Selector
60 , selector, strategyClass
61
62 , strictFirst, strictLast
63 , rarestFirst, randomFirst, endGame
64
65#if defined (TESTING) 58#if defined (TESTING)
66 -- * Debug 59 -- * Debug
67 , mkBitfield 60 , mkBitfield
@@ -78,7 +71,7 @@ import qualified Data.Vector.Unboxed as V
78import qualified Data.Vector.Unboxed.Mutable as VM 71import qualified Data.Vector.Unboxed.Mutable as VM
79import Data.IntervalSet (IntSet) 72import Data.IntervalSet (IntSet)
80import qualified Data.IntervalSet as S 73import qualified Data.IntervalSet as S
81import qualified Data.IntervalSet.ByteString as S 74import qualified Data.IntervalSet.ByteString as S
82import Data.List (foldl') 75import Data.List (foldl')
83import Data.Monoid 76import Data.Monoid
84import Data.Ratio 77import Data.Ratio
@@ -289,66 +282,3 @@ mkBitfield s ixs = Bitfield {
289 bfSize = s 282 bfSize = s
290 , bfSet = S.splitGT (-1) $ S.splitLT s $ S.fromList ixs 283 , bfSet = S.splitGT (-1) $ S.splitLT s $ S.fromList ixs
291 } 284 }
292
293{-----------------------------------------------------------------------
294 Selection
295-----------------------------------------------------------------------}
296
297type Selector = Bitfield -- ^ Indices of client /have/ pieces.
298 -> Bitfield -- ^ Indices of peer /have/ pieces.
299 -> [Bitfield] -- ^ Indices of other peers /have/ pieces.
300 -> Maybe PieceIx -- ^ Zero-based index of piece to request
301 -- to, if any.
302
303selector :: Selector -- ^ Selector to use at the start.
304 -> Ratio PieceCount
305 -> Selector -- ^ Selector to use after the client have
306 -- the C pieces.
307 -> Selector -- ^ Selector that changes behaviour based
308 -- on completeness.
309selector start pt ready h a xs =
310 case strategyClass pt h of
311 SCBeginning -> start h a xs
312 SCReady -> ready h a xs
313 SCEnd -> endGame h a xs
314
315data StartegyClass
316 = SCBeginning
317 | SCReady
318 | SCEnd
319 deriving (Show, Eq, Ord, Enum, Bounded)
320
321
322strategyClass :: Ratio PieceCount -> Bitfield -> StartegyClass
323strategyClass threshold = classify . completeness
324 where
325 classify c
326 | c < threshold = SCBeginning
327 | c + 1 % numerator c < 1 = SCReady
328 -- FIXME numerator have is not total count
329 | otherwise = SCEnd
330
331
332-- | Select the first available piece.
333strictFirst :: Selector
334strictFirst h a _ = Just $ findMin (difference a h)
335
336-- | Select the last available piece.
337strictLast :: Selector
338strictLast h a _ = Just $ findMax (difference a h)
339
340-- |
341rarestFirst :: Selector
342rarestFirst h a xs = rarest (map (intersection want) xs)
343 where
344 want = difference h a
345
346-- | In average random first is faster than rarest first strategy but
347-- only if all pieces are available.
348randomFirst :: Selector
349randomFirst = do
350-- randomIO
351 error "randomFirst"
352
353endGame :: Selector
354endGame = strictLast
diff --git a/src/Network/BitTorrent/Exchange/Selection.hs b/src/Network/BitTorrent/Exchange/Selection.hs
new file mode 100644
index 00000000..2724fabc
--- /dev/null
+++ b/src/Network/BitTorrent/Exchange/Selection.hs
@@ -0,0 +1,85 @@
1-- |
2-- Copyright : (c) Sam Truzjan 2013
3-- License : BSD3
4-- Maintainer : pxqr.sta@gmail.com
5-- Stability : experimental
6-- Portability : portable
7--
8-- Piece selection algorithms.
9--
10module Network.BitTorrent.Exchange.Selection
11 ( -- * Selection
12 Selector
13 , selector
14 , strategyClass
15
16 , strictFirst
17 , strictLast
18 , rarestFirst
19 , randomFirst
20 , endGame
21 ) where
22
23import Data.Ratio
24
25import Data.Torrent.Bitfield
26
27
28type Selector = Bitfield -- ^ Indices of client /have/ pieces.
29 -> Bitfield -- ^ Indices of peer /have/ pieces.
30 -> [Bitfield] -- ^ Indices of other peers /have/ pieces.
31 -> Maybe PieceIx -- ^ Zero-based index of piece to request
32 -- to, if any.
33
34selector :: Selector -- ^ Selector to use at the start.
35 -> Ratio PieceCount
36 -> Selector -- ^ Selector to use after the client have
37 -- the C pieces.
38 -> Selector -- ^ Selector that changes behaviour based
39 -- on completeness.
40selector start pt ready h a xs =
41 case strategyClass pt h of
42 SCBeginning -> start h a xs
43 SCReady -> ready h a xs
44 SCEnd -> endGame h a xs
45
46data StartegyClass
47 = SCBeginning
48 | SCReady
49 | SCEnd
50 deriving (Show, Eq, Ord, Enum, Bounded)
51
52
53strategyClass :: Ratio PieceCount -> Bitfield -> StartegyClass
54strategyClass threshold = classify . completeness
55 where
56 classify c
57 | c < threshold = SCBeginning
58 | c + 1 % numerator c < 1 = SCReady
59 -- FIXME numerator have is not total count
60 | otherwise = SCEnd
61
62
63-- | Select the first available piece.
64strictFirst :: Selector
65strictFirst h a _ = Just $ findMin (difference a h)
66
67-- | Select the last available piece.
68strictLast :: Selector
69strictLast h a _ = Just $ findMax (difference a h)
70
71-- |
72rarestFirst :: Selector
73rarestFirst h a xs = rarest (map (intersection want) xs)
74 where
75 want = difference h a
76
77-- | In average random first is faster than rarest first strategy but
78-- only if all pieces are available.
79randomFirst :: Selector
80randomFirst = do
81-- randomIO
82 error "randomFirst"
83
84endGame :: Selector
85endGame = strictLast