summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Truzjan <pxqr.sta@gmail.com>2013-12-01 14:32:05 +0400
committerSam Truzjan <pxqr.sta@gmail.com>2013-12-01 14:32:05 +0400
commit2749007675a6ff28979fa793b48ffe910635c708 (patch)
treee699029a71f9ce3f74c7ca7bd5372c1778553e78
parentfe12e76da86b514ae5725fb8eaec7821c0376558 (diff)
Add a few thoughts about piece management
-rw-r--r--src/Network/BitTorrent/Exchange/Assembler.hs82
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 @@
1module Network.BitTorrent.Exchange.Assembler
2 ( Assembler
3 , insert
4
5 -- * Query
6 , pendingPieces
7 , completeBlocks
8 , incompleteBlocks
9 ) where
10
11import Data.IntMap.Strict as IM
12import Data.Maybe
13import Data.Torrent.Piece
14import Data.Torrent.Block
15
16type PieceMap = IntMap
17
18-- TODO move to Data.Torrent.Piece ?
19-- assembler is also a block selector?
20data Assembler a = Assembler
21 { piecePending :: PieceMap [Block a]
22 , pieceInfo :: PieceInfo
23 }
24
25
26data 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.
33insert :: Block a -> Assembler a -> (Assembler a, Maybe (Result a))
34insert Block {..} Assembler {..} = undefined
35-- updateWithKey bixPiece
36
37pendingPieces :: Assembler a -> [PieceIx]
38pendingPieces Assembler {..} = keys piecePending
39
40completeBlocks :: Assembler a -> PieceIx -> [Block a]
41completeBlocks Assembler {..} pix = fromMaybe [] $ IM.lookup pix piecePending
42
43incompleteBlocks :: Assembler a -> PieceIx -> [BlockIx]
44incompleteBlocks = undefined
45
46-- TODO merge BlockSelector with Assembler?
47data 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
52insert :: BlockSelector -> (BlockSelector a, Maybe (Result a))
53insert = undefined
54
55
56data 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
74data PieceSelector = Selector
75 { forceQueue :: TVar (Queue PieceIx)
76 , forcePendingQueue :: TVar (Queue PieceIx)
77 , assembler :: TVar Assembler
78 , strategy :: Bool
79 }
80
81select :: Selector -> (Selector, PieceIx)
82select = undefined \ No newline at end of file