Use Linux-like indentation in mptp.c
[swifty.git] / src / libswift_udp / ext / seq_picker.cpp
1 /*
2  *  seq_picker.cpp
3  *  swift
4  *
5  *  Created by Victor Grishchenko on 10/6/09.
6  *  Copyright 2009-2012 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     binmap_t        ack_hint_out_;
21     tbqueue         hint_out_;
22     FileTransfer*   transfer_;
23     uint64_t        twist_;
24     bin_t           range_;
25
26 public:
27
28     SeqPiecePicker (FileTransfer* file_to_pick_from) : ack_hint_out_(),
29            transfer_(file_to_pick_from), twist_(0), range_(bin_t::ALL) {
30         binmap_t::copy(ack_hint_out_, file().ack_out());
31     }
32     virtual ~SeqPiecePicker() {}
33
34     HashTree& file() {
35         return transfer_->file();
36     }
37
38     virtual void Randomize (uint64_t twist) {
39         twist_ = twist;
40     }
41
42     virtual void LimitRange (bin_t range) {
43         range_ = range;
44     }
45
46     virtual bin_t Pick (binmap_t& offer, uint64_t max_width, tint expires) {
47         while (hint_out_.size() && hint_out_.front().time<NOW-TINT_SEC*3/2) { // FIXME sec
48             binmap_t::copy(ack_hint_out_, file().ack_out(), hint_out_.front().bin);
49             hint_out_.pop_front();
50         }
51         if (!file().size()) {
52             return bin_t(0,0); // whoever sends it first
53         // Arno, 2011-06-28: Partial fix by Victor. exact_size_known() missing
54         //} else if (!file().exact_size_known()) {
55         //    return bin64_t(0,(file().size()>>10)-1); // dirty
56         }
57     retry:      // bite me
58         twist_ &= (file().peak(0).toUInt()) & ((1<<6)-1);
59
60         bin_t hint = binmap_t::find_complement(ack_hint_out_, offer, twist_);
61         if (hint.is_none()) {
62             return hint; // TODO: end-game mode
63         }
64
65         if (!file().ack_out().is_empty(hint)) { // unhinted/late data
66             binmap_t::copy(ack_hint_out_, file().ack_out(), hint);
67             goto retry;
68         }
69         while (hint.base_length()>max_width)
70             hint = hint.left();
71         assert(ack_hint_out_.is_empty(hint));
72         ack_hint_out_.set(hint);
73         hint_out_.push_back(tintbin(NOW,hint));
74         return hint;
75     }
76
77     void updatePlaybackPos(int size = 1)
78     {
79         return;
80     }
81
82 };