⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pagepool.cc

📁 柯老师网站上找到的
💻 CC
📖 第 1 页 / 共 3 页
字号:
// 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. //// $Header: /nfs/jade/vint/CVSROOT/ns-2/webcache/pagepool.cc,v 1.14 1999/08/04 21:04:04 haoboy Exp $#include <stdlib.h>#include <sys/types.h>#include <fcntl.h>#ifdef WIN32#include <windows.h>#include <io.h>#else #include <unistd.h>#include <sys/file.h>#endif#include <sys/stat.h>#include <stdio.h>#include <limits.h>#include <ctype.h>extern "C" {#include <otcl.h>}#include "pagepool.h"#include "http.h"// Static/global variablesint ClientPage::PUSHALL_ = 0;	// Initialized to selective pushvoid ServerPage::set_mtime(int *mt, int n){	if (mtime_ != NULL) 		delete []mtime_;	mtime_ = new int[n];	memcpy(mtime_, mt, sizeof(int)*n);}ClientPage::ClientPage(const char *n, int s, double mt, double et, double a) :		Page(s), age_(a), mtime_(mt), etime_(et), 		status_(HTTP_VALID_PAGE), counter_(0), 		mpushTime_(0){	// Parse name to get server and page id	char *buf = new char[strlen(n) + 1];	strcpy(buf, n);	char *tmp = strtok(buf, ":");	server_ = (HttpApp*)TclObject::lookup(tmp);	if (server_ == NULL) {		fprintf(stderr, "Non-exitent server name for page %s", n);		abort();	}	tmp = strtok(NULL, ":");	id_ = atol(tmp);	delete []buf;}void ClientPage::print_name(char* name, PageID& id){	sprintf(name, "%s:%-d", id.s_->name(), id.id_);}void ClientPage::split_name(const char* name, PageID& id){	char *buf = new char[strlen(name)+1];	strcpy(buf, name);	char *tmp = strtok(buf, ":");	id.s_ = (HttpApp*)TclObject::lookup(tmp);	if (id.s_ == NULL) {		fprintf(stderr, "Non-exitent server name for page %s\n", name);		abort();	}	tmp = strtok(NULL, ":");	id.id_ = atol(tmp);	delete []buf;}void ClientPage::print_info(char *buf){	sprintf(buf, "size %d modtime %.17g time %.17g age %.17g",		size(), mtime(), etime(), age());	if (is_uncacheable())		strcat(buf, " noc 1");}void ClientPage::name(char* buf) {	sprintf(buf, "%s:%d", server_->name(), id());}static class PagePoolClass : public TclClass {public:        PagePoolClass() : TclClass("PagePool") {}        TclObject* create(int, const char*const*) {		return (new PagePool());	}} class_pagepool_agent;int PagePool::command(int argc, const char*const* argv){	if (argc == 2) {		// XXX Should be static class variables... 		if (strcmp(argv[1], "set-allpush") == 0) {			ClientPage::PUSHALL_ = 1;			return (TCL_OK);		}		if (strcmp(argv[1], "set-selpush") == 0) {			ClientPage::PUSHALL_ = 0;			return (TCL_OK);		}	}	return TclObject::command(argc, argv);}// TracePagePool// Used for Worrell's filtered server traces only. For handling general // web server traces and proxy traces, have a look at ProxyTracePagePool below.//// Load a trace statistics file, and randomly generate requests and // page lifetimes from the trace.//// Trace statistics file format:// <URL> <size> {<modification time>}static class TracePagePoolClass : public TclClass {public:        TracePagePoolClass() : TclClass("PagePool/Trace") {}        TclObject* create(int argc, const char*const* argv) {		if (argc >= 5)			return (new TracePagePool(argv[4]));		return 0;	}} class_tracepagepool_agent;TracePagePool::TracePagePool(const char *fn) : 	PagePool(), ranvar_(0){	FILE *fp = fopen(fn, "r");	if (fp == NULL) {		fprintf(stderr, 			"TracePagePool: couldn't open trace file %s\n", fn);		abort();	// What else can we do?	}	namemap_ = new Tcl_HashTable;	Tcl_InitHashTable(namemap_, TCL_STRING_KEYS);	idmap_ = new Tcl_HashTable;	Tcl_InitHashTable(idmap_, TCL_ONE_WORD_KEYS);	while (load_page(fp));	change_time();}TracePagePool::~TracePagePool(){	if (namemap_ != NULL) {		Tcl_DeleteHashTable(namemap_);		delete namemap_;	}	if (idmap_ != NULL) {		Tcl_DeleteHashTable(idmap_);		delete idmap_;	}}void TracePagePool::change_time(){	Tcl_HashEntry *he;	Tcl_HashSearch hs;	ServerPage *pg;	int i, j;	for (i = 0, he = Tcl_FirstHashEntry(idmap_, &hs);	     he != NULL;	     he = Tcl_NextHashEntry(&hs), i++) {		pg = (ServerPage *) Tcl_GetHashValue(he);		for (j = 0; j < pg->num_mtime(); j++) 			pg->mtime(j) -= (int)start_time_;	}	end_time_ -= start_time_;	start_time_ = 0;	duration_ = (int)end_time_;}ServerPage* TracePagePool::load_page(FILE *fp){	static char buf[TRACEPAGEPOOL_MAXBUF];	char *delim = " \t\n";	char *tmp1, *tmp2;	ServerPage *pg;	// XXX Use internal variables of struct Page	if (!fgets(buf, TRACEPAGEPOOL_MAXBUF, fp))		return NULL;	// URL	tmp1 = strtok(buf, delim);	// Size	tmp2 = strtok(NULL, delim);	pg = new ServerPage(atoi(tmp2), num_pages_++);	if (add_page(tmp1, pg)) {		delete pg;		return NULL;	}	// Modtimes, assuming they are in ascending time order	int num = 0;	int *nmd = new int[5];	while ((tmp1 = strtok(NULL, delim)) != NULL) {		if (num >= 5) {			int *tt = new int[num+5];			memcpy(tt, nmd, sizeof(int)*num);			delete []nmd;			nmd = tt;		}		nmd[num] = atoi(tmp1);		if (nmd[num] < start_time_)			start_time_ = nmd[num];		if (nmd[num] > end_time_)			end_time_ = nmd[num];		num++;	}	pg->num_mtime() = num;	pg->set_mtime(nmd, num);	delete []nmd;	return pg;}int TracePagePool::add_page(const char* name, ServerPage *pg){	int newEntry = 1;	Tcl_HashEntry *he = Tcl_CreateHashEntry(namemap_, 						(const char *)name,						&newEntry);	if (he == NULL)		return -1;	if (newEntry)		Tcl_SetHashValue(he, (ClientData)pg);	else 		fprintf(stderr, "TracePagePool: Duplicate entry %s\n", 			name);	Tcl_HashEntry *hf = 		Tcl_CreateHashEntry(idmap_, (const char *)pg->id(), &newEntry);	if (hf == NULL) {		Tcl_DeleteHashEntry(he);		return -1;	}	if (newEntry)		Tcl_SetHashValue(hf, (ClientData)pg);	else 		fprintf(stderr, "TracePagePool: Duplicate entry %d\n", 			pg->id());	return 0;}ServerPage* TracePagePool::get_page(int id){	if ((id < 0) || (id >= num_pages_))		return NULL;	Tcl_HashEntry *he = Tcl_FindHashEntry(idmap_, (const char *)id);	if (he == NULL)		return NULL;	return (ServerPage *)Tcl_GetHashValue(he);}int TracePagePool::command(int argc, const char *const* argv){	Tcl &tcl = Tcl::instance();	if (argc == 2) {		if (strcmp(argv[1], "get-poolsize") == 0) {			/* 			 * <pgpool> get-poolsize			 * Get the number of pages currently in pool			 */			tcl.resultf("%d", num_pages_);			return TCL_OK;		} else if (strcmp(argv[1], "get-start-time") == 0) {			tcl.resultf("%.17g", start_time_);			return TCL_OK;		} else if (strcmp(argv[1], "get-duration") == 0) {			tcl.resultf("%d", duration_);			return TCL_OK;		}	} else if (argc == 3) {		if (strcmp(argv[1], "gen-pageid") == 0) {			/* 			 * <pgpool> gen-pageid <client_id>			 * Randomly generate a page id from page pool			 */			double tmp = ranvar_ ? ranvar_->value() : 				Random::uniform();			// tmp should be in [0, num_pages_-1]			tmp = (tmp < 0) ? 0 : (tmp >= num_pages_) ? 				(num_pages_-1):tmp;			if ((int)tmp >= num_pages_) abort();			tcl.resultf("%d", (int)tmp);			return TCL_OK;		} else if (strcmp(argv[1], "gen-size") == 0) {			/*			 * <pgpool> gen-size <pageid>			 */			int id = atoi(argv[2]);			ServerPage *pg = get_page(id);			if (pg == NULL) {				tcl.add_errorf("TracePagePool %s: page %d doesn't exists.\n",					       name_, id);				return TCL_ERROR;			}			tcl.resultf("%d", pg->size());			return TCL_OK;		} else if (strcmp(argv[1], "ranvar") == 0) {			/* 			 * <pgpool> ranvar <ranvar> 			 * Set a random var which is used to randomly pick 			 * a page from the page pool.			 */			ranvar_ = (RandomVariable *)TclObject::lookup(argv[2]);			return TCL_OK;		} else if (strcmp(argv[1], "set-start-time") == 0) {			double st = strtod(argv[2], NULL);			start_time_ = st;			end_time_ += st;		} else if (strcmp(argv[1], "gen-init-modtime") == 0) {			tcl.resultf("%.17g", Scheduler::instance().clock());			return TCL_OK;		}	} else {		if (strcmp(argv[1], "gen-modtime") == 0) {			/* 			 * <pgpool> get-modtime <pageid> <modtime>			 * 			 * Return next modtime that is larger than modtime			 * To retrieve the first modtime (creation time), set 			 * <modtime> to -1 in the request.			 */			int id = atoi(argv[2]);			double mt = strtod(argv[3], NULL);			ServerPage *pg = get_page(id);			if (pg == NULL) {				tcl.add_errorf("TracePagePool %s: page %d doesn't exists.\n",					       name_, id);				return TCL_ERROR;			}			for (int i = 0; i < pg->num_mtime(); i++) 				if (pg->mtime(i) > mt) {					tcl.resultf("%.17g", 						    pg->mtime(i)+start_time_);					return TCL_OK;				}			// When get to the last modtime, return -1			tcl.resultf("%d", INT_MAX);			return TCL_OK;		}	}	return PagePool::command(argc, argv);}static class MathPagePoolClass : public TclClass {public:        MathPagePoolClass() : TclClass("PagePool/Math") {}        TclObject* create(int, const char*const*) {		return (new MathPagePool());	}} class_mathpagepool_agent;// Use 3 ranvars to generate requests, mod times and page sizeint MathPagePool::command(int argc, const char *const* argv){	Tcl& tcl = Tcl::instance();	// Keep the same tcl interface as PagePool/Trace	if (argc == 2) {		if (strcmp(argv[1], "get-poolsize") == 0) { 			tcl.result("1");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -