else
return right();
}
+
+ bin64_t twisted (uint64_t mask) const {
+ return bin64_t( v ^ ((mask<<1)&~tail_bits()) );
+ }
bin64_t parent () const {
uint64_t tbs = tail_bits(), ntbs = (tbs+1)|tbs;
bins ack_hint_out_;
FileTransfer* file_;
+ uint64_t twist_;
public:
- SeqPiecePicker (FileTransfer* file_to_pick_from) : file_(file_to_pick_from), ack_hint_out_() {
+ SeqPiecePicker (FileTransfer* file_to_pick_from) :
+ file_(file_to_pick_from), ack_hint_out_(), twist_(0) {
ack_hint_out_.copy_range(file_->ack_out(),bin64_t::ALL);
}
+ virtual void Randomize (uint64_t twist) {
+ twist_ = twist;
+ }
+
virtual bin64_t Pick (bins& offer, uint8_t layer) {
-
+ if (twist_) {
+ offer.twist(twist_);
+ ack_hint_out_.twist(twist_);
+ }
bin64_t hint = offer.find_filtered
- (ack_hint_out_,bin64_t::ALL,layer,bins::FILLED);
+ (ack_hint_out_,bin64_t::ALL,layer,bins::FILLED);
+ if (twist_) {
+ hint = hint.twisted(twist_);
+ //dprintf("found twisted by %lli fixed to (%i,%lli)\n",
+ // twist_,hint.layer(),hint.offset());
+ offer.twist(0);
+ ack_hint_out_.twist(0);
+ }
if (hint==bin64_t::NONE)
return hint; // TODO: end-game mode
while (hint.layer()>layer)
class PiecePicker {
public:
+ virtual void Randomize (uint64_t twist) = 0;
virtual bin64_t Pick (bins& offered, uint8_t layer) = 0;
virtual void Expired (bin64_t b) = 0;
virtual void Received (bin64_t b) = 0;
b.twist(1<<3);
EXPECT_EQ(bins::FILLED,b.get(bin64_t(3,3)));
EXPECT_EQ(bins::EMPTY,b.get(bin64_t(3,2)));
+ bin64_t tw = b.find(bin64_t(5,0),3,bins::FILLED);
+ tw = tw.twisted(1<<3);
+ EXPECT_EQ(bin64_t(3,2),tw);
b.twist(0);
EXPECT_EQ(bins::FILLED,b.get(bin64_t(3,2)));
EXPECT_EQ(bins::EMPTY,b.get(bin64_t(3,3)));
unlink("copy");
FileTransfer::instance = 1;
FileTransfer* leech = new FileTransfer("copy",seed->root_hash());
+ leech->picker().Randomize(0);
// transfer peak hashes
for(int i=0; i<seed->peak_count(); i++)
leech->OfferHash(seed->peak(i),seed->peak_hash(i));
delete leech;
FileTransfer::instance = 1;
leech = new FileTransfer("copy",seed->root_hash());
+ leech->picker().Randomize(0);
EXPECT_EQ(2,leech->complete_kilo());
}
bin64_t next = leech->picker().Pick(seed->ack_out(),0);
else
RecoverProgress();
picker_ = new SeqPiecePicker(this);
+ picker_->Randomize(Datagram::Time()&7);
}