pagepool.h
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:12k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) Xerox Corporation 1998. All rights reserved.
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify it
  5.  * under the terms of the GNU General Public License as published by the
  6.  * Free Software Foundation; either version 2 of the License, or (at your
  7.  * option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful, but
  10.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12.  * General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License along
  15.  * with this program; if not, write to the Free Software Foundation, Inc.,
  16.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17.  *
  18.  * Linking this file statically or dynamically with other modules is making
  19.  * a combined work based on this file.  Thus, the terms and conditions of
  20.  * the GNU General Public License cover the whole combination.
  21.  *
  22.  * In addition, as a special exception, the copyright holders of this file
  23.  * give you permission to combine this file with free software programs or
  24.  * libraries that are released under the GNU LGPL and with code included in
  25.  * the standard release of ns-2 under the Apache 2.0 license or under
  26.  * otherwise-compatible licenses with advertising requirements (or modified
  27.  * versions of such code, with unchanged license).  You may copy and
  28.  * distribute such a system following the terms of the GNU GPL for this
  29.  * file and the licenses of the other code concerned, provided that you
  30.  * include the source code of that other code when and as the GNU GPL
  31.  * requires distribution of source code.
  32.  *
  33.  * Note that people who make modified versions of this file are not
  34.  * obligated to grant this special exception for their modified versions;
  35.  * it is their choice whether to do so.  The GNU General Public License
  36.  * gives permission to release a modified version without this exception;
  37.  * this exception also makes it possible to release a modified version
  38.  * which carries forward this exception.
  39.  * 
  40.  * $Header: /cvsroot/nsnam/ns-2/webcache/pagepool.h,v 1.17 2005/09/18 23:33:35 tomh Exp $
  41.  *
  42.  */
  43. //
  44. // Definitions for class PagePool
  45. //
  46. #ifndef ns_pagepool_h
  47. #define ns_pagepool_h
  48. #include <stdio.h>
  49. #include <limits.h>
  50. #include <tcl.h>
  51. #include <ranvar.h>
  52. #include <tclcl.h>
  53. #include "config.h"
  54. enum WebPageType { HTML, MEDIA };
  55. class Page {
  56. public:
  57. Page(int size) : size_(size) {}
  58. virtual ~Page () {}
  59. int size() const { return size_; }
  60. int& id() { return id_; }
  61. virtual WebPageType type() const = 0;  // Page type: HTML or MEDIA
  62. protected:
  63. int size_;
  64. int id_;
  65. };
  66. class ServerPage : public Page {
  67. public:
  68. ServerPage(int size, int id) : Page(size) {
  69. id_ = id, mtime_ = NULL, num_mtime_ = 0;
  70. }
  71. virtual ~ServerPage() {
  72. if (mtime_ != NULL) 
  73. delete []mtime_;
  74. }
  75. virtual WebPageType type() const { return HTML; }
  76. int& size() { return size_; }
  77. int& mtime(int n) { return mtime_[n]; }
  78. int& num_mtime() { return num_mtime_; }
  79. void set_mtime(int *mt, int n);
  80. protected:
  81. int *mtime_;
  82. int num_mtime_;
  83. };
  84. class HttpApp;
  85. // Page states
  86. const int HTTP_PAGE_STATE_MASK = 0x00FF;
  87. const int HTTP_ALL_PAGE_STATES = 0x00ff; // all page states
  88. const int HTTP_VALID_PAGE = 0x01; // Valid page
  89. const int HTTP_SERVER_DOWN = 0x02; // Server is down. Don't know if 
  90. // page is valid
  91. const int HTTP_VALID_HEADER = 0x04; // Only meta-data is valid
  92. const int HTTP_UNREAD_PAGE = 0x08; // Unread valid page
  93. // Used only for server to manage its pages. A none-cacheable page won't be 
  94. // stored by caches and clients.
  95. const int HTTP_UNCACHEABLE = 0x10; // Non-cacheable page
  96. // Page actions
  97. const int HTTP_PAGE_ACTION_MASK = 0xFF00; // Page action bit mask
  98. const int HTTP_MANDATORY_PUSH = 0x1000; // If the page is mandatory pushed
  99. struct PageID {
  100. PageID() : s_(NULL), id_(0) {}
  101.         PageID(int *buffer) {
  102.         PageID *realBuffer = reinterpret_cast <PageID *> (buffer);
  103. s_ = realBuffer->s_;
  104. id_ = realBuffer->id_;
  105. }
  106. PageID(HttpApp *app, int id) {
  107. s_ = app;
  108. id_ = id;
  109. }
  110. HttpApp* s_;
  111. int id_;
  112. };
  113. class ClientPage : public Page {
  114. public:
  115. ClientPage(const char *n, int s, double mt, double et, double a);
  116. virtual ~ClientPage() {}
  117. virtual WebPageType type() const { return HTML; }
  118. virtual void print_info(char* buf);
  119. void name(char* buf);
  120. double& mtime() { return mtime_; }
  121. double& etime() { return etime_; }
  122. double& age() { return age_; }
  123. HttpApp* server() { return server_; }
  124. // Page becomes valid. Clear all other possible invalid bits
  125. void validate(double mtime) { 
  126. if (mtime_ >= mtime)
  127. abort(); // This shouldn't happen!
  128. // Clear server down bit
  129. clear_page_state(HTTP_SERVER_DOWN);
  130. set_page_state(HTTP_VALID_PAGE);
  131. mtime_ = mtime;
  132. }
  133. void invalidate(double mtime) { 
  134. if (mtime_ >= mtime)
  135. return;
  136. clear_page_state(HTTP_VALID_PAGE);
  137. clear_page_state(HTTP_VALID_HEADER);
  138. mtime_ = mtime;
  139. }
  140. int is_valid() const { 
  141. return (status_ & HTTP_VALID_PAGE);
  142. }
  143. int is_header_valid() const {
  144. return ((status_ & HTTP_VALID_PAGE) || 
  145. (status_ & HTTP_VALID_HEADER));
  146. }
  147. inline void set_valid_hdr() { 
  148. // XXX page invalid, but only header valid
  149. clear_page_state(HTTP_SERVER_DOWN);
  150. clear_page_state(HTTP_VALID_PAGE);
  151. set_page_state(HTTP_VALID_HEADER); 
  152. }
  153. inline void set_uncacheable() { 
  154. set_page_state(HTTP_UNCACHEABLE);
  155. }
  156. inline int is_uncacheable() {
  157. return (status_ & HTTP_UNCACHEABLE);
  158. }
  159. // Has nothing to do with valid/invalid/server_down etc. It can 
  160. // be combined with all other page status
  161. inline void set_unread() { 
  162. set_page_state(HTTP_UNREAD_PAGE); 
  163. }
  164. inline void set_read() { 
  165. clear_page_state(HTTP_UNREAD_PAGE);
  166. }
  167. inline int is_unread() { return (status_ & HTTP_UNREAD_PAGE); }
  168. inline int is_server_down() { return (status_ & HTTP_SERVER_DOWN); }
  169. inline void server_down() {
  170. // Set page as invalid
  171. // Don't change mtime, only change page status
  172. clear_page_state(HTTP_VALID_PAGE);
  173. clear_page_state(HTTP_VALID_HEADER);
  174. set_page_state(HTTP_SERVER_DOWN);
  175. }
  176. // Flags to indicate whether we want to do all push or selective push
  177. // If 0: selective push, otherwise all push
  178. static int PUSHALL_; 
  179. inline int& counter() { 
  180. if (PUSHALL_) counter_ = INT_MAX;
  181. return counter_;
  182. }
  183. inline int count_inval(int a, int th) { 
  184. if (PUSHALL_) 
  185. return INT_MAX;
  186. else {
  187. counter_ -= a; 
  188. if (counter_ < th) 
  189. counter_ = th;
  190. return counter_; 
  191. }
  192. }
  193. inline int count_request(int b, int th) { 
  194. if (PUSHALL_) 
  195. return INT_MAX;
  196. else {
  197. counter_ += b; 
  198. if (counter_ > th) 
  199. counter_ = th;
  200. return counter_; 
  201. }
  202. }
  203. inline void set_mpush(double time) { 
  204. set_page_action(HTTP_MANDATORY_PUSH), mpushTime_ = time; 
  205. }
  206. inline void clear_mpush() { clear_page_action(HTTP_MANDATORY_PUSH); }
  207. inline int is_mpush() { return status_ & HTTP_MANDATORY_PUSH; }
  208. inline double mpush_time() { return mpushTime_; }
  209. // Used to split page names into page identifiers
  210. static void split_name(const char* name, PageID& id);
  211. static void print_name(char* name, PageID& id);
  212. protected:
  213. void set_page_state(int state) {
  214. status_ |= state;
  215. }
  216. void clear_page_state(int state) {
  217. status_ = status_ & ~state;
  218. }
  219. void set_page_action(int action) {
  220. status_ |= action;
  221. }
  222. void clear_page_action(int action) {
  223. status_ = status_ & ~action;
  224. }
  225. HttpApp* server_;
  226. double age_;
  227. double mtime_; // modification time
  228. double etime_; // entry time
  229. int status_; // VALID or INVALID
  230. int counter_; // counter for invalidation & request
  231. double mpushTime_;
  232. };
  233. // Abstract page pool, used for interface only
  234. class PagePool : public TclObject {
  235. public: 
  236. PagePool() : num_pages_(0), start_time_(INT_MAX), end_time_(INT_MIN) {}
  237. int num_pages() const { return num_pages_; }
  238. protected:
  239. virtual int command(int argc, const char*const* argv);
  240. int num_pages_;
  241. double start_time_;
  242. double end_time_;
  243. int duration_;
  244. // Helper functions
  245. TclObject* lookup_obj(const char* name) {
  246. TclObject* obj = Tcl::instance().lookup(name);
  247. if (obj == NULL) 
  248. fprintf(stderr, "Bad object name %sn", name);
  249. return obj;
  250. }
  251. };
  252. // Page pool based on real server traces
  253. const int TRACEPAGEPOOL_MAXBUF = 4096;
  254. // This trace must contain web page names and all of its modification times
  255. class TracePagePool : public PagePool {
  256. public:
  257. TracePagePool(const char *fn);
  258. virtual ~TracePagePool();
  259. virtual int command(int argc, const char*const* argv);
  260. protected:
  261. Tcl_HashTable *namemap_, *idmap_;
  262. RandomVariable *ranvar_;
  263. ServerPage* load_page(FILE *fp);
  264. void change_time();
  265. int add_page(const char* pgname, ServerPage *pg);
  266. ServerPage* get_page(int id);
  267. };
  268. // Page pool based on mathematical models of request and page 
  269. // modification patterns
  270. class MathPagePool : public PagePool {
  271. public:
  272. // XXX TBA: what should be here???
  273. MathPagePool() : rvSize_(0), rvAge_(0) { num_pages_ = 1; }
  274. protected:
  275. virtual int command(int argc, const char*const* argv);
  276. // Single page
  277. RandomVariable *rvSize_;
  278. RandomVariable *rvAge_;
  279. };
  280. // Assume one main page, which changes often, and multiple component pages
  281. class CompMathPagePool : public PagePool {
  282. public:
  283. CompMathPagePool();
  284. protected:
  285. virtual int command(int argc, const char*const* argv);
  286. RandomVariable *rvMainAge_;  // modtime for main page
  287. RandomVariable *rvCompAge_;  // modtime for component pages
  288. int main_size_, comp_size_;
  289. };
  290. class ClientPagePool : public PagePool {
  291. public:
  292. ClientPagePool();
  293. virtual ~ClientPagePool();
  294. virtual ClientPage* enter_page(int argc, const char*const* argv);
  295. virtual ClientPage* enter_metadata(int argc, const char*const* argv);
  296. virtual ClientPage* enter_page(const char *name, int size, double mt, 
  297.        double et, double age);
  298. virtual ClientPage* enter_metadata(const char *name, int size, 
  299.    double mt, double et, double age);
  300. virtual int remove_page(const char *name);
  301. void invalidate_server(int server_id);
  302. ClientPage* get_page(const char *name);
  303. int get_mtime(const char *name, double &mt);
  304. int set_mtime(const char *name, double mt);
  305. int exist_page(const char *name) { return (get_page(name) != NULL); }
  306. int get_size(const char *name, int &size);
  307. int get_age(const char *name, double &age);
  308. int get_etime(const char *name, double &et);
  309. int set_etime(const char *name, double et);
  310. int get_pageinfo(const char *name, char *buf);
  311. virtual int command(int argc, const char*const* argv);
  312. protected:
  313. int add_page(ClientPage *pg);
  314. Tcl_HashTable *namemap_;
  315. };
  316. // This is *not* designed for BU trace files. We should write a script to 
  317. // transform BU traces to a single trace file with the following format:
  318. //
  319. // <client id> <page id> <time> <size>
  320. //
  321. // Q: How would we deal with page size changes? 
  322. // What if simulated response time
  323. // is longer and a real client request for the same page happened before the 
  324. // simulated request completes? 
  325. class ProxyTracePagePool : public PagePool {
  326. public:
  327. ProxyTracePagePool();
  328. // : rvDyn_(NULL), rvStatic_(NULL), br_(0), 
  329. // size_(NULL), reqfile_(NULL), req_(NULL), lastseq_(0)
  330. // {}
  331. virtual ~ProxyTracePagePool();
  332. virtual int command(int argc, const char*const* argv);
  333. protected:
  334. // How would we handle different types of page modifications? How 
  335. // to integrate bimodal, and multi-modal distributions?
  336. int init_req(const char *fn);
  337. int init_page(const char *fn);
  338. int find_info();
  339. RandomVariable *rvDyn_, *rvStatic_;
  340. int br_;  // bimodal ratio
  341. int *size_;  // page sizes
  342. FILE *reqfile_; // request stream of proxy trace
  343. struct ClientRequest {
  344. ClientRequest() : seq_(0), nrt_(0), nurl_(0), fpos_(0)
  345. {}
  346. int seq_; // client sequence number, used to match 
  347. // client ids in the trace file
  348. double nrt_; // next request time
  349. int nurl_;  // next request url
  350. long fpos_; // position in file of its next request
  351. };
  352. Tcl_HashTable *req_; // Requests table
  353. int nclient_, lastseq_;
  354. ClientRequest* load_req(int cid);
  355. };
  356. class EPATracePagePool : public ProxyTracePagePool {
  357. public:
  358. virtual int command(int argc, const char*const* argv);
  359. };
  360. #endif //ns_pagepool_h