📄 http-aux.h
字号:
// Copyright (c) Xerox Corporation 1998. All rights reserved.//// License is granted to copy, to use, and to make and to use derivative// works for research and evaluation purposes, provided that Xerox is// acknowledged in all documentation pertaining to any such copy or// derivative work. Xerox grants no other licenses expressed or// implied. The Xerox trade name should not be used in any advertising// without its written permission. //// XEROX CORPORATION MAKES NO REPRESENTATIONS CONCERNING EITHER THE// MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE// FOR ANY PARTICULAR PURPOSE. The software is provided "as is" without// express or implied warranty of any kind.//// These notices must be retained in any copies of any part of this// software. //// Auxiliary classes for HTTP multicast invalidation proxy cache//// $Header: /nfs/jade/vint/CVSROOT/ns-2/webcache/http-aux.h,v 1.16 1999/09/08 20:27:37 haoboy Exp $#ifndef ns_http_aux_h#define ns_http_aux_h#include <tclcl.h>#include "random.h"#include "ns-process.h"#include "pagepool.h"#include "timer-handler.h"const int HTTP_HBEXPIRE_COUNT = 5; // How many lost HBs mean disconnection?const int HTTP_HBINTERVAL = 60;// Heartbeat intervals (seconds)const int HTTP_UPDATEINTERVAL = 5; // Delays to push/v1 (seconds)class HttpMInvalCache;// Used for caches to keep track of invalidationsclass InvalidationRec {public: InvalidationRec(const char *pid, double mtime, char updating = 0) { pg_ = new char[strlen(pid) + 1]; strcpy(pg_, pid); mtime_ = mtime; scount_ = HTTP_HBEXPIRE_COUNT; updating_ = updating; next_ = 0, prev_ = 0; } virtual ~InvalidationRec() { delete []pg_; } const char* pg() const { return pg_; } double mtime() const { return mtime_; } char updating() const { return updating_; } int scount() const { return scount_; } InvalidationRec* next() { return next_; } void reset(double mtime) { scount_ = HTTP_HBEXPIRE_COUNT; mtime_ = mtime; } int dec_scount() { return --scount_; } void set_updating() { updating_ = 1; } void clear_updating() { updating_ = 0; } void insert(InvalidationRec **head) { next_ = *head; if (next_ != 0) next_->prev_ = &next_; prev_ = head; *head = this; } void detach() { if (prev_ != 0) *prev_ = next_; if (next_ != 0) next_->prev_ = prev_; } friend class HttpMInvalCache;protected: char *pg_; double mtime_; char updating_; // 1 if an update is going to be sent soon int scount_; // Times that an invalidation needs to be multicast InvalidationRec *next_; InvalidationRec **prev_;};class HBTimer : public TimerHandler {public: HBTimer(HttpMInvalCache *a, double interval) : TimerHandler() { a_ = a, interval_ = interval; } void set_interval(double interval) { interval_ = interval; } double get_interval() const { return interval_; } double next_interval() { return interval_ * (1 + Random::uniform(-0.1,0.1)); } void sched() { TimerHandler::sched(interval_); } void resched() { TimerHandler::resched(next_interval()); }protected: virtual void expire(Event *e); virtual void handle(Event *e) { TimerHandler::handle(e); resched(); } HttpMInvalCache *a_; double interval_;};class PushTimer : public TimerHandler {public: PushTimer(HttpMInvalCache *a, double itv) : TimerHandler(), a_(a), interval_(itv) {} void set_interval(double itv) { interval_ = itv; } double get_interval() const { return interval_; } void sched() { TimerHandler::sched(interval_); }protected: virtual void expire(Event *e); HttpMInvalCache *a_; double interval_;};class LivenessTimer : public TimerHandler {public: LivenessTimer(HttpMInvalCache *a, double itv, int nbr) : TimerHandler(), a_(a), nbr_(nbr), interval_(itv) {} void sched() { TimerHandler::sched(interval_); } void resched() { TimerHandler::resched(interval_); }protected: virtual void expire(Event *e); HttpMInvalCache *a_; // The cache to be alerted int nbr_; // Neighbor cache id double interval_;};// XXX ADU defined in app-connector.hconst int HTTPDATA_COST = 8;// User-level packetsclass HttpData : public AppData {private: int id_; // ID of the senderpublic: HttpData() : AppData(HTTP_DATA) {} HttpData(AppDataType t, int d) : AppData(t) { id_ = d; } HttpData(HttpData& d) : AppData(d) { id_ = d.id_; } inline int& id() { return id_; } virtual int size() const { return sizeof(HttpData); } virtual int cost() const { return HTTPDATA_COST; } virtual AppData* copy() { return (new HttpData(*this)); }};// HTTP data during normal request and response: containing a tcl commandclass HttpNormalData : public HttpData {private: char *str_; int strlen_; int cost_;public: // XXX Whoever sends data should allocate memory to store the string. // Whoever receives this object should delete it to free the string. HttpNormalData(int id, int cost, const char *str) : HttpData(HTTP_NORMAL, id) { if ((str == NULL) || (*str == 0)) strlen_ = 0; else strlen_ = strlen(str) + 1; if (strlen_ > 0) { str_ = new char[strlen_]; strcpy(str_, str); } else str_ = NULL; cost_ = cost; } HttpNormalData(HttpNormalData& d) : HttpData(d) { cost_ = d.cost_; strlen_ = d.strlen_; if (strlen_ > 0) { str_ = new char[strlen_]; strcpy(str_, d.str_); } else str_ = NULL; } virtual ~HttpNormalData() { if (str_ != NULL) delete []str_; } virtual int size() const { // Intentially use sizeof(int) instead of 2*sizeof(int) return (sizeof(HttpData)+sizeof(int)+strlen_); } virtual int cost() const { return cost_; } char* str() const { return str_; } virtual AppData* copy() { return (new HttpNormalData(*this)); }};// XXX assign cost to a constant so as to be more portableconst int HTTPHBDATA_COST = 32;const int HTTP_MAXURLLEN = 20;// Struct used to pack invalidation records into packetsclass HttpHbData : public HttpData {protected: struct InvalRec { char pg_[HTTP_MAXURLLEN]; // Maximum page id length double mtime_; // Used only to mark that this page will be send in the // next multicast update. The updating field in this agent // will only be set after it gets the real update. int updating_; void copy(InvalidationRec *v) { strcpy(pg_, v->pg()); mtime_ = v->mtime(); updating_ = v->updating(); } InvalidationRec* copyto() { return (new InvalidationRec(pg_, mtime_, updating_)); } };private: int num_inv_; InvalRec* inv_rec_; inline InvalRec* inv_rec() { return inv_rec_; }public: HttpHbData(int id, int n) : HttpData(HTTP_INVALIDATION, id), num_inv_(n) { if (num_inv_ > 0) inv_rec_ = new InvalRec[num_inv_]; else inv_rec_ = NULL; } HttpHbData(HttpHbData& d) : HttpData(d) { num_inv_ = d.num_inv_; if (num_inv_ > 0) { inv_rec_ = new InvalRec[num_inv_]; memcpy(inv_rec_, d.inv_rec_,num_inv_*sizeof(InvalRec)); } else inv_rec_ = NULL; } virtual ~HttpHbData() { if (inv_rec_ != NULL) delete []inv_rec_; } virtual int size() const { return HttpData::size() + num_inv_*sizeof(InvalRec); } // XXX byte cost to appear in trace file virtual int cost() const { // Minimum size 1 so that TCP will send a packet return (num_inv_ == 0) ? 1 : (num_inv_*HTTPHBDATA_COST); } virtual AppData* copy() { return (new HttpHbData(*this)); } inline int& num_inv() { return num_inv_; } inline void add(int i, InvalidationRec *r) { inv_rec()[i].copy(r); } inline char* rec_pg(int i) { return inv_rec()[i].pg_; } inline double& rec_mtime(int i) { return inv_rec()[i].mtime_; } void extract(InvalidationRec*& ivlist);};class HttpUpdateData : public HttpData {protected: // Pack page updates to be pushed to caches struct PageRec { char pg_[HTTP_MAXURLLEN]; double mtime_; double age_; int size_; void copy(ClientPage *p) { p->name(pg_); mtime_ = p->mtime(); age_ = p->age(); size_ = p->size(); } };private: int num_; int pgsize_; PageRec *rec_; inline PageRec* rec() { return rec_; }public: HttpUpdateData(int id, int n) : HttpData(HTTP_UPDATE, id) { num_ = n; pgsize_ = 0; if (num_ > 0) rec_ = new PageRec[num_]; else rec_ = NULL; } HttpUpdateData(HttpUpdateData& d) : HttpData(d) { num_ = d.num_; pgsize_ = d.pgsize_; if (num_ > 0) { rec_ = new PageRec[num_]; memcpy(rec_, d.rec_, num_*sizeof(PageRec)); } else rec_ = NULL; } virtual ~HttpUpdateData() { if (rec_ != NULL) delete []rec_; } virtual int size() const { return HttpData::size() + 2*sizeof(int)+num_*sizeof(PageRec); } virtual int cost() const { return pgsize_; } virtual AppData* copy() { return (new HttpUpdateData(*this)); } inline int num() const { return num_; } inline int pgsize() const { return pgsize_; } inline void set_pgsize(int s) { pgsize_ = s; } inline void add(int i, ClientPage *p) { rec()[i].copy(p); pgsize_ += p->size(); } inline char* rec_page(int i) { return rec()[i].pg_; } inline int& rec_size(int i) { return rec()[i].size_; } inline double& rec_age(int i) { return rec()[i].age_; } inline double& rec_mtime(int i) { return rec()[i].mtime_; }};const int HTTPLEAVE_COST = 4;// Message: server leaveclass HttpLeaveData : public HttpData {private: int num_; int* rec_; // array of server ids which are out of contact inline int* rec() { return rec_; }public: HttpLeaveData(int id, int n) : HttpData(HTTP_LEAVE, id) { num_ = n; if (num_ > 0) rec_ = new int[num_]; else rec_ = NULL; } HttpLeaveData(HttpLeaveData& d) : HttpData(d) { num_ = d.num_; if (num_ > 0) { rec_ = new int[num_]; memcpy(rec_, d.rec_, num_*sizeof(int)); } else rec_ = NULL; } virtual ~HttpLeaveData() { if (rec_ != NULL) delete []rec_; } virtual int size() const { return HttpData::size() + (num_+1)*sizeof(int); } virtual int cost() const { return num_*HTTPLEAVE_COST; } virtual AppData* copy() { return (new HttpLeaveData(*this)); } inline int num() const { return num_; } inline void add(int i, int id) { rec()[i] = id; } inline int rec_id(int i) { return rec()[i]; }};// Auxliary classclass NeighborCache {public: NeighborCache(HttpMInvalCache*c, double t, LivenessTimer *timer) : cache_(c), time_(t), down_(0), timer_(timer) {} ~NeighborCache(); double time() { return time_; } void reset_timer(double time) { time_ = time, timer_->resched(); } int is_down() { return down_; } void down() { down_ = 1; } void up() { down_ = 0; } int num() const { return sl_.num(); } HttpMInvalCache* cache() { return cache_; } void pack_leave(HttpLeaveData&); int is_server_down(int sid); void server_down(int sid); void server_up(int sid); void invalidate(HttpMInvalCache *c); void add_server(int sid); // Maintaining neighbor cache timeout entries struct ServerEntry { ServerEntry(int sid) : server_(sid), next_(NULL), down_(0) {} int server() { return server_; } ServerEntry* next() { return next_; } int is_down() { return down_; } void down() { down_ = 1; } void up() { down_ = 0; } int server_; ServerEntry *next_; int down_; }; // We cannot use template. :((( struct ServerList { ServerList() : head_(NULL), num_(0) {} void insert(ServerEntry *s) { s->next_ = head_; head_ = s; num_++; } // We don't need a detach() ServerEntry* gethead() { return head_; } // For iterations int num() const { return num_; } ServerEntry *head_; int num_; };protected: HttpMInvalCache* cache_; double time_; int down_; ServerList sl_; LivenessTimer *timer_;};#endif // ns_http_aux_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -