chunk picker strategies
This commit is contained in:
parent
11dee5870c
commit
bf1fa64973
@ -8,6 +8,104 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
// TODO: move ps to own file
|
||||||
|
// picker strategies are generators
|
||||||
|
// gen returns true if a valid chunk was picked
|
||||||
|
// ps should be light weight and no persistant state
|
||||||
|
// ps produce an index only once
|
||||||
|
|
||||||
|
// simply scans from the beginning, requesting chunks in that order
|
||||||
|
struct PickerStrategySimpleFirst {
|
||||||
|
const BitSet& chunk_candidates;
|
||||||
|
const size_t total_chunks;
|
||||||
|
|
||||||
|
// TODO: optimize simple and start at first chunk we dont have
|
||||||
|
size_t i {0u};
|
||||||
|
|
||||||
|
PickerStrategySimpleFirst(
|
||||||
|
const BitSet& chunk_candidates_,
|
||||||
|
const size_t total_chunks_
|
||||||
|
) :
|
||||||
|
chunk_candidates(chunk_candidates_),
|
||||||
|
total_chunks(total_chunks_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
bool gen(size_t& out_chunk_idx) {
|
||||||
|
for (; i < total_chunks && i < chunk_candidates.size_bits(); i++) {
|
||||||
|
if (chunk_candidates[i]) {
|
||||||
|
out_chunk_idx = i;
|
||||||
|
i++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// chooses a random start position and then requests linearly from there
|
||||||
|
struct PickerStrategyRandom {
|
||||||
|
const BitSet& chunk_candidates;
|
||||||
|
const size_t total_chunks;
|
||||||
|
std::default_random_engine& rng;
|
||||||
|
|
||||||
|
size_t count {0u};
|
||||||
|
size_t i {rng()%total_chunks};
|
||||||
|
|
||||||
|
PickerStrategyRandom(
|
||||||
|
const BitSet& chunk_candidates_,
|
||||||
|
const size_t total_chunks_,
|
||||||
|
std::default_random_engine& rng_
|
||||||
|
) :
|
||||||
|
chunk_candidates(chunk_candidates_),
|
||||||
|
total_chunks(total_chunks_),
|
||||||
|
rng(rng_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool gen(size_t& out_chunk_idx) {
|
||||||
|
for (; count < total_chunks; count++, i++) {
|
||||||
|
// wrap around
|
||||||
|
if (i >= total_chunks) {
|
||||||
|
i = i%total_chunks;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunk_candidates[i]) {
|
||||||
|
out_chunk_idx = i;
|
||||||
|
count++;
|
||||||
|
i++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// switches randomly between random and simple first
|
||||||
|
struct PickerStrategyRandomFirst {
|
||||||
|
PickerStrategyRandom psr;
|
||||||
|
PickerStrategySimpleFirst pssf;
|
||||||
|
|
||||||
|
std::bernoulli_distribution d{0.5f};
|
||||||
|
|
||||||
|
PickerStrategyRandomFirst(
|
||||||
|
const BitSet& chunk_candidates_,
|
||||||
|
const size_t total_chunks_,
|
||||||
|
std::default_random_engine& rng_
|
||||||
|
) :
|
||||||
|
psr(chunk_candidates_, total_chunks_, rng_),
|
||||||
|
pssf(chunk_candidates_, total_chunks_)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool gen(size_t& out_chunk_idx) {
|
||||||
|
if (d(psr.rng)) {
|
||||||
|
return psr.gen(out_chunk_idx);
|
||||||
|
} else {
|
||||||
|
return pssf.gen(out_chunk_idx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void ChunkPicker::updateParticipation(
|
void ChunkPicker::updateParticipation(
|
||||||
Contact3Handle c,
|
Contact3Handle c,
|
||||||
@ -126,7 +224,6 @@ std::vector<ChunkPicker::ContentChunkR> ChunkPicker::updateChunkRequests(
|
|||||||
// TODO: trim off round up to 8, since they are now always set
|
// TODO: trim off round up to 8, since they are now always set
|
||||||
|
|
||||||
// now select (globaly) unrequested other have
|
// now select (globaly) unrequested other have
|
||||||
// TODO: pick strategies
|
|
||||||
// TODO: how do we prioratize within a file?
|
// TODO: how do we prioratize within a file?
|
||||||
// - first (walk from start (or readhead?))
|
// - first (walk from start (or readhead?))
|
||||||
// - random (choose random start pos and walk)
|
// - random (choose random start pos and walk)
|
||||||
@ -135,18 +232,17 @@ std::vector<ChunkPicker::ContentChunkR> ChunkPicker::updateChunkRequests(
|
|||||||
// maybe look into libtorrens deadline stuff
|
// maybe look into libtorrens deadline stuff
|
||||||
// - arbitrary priority maps/functions (and combine with above in rations)
|
// - arbitrary priority maps/functions (and combine with above in rations)
|
||||||
|
|
||||||
// simple, we use first
|
//PickerStrategySimpleFirst ps(chunk_candidates, total_chunks);
|
||||||
// TODO: optimize simple and start at first chunk we dont have
|
//PickerStrategyRandom ps(chunk_candidates, total_chunks, _rng);
|
||||||
for (size_t i = 0; i < total_chunks && req_ret.size() < num_requests && i < chunk_candidates.size_bits(); i++) {
|
// TODO: configurable
|
||||||
if (!chunk_candidates[i]) {
|
PickerStrategyRandomFirst ps(chunk_candidates, total_chunks, _rng);
|
||||||
continue;
|
size_t out_chunk_idx {0};
|
||||||
}
|
while (ps.gen(out_chunk_idx) && req_ret.size() < num_requests) {
|
||||||
|
// out_chunk_idx is a potential candidate we can request form peer
|
||||||
// i is a potential candidate we can request form peer
|
|
||||||
|
|
||||||
// - check against double requests
|
// - check against double requests
|
||||||
if (std::find_if(req_ret.cbegin(), req_ret.cend(), [&](const ContentChunkR& x) -> bool {
|
if (std::find_if(req_ret.cbegin(), req_ret.cend(), [&](const ContentChunkR& x) -> bool {
|
||||||
return x.object == o && x.chunk_index == i;
|
return x.object == o && x.chunk_index == out_chunk_idx;
|
||||||
}) != req_ret.cend()) {
|
}) != req_ret.cend()) {
|
||||||
// already in return array
|
// already in return array
|
||||||
// how did we get here? should we fast exit? if simple-first strat, we would want to
|
// how did we get here? should we fast exit? if simple-first strat, we would want to
|
||||||
@ -154,21 +250,21 @@ std::vector<ChunkPicker::ContentChunkR> ChunkPicker::updateChunkRequests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// - check against global requests (this might differ based on strat)
|
// - check against global requests (this might differ based on strat)
|
||||||
if (requested_chunks.count(i) != 0) {
|
if (requested_chunks.count(out_chunk_idx) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - we check against globally running transfers (this might differ based on strat)
|
// - we check against globally running transfers (this might differ based on strat)
|
||||||
if (rt.containsChunk(o, i)) {
|
if (rt.containsChunk(o, out_chunk_idx)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if nothing else blocks this, add to ret
|
// if nothing else blocks this, add to ret
|
||||||
req_ret.push_back(ContentChunkR{o, i});
|
req_ret.push_back(ContentChunkR{o, out_chunk_idx});
|
||||||
|
|
||||||
// TODO: move this after packet was sent successfully
|
// TODO: move this after packet was sent successfully
|
||||||
// (move net in? hmm)
|
// (move net in? hmm)
|
||||||
requested_chunks[i] = Components::FT1ChunkSHA1Requested::Entry{0.f, c};
|
requested_chunks[out_chunk_idx] = Components::FT1ChunkSHA1Requested::Entry{0.f, c};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <random>
|
||||||
|
|
||||||
//#include <solanaceae/ngc_ft1/ngcft1.hpp>
|
//#include <solanaceae/ngc_ft1/ngcft1.hpp>
|
||||||
|
|
||||||
@ -24,6 +25,8 @@ struct ChunkPicker {
|
|||||||
static constexpr size_t max_tf_info_requests {1};
|
static constexpr size_t max_tf_info_requests {1};
|
||||||
static constexpr size_t max_tf_chunk_requests {3};
|
static constexpr size_t max_tf_chunk_requests {3};
|
||||||
|
|
||||||
|
std::default_random_engine _rng{1337*17};
|
||||||
|
|
||||||
//// max outstanding requests
|
//// max outstanding requests
|
||||||
//// TODO: should this include transfers?
|
//// TODO: should this include transfers?
|
||||||
//static constexpr size_t max_open_info_requests {1};
|
//static constexpr size_t max_open_info_requests {1};
|
||||||
|
Loading…
Reference in New Issue
Block a user