00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #ifndef ns_media_app_h
00061 #define ns_media_app_h
00062
00063 #include <stdlib.h>
00064 #include <tcl.h>
00065 #include "config.h"
00066 #include "agent.h"
00067 #include "app.h"
00068 #include "webcache/http-aux.h"
00069 #include "rap/rap.h"
00070 #include "rap/utilities.h"
00071
00072
00073 class HttpMediaData;
00074
00075
00076 class MediaSegment : public DoubleListElem {
00077 public:
00078 MediaSegment() : start_(0), end_(0), flags_(0) {}
00079 MediaSegment(int start, int end) : start_(start),end_(end),flags_(0) {}
00080 MediaSegment(const HttpMediaData& d);
00081 MediaSegment(const MediaSegment& s) {
00082
00083 start_ = s.start_;
00084 end_ = s.end_;
00085 flags_ = s.flags_;
00086 }
00087
00088 int start() const { return start_; }
00089 int end() const { return end_; }
00090 int datasize() const { return end_ - start_; }
00091 MediaSegment* next() const {
00092 return (MediaSegment *)DoubleListElem::next();
00093 }
00094 MediaSegment* prev() const {
00095 return (MediaSegment *)DoubleListElem::prev();
00096 }
00097
00098 void set_start(int d) { start_ = d; }
00099 void set_end(int d) { end_ = d; }
00100 void set_datasize(int d) { end_ = start_ + d; }
00101
00102 void advance(int size) { start_ += size, end_ = start_ + size; }
00103
00104 int in(const MediaSegment& s) const {
00105 return ((start_ >= s.start_) && (end_ <= s.end_));
00106 }
00107 int before(const MediaSegment& s) const {
00108 return (end_ <= s.start_);
00109 }
00110 int overlap(const MediaSegment& s) const {
00111 assert(s.start_ <= s.end_);
00112 return ((s.end_ >= start_) && (s.start_ <= end_));
00113 }
00114
00115 int merge(const MediaSegment& s) {
00116 if ((s.end_ < start_) || (s.start_ > end_))
00117
00118 return 0;
00119 int size = datasize() + s.datasize();
00120 if (s.start_ < start_) start_ = s.start_;
00121 if (s.end_ > end_) end_ = s.end_;
00122 assert(size >= datasize());
00123 return (size - datasize());
00124 }
00125
00126 int evict_tail(int sz) {
00127
00128 #ifdef MCACHE_DEBUG
00129 fprintf(stderr, "evicted (%d, %d) ", end_-sz, end_);
00130 #endif
00131 if (datasize() >= sz)
00132 end_ -= sz;
00133 else {
00134 sz = datasize();
00135 end_ = start_;
00136 }
00137 return sz;
00138 }
00139
00140 int evict_head(int sz) {
00141
00142 if (datasize() >= sz)
00143 start_ += sz;
00144 else {
00145 sz = datasize();
00146 end_ = start_;
00147 }
00148 return sz;
00149 }
00150 int is_empty() const { return end_ == start_; }
00151
00152
00153 enum { MS_LAST = 1, MS_PREF = 2 };
00154 int is_last() const { return (flags_ & MS_LAST); }
00155 void set_last() { flags_ |= MS_LAST; }
00156 int is_pref() const { return (flags_ & MS_PREF); }
00157 void set_pref() { flags_ |= MS_PREF; }
00158
00159 private:
00160 int start_;
00161 int end_;
00162 int flags_;
00163 };
00164
00165
00166 class MediaSegmentList : public DoubleList {
00167 public:
00168 MediaSegmentList() : DoubleList(), length_(0) {}
00169
00170 int length() const { return length_; }
00171 void add(const MediaSegment& s);
00172 int in(const MediaSegment& s);
00173 MediaSegment get_nextseg(const MediaSegment& s);
00174 int evict_tail(int size);
00175 int evict_head(int size);
00176 int evict_head_offset(int offset);
00177 int overlap_size(const MediaSegment& s) const;
00178 MediaSegmentList check_holes(const MediaSegment& s);
00179
00180 char* dump2buf();
00181 virtual void destroy() {
00182 DoubleList::destroy();
00183 length_ = 0;
00184 }
00185
00186
00187 void print(void);
00188 int getsize();
00189 void check_integrity();
00190
00191 protected:
00192 void merge_seg(MediaSegment* seg);
00193
00194 private:
00195 int length_;
00196 };
00197
00198
00199
00200 class HttpMediaData : public HttpData {
00201 private:
00202 char page_[HTTP_MAXURLLEN];
00203 char sender_[HTTP_MAXURLLEN];
00204 int layer_;
00205 int st_;
00206 int et_;
00207 int flags_;
00208 Application* conid_;
00209 public:
00210 struct hdr {
00211 char sender_[HTTP_MAXURLLEN];
00212 char page_[HTTP_MAXURLLEN];
00213 int layer_;
00214 int st_, et_;
00215 int flags_;
00216 };
00217
00218 public:
00219 HttpMediaData(const char* sender, const char* name, int layer,
00220 int st, int et);
00221 HttpMediaData(HttpMediaData& d) : HttpData(d) {
00222 layer_ = d.layer_;
00223 st_ = d.st_;
00224 et_ = d.et_;
00225 flags_ = d.flags_;
00226 strcpy(page_, d.page_);
00227 strcpy(sender_, d.sender_);
00228 }
00229
00230 virtual int size() const { return HttpData::size() + sizeof(hdr); }
00231 virtual AppData* copy() { return (new HttpMediaData(*this)); }
00232
00233 int st() const { return st_; }
00234 int et() const { return et_; }
00235 int datasize() const { return et_ - st_; }
00236 int layer() const { return layer_; }
00237 const char* page() const { return page_; }
00238 const char* sender() const { return sender_; }
00239
00240 Application* conid() { return conid_; }
00241 void set_conid(Application* c) { conid_ = c; }
00242
00243
00244
00245
00246 enum {
00247 MD_LAST = 1,
00248 MD_FINISH = 2,
00249 MD_PREFETCH = 4
00250 };
00251
00252
00253 int is_last() const { return (flags_ & MD_LAST); }
00254 void set_last() { flags_ |= MD_LAST; }
00255 int is_finished() const { return (flags_ & MD_FINISH); }
00256 void set_finish() { flags_ |= MD_FINISH; }
00257 int is_pref() const { return (flags_ & MD_PREFETCH); }
00258 void set_pref() { flags_ |= MD_PREFETCH; }
00259 };
00260
00261
00262 const int MEDIAREQ_GETSEG = 1;
00263 const int MEDIAREQ_CHECKSEG = 2;
00264
00265 const int MEDIAREQ_SEGAVAIL = 3;
00266 const int MEDIAREQ_SEGUNAVAIL = 4;
00267
00268
00269
00270 class MediaRequest : public AppData {
00271 private:
00272 int request_;
00273 char name_[HTTP_MAXURLLEN];
00274 int layer_;
00275 u_int st_;
00276 u_int et_;
00277 Application* app_;
00278 public:
00279 MediaRequest(int rc) : AppData(MEDIA_REQUEST), request_(rc) {}
00280 MediaRequest(const MediaRequest& r) : AppData(MEDIA_REQUEST) {
00281 request_ = r.request();
00282 st_ = r.st();
00283 et_ = r.et();
00284 layer_ = r.layer();
00285 strcpy(name_, r.name());
00286 }
00287
00288 virtual AppData* copy() { abort(); return NULL; }
00289
00290 int request() const { return request_; }
00291 int st() const { return st_; }
00292 int et() const { return et_; }
00293 int datasize() const { return et_ - st_; }
00294 int layer() const { return layer_; }
00295 const char* name() const { return name_; }
00296 Application* app() const { return app_; }
00297
00298
00299
00300 void set_st(int d) { st_ = d; }
00301 void set_et(int d) { et_ = d; }
00302 void set_datasize(int d) { et_ = st_ + d; }
00303 void set_name(const char *s) { strcpy(name_, s); }
00304 void set_layer(int d) { layer_ = d; }
00305 void set_app(Application* a) { app_ = a; }
00306 };
00307
00308
00309
00310
00311 const int MAX_LAYER = 10;
00312
00313
00314
00315
00316 class MediaApp : public Application {
00317 public:
00318 MediaApp(const char* page);
00319
00320 virtual AppData* get_data(int& size, AppData* req_data = 0);
00321 virtual void process_data(int size, AppData* data) {
00322 send_data(size, data);
00323 }
00324 void set_page(const char* pg) { strcpy(page_, pg); }
00325
00326 void log(const char* fmt, ...);
00327 int command(int argc, const char*const* argv);
00328
00329 protected:
00330 virtual void start();
00331 virtual void stop();
00332
00333
00334 RapAgent* rap() { return (RapAgent*)agent_; }
00335
00336 int seg_size_;
00337 char page_[HTTP_MAXURLLEN];
00338 MediaSegment data_[MAX_LAYER];
00339 Tcl_Channel log_;
00340
00341
00342
00343 int num_layer_;
00344 private:
00345 int last_layer_;
00346 };
00347
00348
00349
00350 class QA;
00351
00352 class QATimer : public TimerHandler {
00353 public:
00354 QATimer(QA *a) : TimerHandler() { a_ = a; }
00355 protected:
00356 virtual void expire(Event *e);
00357 QA *a_;
00358 };
00359
00360 const double QA_EPSILON = 1e-6;
00361
00362 class QA : public MediaApp {
00363 public:
00364 QA(const char *page);
00365 virtual ~QA();
00366
00367 virtual AppData* get_data(int& size, AppData* req_data = 0);
00368 void UpdateState();
00369 double UpdateInterval() { return rap()->srtt(); }
00370
00371 protected:
00372 virtual int command(int argc, const char*const* argv);
00373 virtual void stop();
00374
00375
00376 void check_availability(int layer, const MediaSegment& s);
00377 RapAgent* rap() { return (RapAgent*)agent_; }
00378
00379
00380 inline double MWM(double srtt) {
00381 return 2 * LAYERBW_ * srtt;
00382 }
00383 inline double rate() {
00384 return (double)seg_size_ / rap()->ipg();
00385 }
00386
00387
00388 inline double BufNeed(double side, double slope) {
00389 return (side <= 0) ? 0.0 : ((side*side) / (2.0*slope));
00390 }
00391 int AllZero(double *arr, int len);
00392 double TotalBuf(int n, double *buffer);
00393 AppData* output(int& size, int layer);
00394 void DumpInfo(double t, double last_t, double rate,
00395 double avgrate, double srtt);
00396 double bufOptScen1(int layer, int layers, double currrate,
00397 double slope, int backoffs);
00398 double bufOptScen2(int layer, int layers, double currrate,
00399 double slope, int backoffs);
00400 void drain_buf(double* DrainArr, double bufToDrain,
00401 double* FinalDrainArray, double* bufAvail,
00402 int layers, double rate, double srtt);
00403 void DrainPacket(double bufToDrain, double* FinalDrainArray,
00404 int layers, double rate, double srtt,
00405 double* FinalBuffer);
00406
00407
00408 void DrainBuffers();
00409
00410
00411 void debug(const char* fmt, ...);
00412 void panic(const char* fmt, ...);
00413 void check_layers(int layer, MediaSegment& tmp);
00414
00415
00416 int layer_;
00417 double playTime_;
00418 double startTime_;
00419
00420
00421 double buffer_[MAX_LAYER];
00422 double drained_[MAX_LAYER];
00423 double bw_[MAX_LAYER];
00424 int playing_[MAX_LAYER];
00425 int sending_[MAX_LAYER];
00426 QATimer* updTimer_;
00427
00428
00429
00430 double avgrate_;
00431 double rate_weight_;
00432
00433
00434 int poffset_;
00435
00436
00437
00438 MediaSegmentList outlist_[MAX_LAYER];
00439
00440
00441 int pref_[MAX_LAYER];
00442
00443
00444 int debug_;
00445 double pref_srtt_;
00446 int LAYERBW_;
00447 int MAXACTIVELAYERS_;
00448 double SRTTWEIGHT_;
00449 int SMOOTHFACTOR_;
00450 int MAXBKOFF_;
00451 };
00452
00453 #endif // ns_media_app_h