1 /* 2 * seq_picker.cpp 3 * swift 4 * 5 * Created by Victor Grishchenko on 10/6/09. 6 * Copyright 2009-2016 TECHNISCHE UNIVERSITEIT DELFT. All rights reserved. 7 * 8 */ 9 10 #include "swift.h" 11 #include <cassert> 12 13 using namespace swift; 14 15 16 /** Picks pieces nearly sequentialy; some local randomization (twisting) 17 is introduced to prevent synchronization among multiple channels. */ 18 class SeqPiecePicker : public PiecePicker 19 { 20 21 binmap_t ack_hint_out_; 22 tbqueue hint_out_; 23 FileTransfer* transfer_; 24 uint64_t twist_; 25 bin_t range_; 26 27 public: 28 SeqPiecePicker(FileTransfer * file_to_pick_from)29 SeqPiecePicker(FileTransfer* file_to_pick_from) : ack_hint_out_(), 30 transfer_(file_to_pick_from), twist_(0), range_(bin_t::ALL) { 31 binmap_t::copy(ack_hint_out_, *(hashtree()->ack_out())); 32 } ~SeqPiecePicker()33 virtual ~SeqPiecePicker() {} 34 hashtree()35 HashTree * hashtree() { 36 return transfer_->hashtree(); 37 } 38 Randomize(uint64_t twist)39 virtual void Randomize(uint64_t twist) { 40 twist_ = twist; 41 } 42 LimitRange(bin_t range)43 virtual void LimitRange(bin_t range) { 44 range_ = range; 45 } 46 Pick(binmap_t & offer,uint64_t max_width,tint expires,uint32_t channelid)47 virtual bin_t Pick(binmap_t& offer, uint64_t max_width, tint expires, uint32_t channelid) { 48 while (hint_out_.size() && hint_out_.front().time<NOW-TINT_SEC*PICKER_TIMEOUT) { // FIXME sec 49 binmap_t::copy(ack_hint_out_, *(hashtree()->ack_out()), hint_out_.front().bin); 50 hint_out_.pop_front(); 51 } 52 if (!hashtree()->size()) { 53 return bin_t(0,0); // whoever sends it first 54 // Arno, 2011-06-28: Partial fix by Victor. exact_size_known() missing 55 //} else if (!hashtree()->exact_size_known()) { 56 // return bin64_t(0,(hashtree()->size()>>10)-1); // dirty 57 } 58 retry: // bite me 59 twist_ &= (hashtree()->peak(0).toUInt()) & ((1<<6)-1); 60 61 bin_t hint = binmap_t::find_complement(ack_hint_out_, offer, twist_); 62 63 if (hint.is_none()) { 64 return hint; // TODO: end-game mode 65 } 66 67 if (!hashtree()->ack_out()->is_empty(hint)) { // unhinted/late data 68 binmap_t::copy(ack_hint_out_, *(hashtree()->ack_out()), hint); 69 goto retry; 70 } 71 while (hint.base_length()>max_width) 72 hint = hint.left(); 73 assert(ack_hint_out_.is_empty(hint)); 74 ack_hint_out_.set(hint); 75 hint_out_.push_back(tintbin(NOW,hint)); 76 return hint; 77 } 78 Seek(bin_t offbin,int whence)79 int Seek(bin_t offbin, int whence) { 80 return -1; 81 } 82 }; 83