• Main Page
  • Classes
  • Files
  • File List

/Users/yzchen/ns/ns-allinone-2.33/ns-2.33/webcache/pagepool.h

00001 /*
00002  * Copyright (c) Xerox Corporation 1998. All rights reserved.
00003  *
00004  * This program is free software; you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License as published by the
00006  * Free Software Foundation; either version 2 of the License, or (at your
00007  * option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License along
00015  * with this program; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  * Linking this file statically or dynamically with other modules is making
00019  * a combined work based on this file.  Thus, the terms and conditions of
00020  * the GNU General Public License cover the whole combination.
00021  *
00022  * In addition, as a special exception, the copyright holders of this file
00023  * give you permission to combine this file with free software programs or
00024  * libraries that are released under the GNU LGPL and with code included in
00025  * the standard release of ns-2 under the Apache 2.0 license or under
00026  * otherwise-compatible licenses with advertising requirements (or modified
00027  * versions of such code, with unchanged license).  You may copy and
00028  * distribute such a system following the terms of the GNU GPL for this
00029  * file and the licenses of the other code concerned, provided that you
00030  * include the source code of that other code when and as the GNU GPL
00031  * requires distribution of source code.
00032  *
00033  * Note that people who make modified versions of this file are not
00034  * obligated to grant this special exception for their modified versions;
00035  * it is their choice whether to do so.  The GNU General Public License
00036  * gives permission to release a modified version without this exception;
00037  * this exception also makes it possible to release a modified version
00038  * which carries forward this exception.
00039  * 
00040  * $Header: /cvsroot/nsnam/ns-2/webcache/pagepool.h,v 1.17 2005/09/18 23:33:35 tomh Exp $
00041  *
00042  */
00043 //
00044 // Definitions for class PagePool
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;   // Page type: HTML or MEDIA
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 // Page states
00097 const int HTTP_PAGE_STATE_MASK  = 0x00FF;
00098 const int HTTP_ALL_PAGE_STATES  = 0x00ff; // all page states
00099 const int HTTP_VALID_PAGE       = 0x01; // Valid page
00100 const int HTTP_SERVER_DOWN      = 0x02; // Server is down. Don't know if 
00101                                         // page is valid
00102 const int HTTP_VALID_HEADER     = 0x04; // Only meta-data is valid
00103 const int HTTP_UNREAD_PAGE      = 0x08; // Unread valid page
00104 
00105 // Used only for server to manage its pages. A none-cacheable page won't be 
00106 // stored by caches and clients.
00107 const int HTTP_UNCACHEABLE      = 0x10; // Non-cacheable page
00108 
00109 // Page actions
00110 const int HTTP_PAGE_ACTION_MASK = 0xFF00; // Page action bit mask
00111 const int HTTP_MANDATORY_PUSH   = 0x1000; // If the page is mandatory pushed
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         // Page becomes valid. Clear all other possible invalid bits
00143         void validate(double mtime) { 
00144                 if (mtime_ >= mtime)
00145                         abort(); // This shouldn't happen!
00146                 // Clear server down bit
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                 // XXX page invalid, but only header valid
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         // Has nothing to do with valid/invalid/server_down etc. It can 
00180         // be combined with all other page status
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                 // Set page as invalid
00192                 // Don't change mtime, only change page status
00193                 clear_page_state(HTTP_VALID_PAGE);
00194                 clear_page_state(HTTP_VALID_HEADER);
00195                 set_page_state(HTTP_SERVER_DOWN);
00196         }
00197 
00198         // Flags to indicate whether we want to do all push or selective push
00199         // If 0: selective push, otherwise all push
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         // Used to split page names into page identifiers
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_;  // modification time
00253         double etime_;  // entry time
00254         int status_;    // VALID or INVALID
00255         int counter_;   // counter for invalidation & request
00256         double mpushTime_;
00257 };
00258 
00259 
00260 // Abstract page pool, used for interface only
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         // Helper functions
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 // Page pool based on real server traces
00282 
00283 const int TRACEPAGEPOOL_MAXBUF = 4096;
00284 
00285 // This trace must contain web page names and all of its modification times
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 // Page pool based on mathematical models of request and page 
00304 // modification patterns
00305 class MathPagePool : public PagePool {
00306 public:
00307         // XXX TBA: what should be here???
00308         MathPagePool() : rvSize_(0), rvAge_(0) { num_pages_ = 1; }
00309 
00310 protected:
00311         virtual int command(int argc, const char*const* argv);
00312         // Single page
00313         RandomVariable *rvSize_;
00314         RandomVariable *rvAge_;
00315 };
00316 
00317 // Assume one main page, which changes often, and multiple component pages
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_;  // modtime for main page
00325         RandomVariable *rvCompAge_;  // modtime for component pages
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 // This is *not* designed for BU trace files. We should write a script to 
00363 // transform BU traces to a single trace file with the following format:
00364 //
00365 // <client id> <page id> <time> <size>
00366 //
00367 // Q: How would we deal with page size changes? 
00368 // What if simulated response time
00369 // is longer and a real client request for the same page happened before the 
00370 // simulated request completes? 
00371 
00372 class ProxyTracePagePool : public PagePool {
00373 public:
00374         ProxyTracePagePool();
00375 // : rvDyn_(NULL), rvStatic_(NULL), br_(0), 
00376 //              size_(NULL), reqfile_(NULL), req_(NULL), lastseq_(0)
00377 //              {}
00378         virtual ~ProxyTracePagePool();
00379         virtual int command(int argc, const char*const* argv);
00380 
00381 protected:
00382         // How would we handle different types of page modifications? How 
00383         // to integrate bimodal, and multi-modal distributions?
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_;                // bimodal ratio
00390         int *size_;             // page sizes
00391         FILE *reqfile_;         // request stream of proxy trace
00392 
00393         struct ClientRequest {
00394                 ClientRequest() : seq_(0), nrt_(0), nurl_(0), fpos_(0)
00395                         {}
00396                 int seq_;       // client sequence number, used to match 
00397                                 // client ids in the trace file
00398                 double nrt_;    // next request time
00399                 int nurl_;      // next request url
00400                 long fpos_;     // position in file of its next request
00401         };
00402         Tcl_HashTable *req_;    // Requests table
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

Generated on Tue Aug 10 2010 16:16:09 for ns-2.33 by  doxygen 1.7.1