diff options
author | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-01 14:32:05 +0400 |
---|---|---|
committer | Sam Truzjan <pxqr.sta@gmail.com> | 2013-12-01 14:32:05 +0400 |
commit | 2749007675a6ff28979fa793b48ffe910635c708 (patch) | |
tree | e699029a71f9ce3f74c7ca7bd5372c1778553e78 /src/Network/BitTorrent/Exchange | |
parent | fe12e76da86b514ae5725fb8eaec7821c0376558 (diff) |
Add a few thoughts about piece management
Diffstat (limited to 'src/Network/BitTorrent/Exchange')
-rw-r--r-- | src/Network/BitTorrent/Exchange/Assembler.hs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/Network/BitTorrent/Exchange/Assembler.hs b/src/Network/BitTorrent/Exchange/Assembler.hs new file mode 100644 index 00000000..a490d2dc --- /dev/null +++ b/src/Network/BitTorrent/Exchange/Assembler.hs | |||
@@ -0,0 +1,82 @@ | |||
1 | module Network.BitTorrent.Exchange.Assembler | ||
2 | ( Assembler | ||
3 | , insert | ||
4 | |||
5 | -- * Query | ||
6 | , pendingPieces | ||
7 | , completeBlocks | ||
8 | , incompleteBlocks | ||
9 | ) where | ||
10 | |||
11 | import Data.IntMap.Strict as IM | ||
12 | import Data.Maybe | ||
13 | import Data.Torrent.Piece | ||
14 | import Data.Torrent.Block | ||
15 | |||
16 | type PieceMap = IntMap | ||
17 | |||
18 | -- TODO move to Data.Torrent.Piece ? | ||
19 | -- assembler is also a block selector? | ||
20 | data Assembler a = Assembler | ||
21 | { piecePending :: PieceMap [Block a] | ||
22 | , pieceInfo :: PieceInfo | ||
23 | } | ||
24 | |||
25 | |||
26 | data Result a | ||
27 | = Assembled (Piece a) | ||
28 | | Failed PieceIx | ||
29 | |||
30 | -- | You should check if a returned by peer block is actually have | ||
31 | -- been requested and in-flight. This is needed to avoid "I send | ||
32 | -- random corrupted block" attacks. | ||
33 | insert :: Block a -> Assembler a -> (Assembler a, Maybe (Result a)) | ||
34 | insert Block {..} Assembler {..} = undefined | ||
35 | -- updateWithKey bixPiece | ||
36 | |||
37 | pendingPieces :: Assembler a -> [PieceIx] | ||
38 | pendingPieces Assembler {..} = keys piecePending | ||
39 | |||
40 | completeBlocks :: Assembler a -> PieceIx -> [Block a] | ||
41 | completeBlocks Assembler {..} pix = fromMaybe [] $ IM.lookup pix piecePending | ||
42 | |||
43 | incompleteBlocks :: Assembler a -> PieceIx -> [BlockIx] | ||
44 | incompleteBlocks = undefined | ||
45 | |||
46 | -- TODO merge BlockSelector with Assembler? | ||
47 | data BlockSelector a = BlockSelector | ||
48 | { assembler :: Assembler a -- we do not select already transfered blocks | ||
49 | , inflightSet :: Set BlockIx -- we do not select blocks in flight | ||
50 | } | ||
51 | |||
52 | insert :: BlockSelector -> (BlockSelector a, Maybe (Result a)) | ||
53 | insert = undefined | ||
54 | |||
55 | |||
56 | data StorageAdapter = StorageAdapter | ||
57 | { bitfield :: Bitfield | ||
58 | , requestQ :: Queue PieceIx | ||
59 | } | ||
60 | -- we do select 'incompleteBlocks' that is not in flight | ||
61 | |||
62 | --assembler :: Assembler -> Conduit (Block a) (Result a) | ||
63 | --assembler = undefined | ||
64 | |||
65 | -- by priority | ||
66 | -- foreign request queue (max queue size) | ||
67 | -- assembler block information (max queue size) | ||
68 | -- selection strategies (bitfields) | ||
69 | |||
70 | -- when in flight queue is full we do not use selector | ||
71 | -- in flight queue information (max queue size) | ||
72 | |||
73 | -- piece select is used when | ||
74 | data PieceSelector = Selector | ||
75 | { forceQueue :: TVar (Queue PieceIx) | ||
76 | , forcePendingQueue :: TVar (Queue PieceIx) | ||
77 | , assembler :: TVar Assembler | ||
78 | , strategy :: Bool | ||
79 | } | ||
80 | |||
81 | select :: Selector -> (Selector, PieceIx) | ||
82 | select = undefined \ No newline at end of file | ||