/* Web Polygraph http://www.web-polygraph.org/
* (C) 2003-2006 The Measurement Factory
* Licensed under the Apache License, Version 2.0 */
#include "pgl/pgl.h"
#include "xstd/String.h"
#include "xstd/rndDistrs.h"
#include "base/RndPermut.h"
#include "pgl/PglBoolSym.h"
#include "pgl/PglIntSym.h"
#include "pgl/PglNumSym.h"
#include "pgl/PglRateSym.h"
#include "pgl/PglRec.h"
#include "pgl/PglStringSym.h"
#include "pgl/PglNetAddrSym.h"
#include "pgl/PglArraySym.h"
#include "pgl/AclSym.h"
#include "pgl/DnsResolverSym.h"
#include "pgl/SessionSym.h"
#include "pgl/RobotSym.h"
const String RobotSym::TheType = "Robot";
static String strAcl = "acl";
static String strAddrArr = "addr[]";
static String strAuth_error = "auth_error";
static String strCredentials = "credentials";
static String strDns_resolver = "dns_resolver";
static String strEmbed_recur = "embed_recur";
static String strForeign_trace = "foreign_trace";
static String strRaw_uri_thrower = "raw_uri_thrower";
static String strIcp_port = "icp_port";
static String strInterests = "interests";
static String strMinimize_new_conn = "minimize_new_conn";
static String strOpen_conn_lmt = "open_conn_lmt";
static String strOrigins = "origins";
static String strPeer_http = "peer_http";
static String strPeer_icp = "peer_icp";
static String strPrivate_cache_cap = "private_cache_cap";
static String strProxies = "proxies";
static String strRecurrence = "recurrence";
static String strReq_inter_arrival = "req_inter_arrival";
static String strReq_methods = "req_methods";
static String strContainerTags = "container_tags";
static String strReq_rate = "req_rate";
static String strReq_types = "req_types";
static String strSession = "session";
static String strStringArr = "string[]";
static String strTime_distr = "time_distr";
static String strFloat_distr = "float_distr";
static String strSize_distr = "size_distr";
static String strUnique_urls = "unique_urls";
static String strWait_xact_lmt = "wait_xact_lmt";
static String strPipeline_depth = "pipeline_depth";
static String strCookies_keep_lmt = "cookies_keep_lmt";
static String strAcceptContentEncodings = "accept_content_encodings";
RobotSym::RobotSym(): AgentSym(TheType) {
theRec->bAdd(strAddrArr, strProxies, 0);
theRec->bAdd(strAddrArr, strOrigins, 0);
theRec->bAdd(RateSym::TheType, strReq_rate, 0);
theRec->bAdd(strTime_distr, strReq_inter_arrival, 0);
theRec->bAdd(NumSym::TheType, strRecurrence, 0);
theRec->bAdd(NumSym::TheType, strEmbed_recur, 0);
theRec->bAdd(strStringArr, strInterests, 0);
theRec->bAdd(strStringArr, strReq_types, 0);
theRec->bAdd(strStringArr, strReq_methods, 0);
theRec->bAdd(strStringArr, strContainerTags, 0);
theRec->bAdd(strStringArr, strAcceptContentEncodings, 0);
theRec->bAdd(IntSym::TheType, strPrivate_cache_cap, 0);
theRec->bAdd(BoolSym::TheType, strUnique_urls, 0);
theRec->bAdd(IntSym::TheType, strOpen_conn_lmt, 0);
theRec->bAdd(IntSym::TheType, strWait_xact_lmt, 0);
theRec->bAdd(NumSym::TheType, strMinimize_new_conn, 0);
theRec->bAdd(strStringArr, strCredentials, 0);
theRec->bAdd(NumSym::TheType, strAuth_error, 0);
theRec->bAdd(AclSym::TheType, strAcl, new AclSym);
theRec->bAdd(SessionSym::TheType, strSession, new SessionSym);
theRec->bAdd(IntSym::TheType, strIcp_port, 0);
theRec->bAdd(NetAddrSym::TheType, strPeer_http, 0);
theRec->bAdd(NetAddrSym::TheType, strPeer_icp, 0);
theRec->bAdd(DnsResolverSym::TheType, strDns_resolver, new DnsResolverSym);
theRec->bAdd(StringSym::TheType, strForeign_trace, 0);
theRec->bAdd(StringSym::TheType, strRaw_uri_thrower, 0);
theRec->bAdd(strFloat_distr, strPipeline_depth, 0);
theRec->bAdd(strFloat_distr, strCookies_keep_lmt, 0);
}
RobotSym::RobotSym(const String &aType, PglRec *aRec): AgentSym(aType, aRec) {
}
bool RobotSym::isA(const String &type) const {
return AgentSym::isA(type) || type == TheType;
}
SynSym *RobotSym::dupe(const String &type) const {
if (isA(type))
return new RobotSym(this->type(), theRec->clone());
return AgentSym::dupe(type);
}
bool RobotSym::reqRate(double &rate) const {
return getRate(strReq_rate, rate);
}
bool RobotSym::reqInterArrival(RndDistr *&iad) const {
iad = getDistr(strReq_inter_arrival);
double rr = -1;
const bool hasRR = reqRate(rr);
if (hasRR && iad)
cerr << loc() << ": cannot specify both request rate"
<< " and inter-arrival distribution" << endl << xexit;
if (iad)
return true;
if (!hasRR)
return false;
if (rr <= 0)
return true; // iad is nil
// poisson request stream (default) is modeled using an exponential
// distribution with a mean of a given request rate
// all clients should share one rng
static RndGen rng(GlbPermut(rndRobotSymReqInterArrival));
iad = new ExpDistr(&rng, 1/rr);
return true;
}
bool RobotSym::recurRatio(double &ratio) const {
return getDouble(strRecurrence, ratio);
}
bool RobotSym::embedRecurRatio(double &ratio) const {
return getDouble(strEmbed_recur, ratio);
}
bool RobotSym::uniqueUrls(bool &set) const {
return getBool(strUnique_urls, set);
}
bool RobotSym::openConnLimit(int &lmt) const {
return getInt(strOpen_conn_lmt, lmt);
}
bool RobotSym::waitXactLimit(int &lmt) const {
return getInt(strWait_xact_lmt, lmt);
}
bool RobotSym::minimizeNewConn(double &prob) const {
return getDouble(strMinimize_new_conn, prob);
}
SessionSym *RobotSym::session() const {
const SynSym *ss = getRecSym(strSession);
return ss ?
&((SessionSym&)ss->cast(SessionSym::TheType)) : 0;
}
bool RobotSym::authError(double &prob) const {
return getDouble(strAuth_error, prob);
}
bool RobotSym::icpPort(int &port) const {
return getInt(strIcp_port, port);
}
NetAddr RobotSym::peerHttp() const {
return getNetAddr(strPeer_http);
}
NetAddr RobotSym::peerIcp() const {
return getNetAddr(strPeer_icp);
}
AclSym *RobotSym::acl() const {
SynSymTblItem *i = 0;
Assert(theRec->find(strAcl, i));
return i->sym() ?
&((AclSym&)i->sym()->cast(AclSym::TheType)) : 0;
}
DnsResolverSym *RobotSym::dnsResolver() const {
SynSymTblItem *di = 0;
Assert(theRec->find(strDns_resolver, di));
return di->sym() ?
&((DnsResolverSym&)di->sym()->cast(DnsResolverSym::TheType)) : 0;
}
bool RobotSym::privCache(int &capacity) const {
return getInt(strPrivate_cache_cap, capacity);
}
bool RobotSym::proxies(Array<NetAddr*> &addrs) const {
return getNetAddrs(strProxies, addrs);
}
bool RobotSym::origins(Array<NetAddr*> &addrs) const {
return getNetAddrs(strOrigins, addrs);
}
bool RobotSym::origins(Array<NetAddr*> &addrs, RndDistr *&selector) const {
SynSymTblItem *oi = 0;
Assert(theRec->find(strOrigins, oi));
if (!oi->sym())
return false; // undefined
// build address array and selector
origins(addrs);
ArraySym &os = (ArraySym&)oi->sym()->cast(ArraySym::TheType);
selector = os.makeSelector(kind() + "-origins");
return true;
}
String RobotSym::msgTypesField() const {
return strReq_types;
}
bool RobotSym::credentials(Array<String*> &creds) const {
return getStrings(strCredentials, creds);
}
bool RobotSym::containerTags(Array<String*> &tags) const {
return getStrings(strContainerTags, tags);
}
bool RobotSym::acceptedContentCodings(Array<String*> &codings) const {
return getStrings(strAcceptContentEncodings, codings);
}
bool RobotSym::interests(Array<StringSym*> &istrs, Array<double> &iprobs) const {
if (ArraySym *a = getArraySym(strInterests)) {
a->copyProbs(iprobs);
ArraySymExportM(StringSym, *a, StringSym::TheType, istrs);
return true;
}
return false;
}
RndDistr *RobotSym::interests(const StrIdentifier &interestKinds) const {
return namesToDistr(strInterests, interestKinds);
}
RndDistr *RobotSym::reqMethods(const StrIdentifier &reqMethodNames) const {
return namesToDistr(strReq_methods, reqMethodNames);
}
RndDistr *RobotSym::pipelineDepth() const {
return getDistr(strPipeline_depth);
}
String RobotSym::foreignTrace() const {
return getString(strForeign_trace);
}
String RobotSym::rawUriThrower() const {
return getString(strRaw_uri_thrower);
}
RndDistr *RobotSym::cookiesKeepLimit() const {
return getDistr(strCookies_keep_lmt);
}
syntax highlighted by Code2HTML, v. 0.9.1