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 #ifndef ns_pagepool_h
00048 #define ns_pagepool_h
00049
00050 #include <stdio.h>
00051 #include <limits.h>
00052 #include <tcl.h>
00053 #include <ranvar.h>
00054 #include <tclcl.h>
00055 #include "config.h"
00056
00057 enum WebPageType { HTML, MEDIA };
00058
00059 class Page {
00060 public:
00061 Page(int size) : size_(size) {}
00062 virtual ~Page () {}
00063 int size() const { return size_; }
00064 int& id() { return id_; }
00065 virtual WebPageType type() const = 0;
00066
00067 protected:
00068 int size_;
00069 int id_;
00070 };
00071
00072 class ServerPage : public Page {
00073 public:
00074 ServerPage(int size, int id) : Page(size) {
00075 id_ = id, mtime_ = NULL, num_mtime_ = 0;
00076 }
00077 virtual ~ServerPage() {
00078 if (mtime_ != NULL)
00079 delete []mtime_;
00080 }
00081
00082 virtual WebPageType type() const { return HTML; }
00083
00084 int& size() { return size_; }
00085 int& mtime(int n) { return mtime_[n]; }
00086 int& num_mtime() { return num_mtime_; }
00087 void set_mtime(int *mt, int n);
00088
00089 protected:
00090 int *mtime_;
00091 int num_mtime_;
00092 };
00093
00094 class HttpApp;
00095
00096
00097 const int HTTP_PAGE_STATE_MASK = 0x00FF;
00098 const int HTTP_ALL_PAGE_STATES = 0x00ff;
00099 const int HTTP_VALID_PAGE = 0x01;
00100 const int HTTP_SERVER_DOWN = 0x02;
00101
00102 const int HTTP_VALID_HEADER = 0x04;
00103 const int HTTP_UNREAD_PAGE = 0x08;
00104
00105
00106
00107 const int HTTP_UNCACHEABLE = 0x10;
00108
00109
00110 const int HTTP_PAGE_ACTION_MASK = 0xFF00;
00111 const int HTTP_MANDATORY_PUSH = 0x1000;
00112
00113 struct PageID {
00114 PageID() : s_(NULL), id_(0) {}
00115 PageID(int *buffer) {
00116 PageID *realBuffer = reinterpret_cast <PageID *> (buffer);
00117 s_ = realBuffer->s_;
00118 id_ = realBuffer->id_;
00119 }
00120 PageID(HttpApp *app, int id) {
00121 s_ = app;
00122 id_ = id;
00123 }
00124 HttpApp* s_;
00125 int id_;
00126 };
00127
00128 class ClientPage : public Page {
00129 public:
00130 ClientPage(const char *n, int s, double mt, double et, double a);
00131 virtual ~ClientPage() {}
00132
00133 virtual WebPageType type() const { return HTML; }
00134 virtual void print_info(char* buf);
00135
00136 void name(char* buf);
00137 double& mtime() { return mtime_; }
00138 double& etime() { return etime_; }
00139 double& age() { return age_; }
00140 HttpApp* server() { return server_; }
00141
00142
00143 void validate(double mtime) {
00144 if (mtime_ >= mtime)
00145 abort();
00146
00147 clear_page_state(HTTP_SERVER_DOWN);
00148 set_page_state(HTTP_VALID_PAGE);
00149 mtime_ = mtime;
00150 }
00151 void invalidate(double mtime) {
00152 if (mtime_ >= mtime)
00153 return;
00154 clear_page_state(HTTP_VALID_PAGE);
00155 clear_page_state(HTTP_VALID_HEADER);
00156 mtime_ = mtime;
00157 }
00158 int is_valid() const {
00159 return (status_ & HTTP_VALID_PAGE);
00160 }
00161 int is_header_valid() const {
00162 return ((status_ & HTTP_VALID_PAGE) ||
00163 (status_ & HTTP_VALID_HEADER));
00164 }
00165 inline void set_valid_hdr() {
00166
00167 clear_page_state(HTTP_SERVER_DOWN);
00168 clear_page_state(HTTP_VALID_PAGE);
00169 set_page_state(HTTP_VALID_HEADER);
00170 }
00171
00172 inline void set_uncacheable() {
00173 set_page_state(HTTP_UNCACHEABLE);
00174 }
00175 inline int is_uncacheable() {
00176 return (status_ & HTTP_UNCACHEABLE);
00177 }
00178
00179
00180
00181 inline void set_unread() {
00182 set_page_state(HTTP_UNREAD_PAGE);
00183 }
00184 inline void set_read() {
00185 clear_page_state(HTTP_UNREAD_PAGE);
00186 }
00187 inline int is_unread() { return (status_ & HTTP_UNREAD_PAGE); }
00188
00189 inline int is_server_down() { return (status_ & HTTP_SERVER_DOWN); }
00190 inline void server_down() {
00191
00192
00193 clear_page_state(HTTP_VALID_PAGE);
00194 clear_page_state(HTTP_VALID_HEADER);
00195 set_page_state(HTTP_SERVER_DOWN);
00196 }
00197
00198
00199
00200 static int PUSHALL_;
00201 inline int& counter() {
00202 if (PUSHALL_) counter_ = INT_MAX;
00203 return counter_;
00204 }
00205 inline int count_inval(int a, int th) {
00206 if (PUSHALL_)
00207 return INT_MAX;
00208 else {
00209 counter_ -= a;
00210 if (counter_ < th)
00211 counter_ = th;
00212 return counter_;
00213 }
00214 }
00215 inline int count_request(int b, int th) {
00216 if (PUSHALL_)
00217 return INT_MAX;
00218 else {
00219 counter_ += b;
00220 if (counter_ > th)
00221 counter_ = th;
00222 return counter_;
00223 }
00224 }
00225 inline void set_mpush(double time) {
00226 set_page_action(HTTP_MANDATORY_PUSH), mpushTime_ = time;
00227 }
00228 inline void clear_mpush() { clear_page_action(HTTP_MANDATORY_PUSH); }
00229 inline int is_mpush() { return status_ & HTTP_MANDATORY_PUSH; }
00230 inline double mpush_time() { return mpushTime_; }
00231
00232
00233 static void split_name(const char* name, PageID& id);
00234 static void print_name(char* name, PageID& id);
00235
00236 protected:
00237 void set_page_state(int state) {
00238 status_ |= state;
00239 }
00240 void clear_page_state(int state) {
00241 status_ = status_ & ~state;
00242 }
00243 void set_page_action(int action) {
00244 status_ |= action;
00245 }
00246 void clear_page_action(int action) {
00247 status_ = status_ & ~action;
00248 }
00249
00250 HttpApp* server_;
00251 double age_;
00252 double mtime_;
00253 double etime_;
00254 int status_;
00255 int counter_;
00256 double mpushTime_;
00257 };
00258
00259
00260
00261 class PagePool : public TclObject {
00262 public:
00263 PagePool() : num_pages_(0), start_time_(INT_MAX), end_time_(INT_MIN) {}
00264 int num_pages() const { return num_pages_; }
00265 protected:
00266 virtual int command(int argc, const char*const* argv);
00267 int num_pages_;
00268 double start_time_;
00269 double end_time_;
00270 int duration_;
00271
00272
00273 TclObject* lookup_obj(const char* name) {
00274 TclObject* obj = Tcl::instance().lookup(name);
00275 if (obj == NULL)
00276 fprintf(stderr, "Bad object name %s\n", name);
00277 return obj;
00278 }
00279 };
00280
00281
00282
00283 const int TRACEPAGEPOOL_MAXBUF = 4096;
00284
00285
00286 class TracePagePool : public PagePool {
00287 public:
00288 TracePagePool(const char *fn);
00289 virtual ~TracePagePool();
00290 virtual int command(int argc, const char*const* argv);
00291
00292 protected:
00293 Tcl_HashTable *namemap_, *idmap_;
00294 RandomVariable *ranvar_;
00295
00296 ServerPage* load_page(FILE *fp);
00297 void change_time();
00298 int add_page(const char* pgname, ServerPage *pg);
00299
00300 ServerPage* get_page(int id);
00301 };
00302
00303
00304
00305 class MathPagePool : public PagePool {
00306 public:
00307
00308 MathPagePool() : rvSize_(0), rvAge_(0) { num_pages_ = 1; }
00309
00310 protected:
00311 virtual int command(int argc, const char*const* argv);
00312
00313 RandomVariable *rvSize_;
00314 RandomVariable *rvAge_;
00315 };
00316
00317
00318 class CompMathPagePool : public PagePool {
00319 public:
00320 CompMathPagePool();
00321
00322 protected:
00323 virtual int command(int argc, const char*const* argv);
00324 RandomVariable *rvMainAge_;
00325 RandomVariable *rvCompAge_;
00326 int main_size_, comp_size_;
00327 };
00328
00329 class ClientPagePool : public PagePool {
00330 public:
00331 ClientPagePool();
00332 virtual ~ClientPagePool();
00333
00334 virtual ClientPage* enter_page(int argc, const char*const* argv);
00335 virtual ClientPage* enter_metadata(int argc, const char*const* argv);
00336 virtual ClientPage* enter_page(const char *name, int size, double mt,
00337 double et, double age);
00338 virtual ClientPage* enter_metadata(const char *name, int size,
00339 double mt, double et, double age);
00340 virtual int remove_page(const char *name);
00341
00342 void invalidate_server(int server_id);
00343
00344 ClientPage* get_page(const char *name);
00345 int get_mtime(const char *name, double &mt);
00346 int set_mtime(const char *name, double mt);
00347 int exist_page(const char *name) { return (get_page(name) != NULL); }
00348 int get_size(const char *name, int &size);
00349 int get_age(const char *name, double &age);
00350 int get_etime(const char *name, double &et);
00351 int set_etime(const char *name, double et);
00352 int get_pageinfo(const char *name, char *buf);
00353
00354 virtual int command(int argc, const char*const* argv);
00355
00356 protected:
00357
00358 int add_page(ClientPage *pg);
00359 Tcl_HashTable *namemap_;
00360 };
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 class ProxyTracePagePool : public PagePool {
00373 public:
00374 ProxyTracePagePool();
00375
00376
00377
00378 virtual ~ProxyTracePagePool();
00379 virtual int command(int argc, const char*const* argv);
00380
00381 protected:
00382
00383
00384 int init_req(const char *fn);
00385 int init_page(const char *fn);
00386 int find_info();
00387
00388 RandomVariable *rvDyn_, *rvStatic_;
00389 int br_;
00390 int *size_;
00391 FILE *reqfile_;
00392
00393 struct ClientRequest {
00394 ClientRequest() : seq_(0), nrt_(0), nurl_(0), fpos_(0)
00395 {}
00396 int seq_;
00397
00398 double nrt_;
00399 int nurl_;
00400 long fpos_;
00401 };
00402 Tcl_HashTable *req_;
00403 int nclient_, lastseq_;
00404 ClientRequest* load_req(int cid);
00405 };
00406
00407 class EPATracePagePool : public ProxyTracePagePool {
00408 public:
00409 virtual int command(int argc, const char*const* argv);
00410 };
00411
00412 #endif //ns_pagepool_h