From 2749007675a6ff28979fa793b48ffe910635c708 Mon Sep 17 00:00:00 2001 From: Sam Truzjan Date: Sun, 1 Dec 2013 14:32:05 +0400 Subject: Add a few thoughts about piece management --- src/Network/BitTorrent/Exchange/Assembler.hs | 82 ++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/Network/BitTorrent/Exchange/Assembler.hs 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 @@ +module Network.BitTorrent.Exchange.Assembler + ( Assembler + , insert + + -- * Query + , pendingPieces + , completeBlocks + , incompleteBlocks + ) where + +import Data.IntMap.Strict as IM +import Data.Maybe +import Data.Torrent.Piece +import Data.Torrent.Block + +type PieceMap = IntMap + +-- TODO move to Data.Torrent.Piece ? +-- assembler is also a block selector? +data Assembler a = Assembler + { piecePending :: PieceMap [Block a] + , pieceInfo :: PieceInfo + } + + +data Result a + = Assembled (Piece a) + | Failed PieceIx + +-- | You should check if a returned by peer block is actually have +-- been requested and in-flight. This is needed to avoid "I send +-- random corrupted block" attacks. +insert :: Block a -> Assembler a -> (Assembler a, Maybe (Result a)) +insert Block {..} Assembler {..} = undefined +-- updateWithKey bixPiece + +pendingPieces :: Assembler a -> [PieceIx] +pendingPieces Assembler {..} = keys piecePending + +completeBlocks :: Assembler a -> PieceIx -> [Block a] +completeBlocks Assembler {..} pix = fromMaybe [] $ IM.lookup pix piecePending + +incompleteBlocks :: Assembler a -> PieceIx -> [BlockIx] +incompleteBlocks = undefined + +-- TODO merge BlockSelector with Assembler? +data BlockSelector a = BlockSelector + { assembler :: Assembler a -- we do not select already transfered blocks + , inflightSet :: Set BlockIx -- we do not select blocks in flight + } + +insert :: BlockSelector -> (BlockSelector a, Maybe (Result a)) +insert = undefined + + +data StorageAdapter = StorageAdapter + { bitfield :: Bitfield + , requestQ :: Queue PieceIx + } +-- we do select 'incompleteBlocks' that is not in flight + +--assembler :: Assembler -> Conduit (Block a) (Result a) +--assembler = undefined + +-- by priority +-- foreign request queue (max queue size) +-- assembler block information (max queue size) +-- selection strategies (bitfields) + +-- when in flight queue is full we do not use selector +-- in flight queue information (max queue size) + +-- piece select is used when +data PieceSelector = Selector + { forceQueue :: TVar (Queue PieceIx) + , forcePendingQueue :: TVar (Queue PieceIx) + , assembler :: TVar Assembler + , strategy :: Bool + } + +select :: Selector -> (Selector, PieceIx) +select = undefined \ No newline at end of file -- cgit v1.2.3