Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

pagepool.h

Go to the documentation of this file.
00001 // Copyright (c) Xerox Corporation 1998. All rights reserved.
00002 //
00003 // License is granted to copy, to use, and to make and to use derivative
00004 // works for research and evaluation purposes, provided that Xerox is
00005 // acknowledged in all documentation pertaining to any such copy or
00006 // derivative work. Xerox grants no other licenses expressed or
00007 // implied. The Xerox trade name should not be used in any advertising
00008 // without its written permission. 
00009 //
00010 // XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE
00011 // MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
00012 // FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
00013 // express or implied warranty of any kind.
00014 //
00015 // These notices must be retained in any copies of any part of this
00016 // software. 
00017 //
00018 // Definitions for class PagePool
00019 //
00020 // $Header: /nfs/jade/vint/CVSROOT/ns-2/webcache/pagepool.h,v 1.14 1999/11/18 23:14:35 haoboy Exp $
00021 
00022 #ifndef ns_pagepool_h
00023 #define ns_pagepool_h
00024 
00025 #include <stdio.h>
00026 #include <limits.h>
00027 #include <tcl.h>
00028 #include <ranvar.h>
00029 #include <tclcl.h>
00030 #include "config.h"
00031 
00032 enum WebPageType { HTML, MEDIA };
00033 
00034 class Page {
00035 public:
00036         Page(int size) : size_(size) {}
00037         int size() const { return size_; }
00038         int& id() { return id_; }
00039         virtual WebPageType type() const = 0;   // Page type: HTML or MEDIA
00040 
00041 protected:
00042         int size_;
00043         int id_;
00044 };
00045 
00046 class ServerPage : public Page {
00047 public:
00048         ServerPage(int size, int id) : Page(size) {
00049                 id_ = id, mtime_ = NULL, num_mtime_ = 0;
00050         }
00051         virtual ~ServerPage() {
00052                 if (mtime_ != NULL) 
00053                         delete []mtime_;
00054         }
00055 
00056         virtual WebPageType type() const { return HTML; }
00057 
00058         int& size() { return size_; }
00059         int& mtime(int n) { return mtime_[n]; }
00060         int& num_mtime() { return num_mtime_; }
00061         void set_mtime(int *mt, int n);
00062 
00063 protected:
00064         int *mtime_;
00065         int num_mtime_;
00066 };
00067 
00068 class HttpApp;
00069 
00070 // Page states
00071 const int HTTP_PAGE_STATE_MASK  = 0x00FF;
00072 const int HTTP_ALL_PAGE_STATES  = 0x00ff; // all page states
00073 const int HTTP_VALID_PAGE       = 0x01; // Valid page
00074 const int HTTP_SERVER_DOWN      = 0x02; // Server is down. Don't know if 
00075                                         // page is valid
00076 const int HTTP_VALID_HEADER     = 0x04; // Only meta-data is valid
00077 const int HTTP_UNREAD_PAGE      = 0x08; // Unread valid page
00078 
00079 // Used only for server to manage its pages. A none-cacheable page won't be 
00080 // stored by caches and clients.
00081 const int HTTP_UNCACHEABLE      = 0x10; // Non-cacheable page
00082 
00083 // Page actions
00084 const int HTTP_PAGE_ACTION_MASK = 0xFF00; // Page action bit mask
00085 const int HTTP_MANDATORY_PUSH   = 0x1000; // If the page is mandatory pushed
00086 
00087 struct PageID {
00088         PageID() : s_(NULL), id_(0) {}
00089         PageID(int* t) {
00090                 s_ = (HttpApp*)t[0];
00091                 id_ = t[1];
00092         }
00093         HttpApp* s_;
00094         int id_;
00095 };
00096 
00097 class ClientPage : public Page {
00098 public:
00099         ClientPage(const char *n, int s, double mt, double et, double a);
00100         virtual ~ClientPage() {}
00101 
00102         virtual WebPageType type() const { return HTML; }
00103         virtual void print_info(char* buf);
00104 
00105         void name(char* buf);
00106         double& mtime() { return mtime_; }
00107         double& etime() { return etime_; }
00108         double& age() { return age_; }
00109         HttpApp* server() { return server_; }
00110 
00111         // Page becomes valid. Clear all other possible invalid bits
00112         void validate(double mtime) { 
00113                 if (mtime_ >= mtime)
00114                         abort(); // This shouldn't happen!
00115                 // Clear server down bit
00116                 clear_page_state(HTTP_SERVER_DOWN);
00117                 set_page_state(HTTP_VALID_PAGE);
00118                 mtime_ = mtime;
00119         }
00120         void invalidate(double mtime) { 
00121                 if (mtime_ >= mtime)
00122                         return;
00123                 clear_page_state(HTTP_VALID_PAGE);
00124                 clear_page_state(HTTP_VALID_HEADER);
00125                 mtime_ = mtime;
00126         }
00127         int is_valid() const { 
00128                 return (status_ & HTTP_VALID_PAGE);
00129         }
00130         int is_header_valid() const {
00131                 return ((status_ & HTTP_VALID_PAGE) || 
00132                         (status_ & HTTP_VALID_HEADER));
00133         }
00134         inline void set_valid_hdr() { 
00135                 // XXX page invalid, but only header valid
00136                 clear_page_state(HTTP_SERVER_DOWN);
00137                 clear_page_state(HTTP_VALID_PAGE);
00138                 set_page_state(HTTP_VALID_HEADER); 
00139         }
00140 
00141         inline void set_uncacheable() { 
00142                 set_page_state(HTTP_UNCACHEABLE);
00143         }
00144         inline int is_uncacheable() {
00145                 return (status_ & HTTP_UNCACHEABLE);
00146         }
00147 
00148         // Has nothing to do with valid/invalid/server_down etc. It can 
00149         // be combined with all other page status
00150         inline void set_unread() { 
00151                 set_page_state(HTTP_UNREAD_PAGE); 
00152         }
00153         inline void set_read() { 
00154                 clear_page_state(HTTP_UNREAD_PAGE);
00155         }
00156         inline int is_unread() { return (status_ & HTTP_UNREAD_PAGE); }
00157 
00158         inline int is_server_down() { return (status_ & HTTP_SERVER_DOWN); }
00159         inline void server_down() {
00160                 // Set page as invalid
00161                 // Don't change mtime, only change page status
00162                 clear_page_state(HTTP_VALID_PAGE);
00163                 clear_page_state(HTTP_VALID_HEADER);
00164                 set_page_state(HTTP_SERVER_DOWN);
00165         }
00166 
00167         // Flags to indicate whether we want to do all push or selective push
00168         // If 0: selective push, otherwise all push
00169         static int PUSHALL_; 
00170         inline int& counter() { 
00171                 if (PUSHALL_) counter_ = INT_MAX;
00172                 return counter_;
00173         }
00174         inline int count_inval(int a, int th) { 
00175                 if (PUSHALL_) 
00176                         return INT_MAX;
00177                 else {
00178                         counter_ -= a; 
00179                         if (counter_ < th) 
00180                                 counter_ = th;
00181                         return counter_; 
00182                 }
00183         }
00184         inline int count_request(int b, int th) { 
00185                 if (PUSHALL_) 
00186                         return INT_MAX;
00187                 else {
00188                         counter_ += b; 
00189                         if (counter_ > th) 
00190                                 counter_ = th;
00191                         return counter_; 
00192                 }
00193         }
00194         inline void set_mpush(double time) { 
00195                 set_page_action(HTTP_MANDATORY_PUSH), mpushTime_ = time; 
00196         }
00197         inline void clear_mpush() { clear_page_action(HTTP_MANDATORY_PUSH); }
00198         inline int is_mpush() { return status_ & HTTP_MANDATORY_PUSH; }
00199         inline double mpush_time() { return mpushTime_; }
00200 
00201         // Used to split page names into page identifiers
00202         static void split_name(const char* name, PageID& id);
00203         static void print_name(char* name, PageID& id);
00204 
00205 protected:
00206         void set_page_state(int state) {
00207                 status_ |= state;
00208         }
00209         void clear_page_state(int state) {
00210                 status_ = status_ & ~state;
00211         }
00212         void set_page_action(int action) {
00213                 status_ |= action;
00214         }
00215         void clear_page_action(int action) {
00216                 status_ = status_ & ~action;
00217         }
00218 
00219         HttpApp* server_;
00220         double age_;
00221         double mtime_;  // modification time
00222         double etime_;  // entry time
00223         int status_;    // VALID or INVALID
00224         int counter_;   // counter for invalidation & request
00225         double mpushTime_;
00226 };
00227 
00228 
00229 // Abstract page pool, used for interface only
00230 class PagePool : public TclObject {
00231 public: 
00232         PagePool() : num_pages_(0), start_time_(INT_MAX), end_time_(INT_MIN) {}
00233         int num_pages() const { return num_pages_; }
00234 protected:
00235         virtual int command(int argc, const char*const* argv);
00236         int num_pages_;
00237         double start_time_;
00238         double end_time_;
00239         int duration_;
00240 
00241         // Helper functions
00242         TclObject* lookup_obj(const char* name) {
00243                 TclObject* obj = Tcl::instance().lookup(name);
00244                 if (obj == NULL) 
00245                         fprintf(stderr, "Bad object name %s\n", name);
00246                 return obj;
00247         }
00248 };
00249 
00250 // Page pool based on real server traces
00251 
00252 const int TRACEPAGEPOOL_MAXBUF = 4096;
00253 
00254 // This trace must contain web page names and all of its modification times
00255 class TracePagePool : public PagePool {
00256 public:
00257         TracePagePool(const char *fn);
00258         virtual ~TracePagePool();
00259         virtual int command(int argc, const char*const* argv);
00260 
00261 protected:
00262         Tcl_HashTable *namemap_, *idmap_;
00263         RandomVariable *ranvar_;
00264 
00265         ServerPage* load_page(FILE *fp);
00266         void change_time();
00267         int add_page(const char* pgname, ServerPage *pg);
00268 
00269         ServerPage* get_page(int id);
00270 };
00271 
00272 // Page pool based on mathematical models of request and page 
00273 // modification patterns
00274 class MathPagePool : public PagePool {
00275 public:
00276         // XXX TBA: what should be here???
00277         MathPagePool() : rvSize_(0), rvAge_(0) { num_pages_ = 1; }
00278 
00279 protected:
00280         virtual int command(int argc, const char*const* argv);
00281         // Single page
00282         RandomVariable *rvSize_;
00283         RandomVariable *rvAge_;
00284 };
00285 
00286 // Assume one main page, which changes often, and multiple component pages
00287 class CompMathPagePool : public PagePool {
00288 public:
00289         CompMathPagePool();
00290 
00291 protected:
00292         virtual int command(int argc, const char*const* argv);
00293         RandomVariable *rvMainAge_;  // modtime for main page
00294         RandomVariable *rvCompAge_;  // modtime for component pages
00295         int main_size_, comp_size_;
00296 };
00297 
00298 class ClientPagePool : public PagePool {
00299 public:
00300         ClientPagePool();
00301         virtual ~ClientPagePool();
00302 
00303         virtual ClientPage* enter_page(int argc, const char*const* argv);
00304         virtual ClientPage* enter_metadata(int argc, const char*const* argv);
00305         virtual ClientPage* enter_page(const char *name, int size, double mt, 
00306                                        double et, double age);
00307         virtual ClientPage* enter_metadata(const char *name, int size, 
00308                                            double mt, double et, double age);
00309         virtual int remove_page(const char *name);
00310 
00311         void invalidate_server(int server_id);
00312 
00313         ClientPage* get_page(const char *name);
00314         int get_mtime(const char *name, double &mt);
00315         int set_mtime(const char *name, double mt);
00316         int exist_page(const char *name) { return (get_page(name) != NULL); }
00317         int get_size(const char *name, int &size);
00318         int get_age(const char *name, double &age);
00319         int get_etime(const char *name, double &et);
00320         int set_etime(const char *name, double et);
00321         int get_pageinfo(const char *name, char *buf);
00322 
00323         virtual int command(int argc, const char*const* argv);
00324 
00325 protected:
00326 
00327         int add_page(ClientPage *pg);
00328         Tcl_HashTable *namemap_;
00329 };
00330 
00331 // This is *not* designed for BU trace files. We should write a script to 
00332 // transform BU traces to a single trace file with the following format:
00333 //
00334 // <client id> <page id> <time> <size>
00335 //
00336 // Q: How would we deal with page size changes? 
00337 // What if simulated response time
00338 // is longer and a real client request for the same page happened before the 
00339 // simulated request completes? 
00340 
00341 class ProxyTracePagePool : public PagePool {
00342 public:
00343         ProxyTracePagePool();
00344 // : rvDyn_(NULL), rvStatic_(NULL), br_(0), 
00345 //              size_(NULL), reqfile_(NULL), req_(NULL), lastseq_(0)
00346 //              {}
00347         virtual ~ProxyTracePagePool();
00348         virtual int command(int argc, const char*const* argv);
00349 
00350 protected:
00351         // How would we handle different types of page modifications? How 
00352         // to integrate bimodal, and multi-modal distributions?
00353         int init_req(const char *fn);
00354         int init_page(const char *fn);
00355         int find_info();
00356 
00357         RandomVariable *rvDyn_, *rvStatic_;
00358         int br_;                // bimodal ratio
00359         int *size_;             // page sizes
00360         FILE *reqfile_;         // request stream of proxy trace
00361 
00362         struct ClientRequest {
00363                 ClientRequest() : seq_(0), nrt_(0), nurl_(0), fpos_(0)
00364                         {}
00365                 int seq_;       // client sequence number, used to match 
00366                                 // client ids in the trace file
00367                 double nrt_;    // next request time
00368                 int nurl_;      // next request url
00369                 long fpos_;     // position in file of its next request
00370         };
00371         Tcl_HashTable *req_;    // Requests table
00372         int nclient_, lastseq_;
00373         ClientRequest* load_req(int cid);
00374 };
00375 
00376 class EPATracePagePool : public ProxyTracePagePool {
00377 public:
00378         virtual int command(int argc, const char*const* argv);
00379 };
00380 
00381 #endif //ns_pagepool_h

Generated on Tue Apr 20 12:14:26 2004 for NS2.26SourcesOriginal by doxygen 1.3.3