1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-28 01:35:32 +00:00
elinks/src/protocol/bittorrent/piececache.h

137 lines
5.4 KiB
C
Raw Permalink Normal View History

#ifndef EL__PROTOCOL_BITTORRENT_PIECECACHE_H
#define EL__PROTOCOL_BITTORRENT_PIECECACHE_H
#include "protocol/bittorrent/common.h"
#include "util/lists.h"
#ifdef __cplusplus
extern "C" {
#endif
struct bitfield;
struct bittorrent_piece_cache_entry {
LIST_HEAD_EL(struct bittorrent_piece_cache_entry);
/** Piece rarity index
* To keep track of the client's view of the swarm in regards to pieces a
* piece rarity index for neighboring peers is maintained for each piece
* in the torrent. It keeps track of how many neighboring peers have the
* piece. The smaller the value the more rare the piece is. The table is
* updated when the client receives bitfield or have messages. Zero
* indicates that no neightboring peer has the piece. */
uint16_t rarity;
unsigned int completed:1; /**< All blocks was downloaded. */
unsigned int remaining:1; /**< Nothing has been even requested. */
unsigned int locked:1; /**< Edge piece from partial downloads. */
unsigned int selected:1; /**< Piece is part of partial download. */
/** A bitfield of the blocks which remains to be downloaded for this
* piece. May be NULL if downloading is not in progress. */
struct bitfield *blocks;
/** The data of the piece.
* May be NULL if data has not been downloaded
* or the piece has been written to disk.
* XXX: This memory is mmaped using the mem_mmap_*() functions. */
char *data;
};
struct bittorrent_piece_cache {
/* The following is mostly maintained for making it easy to display in
* dialogs. */
unsigned int remaining_pieces; /**< Number of untouched pieces */
unsigned int completed_pieces; /**< Number of downloaded pieces */
unsigned int loading_pieces; /**< Number of pieces in progress */
unsigned int rejected_pieces; /**< Number of hash check rejects */
unsigned int unavailable_pieces;/**< Number of unavailable pieces */
unsigned int partial_pieces; /**< Number of selected file pieces */
unsigned int locked_pieces; /**< Pieces locked due to partial download */
/* Flags set from the download dialog. */
unsigned int delete_files:1; /**< Unlink files on shutdown? */
unsigned int notify_complete:1; /**< Notify upon completion? */
unsigned int partial:1; /**< Dealing with a partial download? */
/** The pipe descripter used for communicating with the resume thread. */
int resume_fd;
uint32_t resume_pos;
/** A bitfield of the available pieces. */
struct bitfield *bitfield;
/** A list of completed and saved entries which has been loaded into
* memory. The allocated memory for all these entries is disposable. The
* entries are sorted in a LRU-manner. */
LIST_OF(struct bittorrent_piece_cache_entry) queue;
/** Remaining pieces are tracked using the remaining_blocks member of the
* piece cache entry and a free list of piece blocks to be requested.
* Requests are taken from the free list every time a peer queries which
* piece block to request next. If the piece list is empty (or if the
* remote peer does not have any of the pieces currently in the free
* list) the cache is searched for a remaining piece and any found piece
* is then broken into a number of requests. Typically, the querying
* peer will only add a few of the requests to its queue so the rest of
* the requests will end up in the free list. This way more than one
* peer can request blocks from the same piece and the overall strategy
* will try to finish already started pieces before it begins
* downloading of new ones.
*
* When the free list is empty _and_ the number of remaining pieces is
* zero the client enters the end game mode. That is, _all_ remaining
* requests are _pending_. To speed up the end game mode, more than one
* peer is allowed to request the same piece, however, it is important
* to cancel these requests when they are completed to not waste
* bandwitdth. To ease canceling in end game mode peer requests has a
* cloned flag. The flag is set when piece block requests are cloned. If
* the cloned flag is set when receiving a block then the peer-list is
* searched and requests for the same piece is canceled. */
LIST_OF(struct bittorrent_piece_request) free_list;
struct bittorrent_piece_cache_entry entries[1];
};
enum bittorrent_state
init_bittorrent_piece_cache(struct bittorrent_connection *bittorrent,
struct bittorrent_const_string *metafile);
void done_bittorrent_piece_cache(struct bittorrent_connection *bittorrent);
void update_bittorrent_piece_cache_state(struct bittorrent_connection *bittorrent);
/* Depending on the current download mode, try to find a block to request. */
struct bittorrent_peer_request *
find_bittorrent_peer_request(struct bittorrent_peer_connection *peer);
void
add_requests_to_bittorrent_piece_cache(struct bittorrent_peer_connection *peer,
struct bittorrent_peer_status *status);
void
update_bittorrent_piece_cache(struct bittorrent_peer_connection *peer,
uint32_t piece);
void
update_bittorrent_piece_cache_from_bitfield(struct bittorrent_peer_connection *peer);
void
remove_bittorrent_peer_from_piece_cache(struct bittorrent_peer_connection *peer);
enum bittorrent_state
add_to_bittorrent_piece_cache(struct bittorrent_peer_connection *peer,
uint32_t piece, uint32_t offset,
char *data, uint32_t datalen,
int *write_errno);
char *
get_bittorrent_piece_cache_data(struct bittorrent_connection *bittorrent,
uint32_t piece);
#ifdef __cplusplus
}
#endif
#endif