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

通讯编程

开发平台:

Visual C++

  1. // Generate statistics from UCB traces
  2. // All we need to know: 
  3. // 
  4. // (1) client request streams: 
  5. //     <time> <clientID> <serverID> <URL_ID> 
  6. // (2) server page mod stream(s):
  7. //     <serverID> <URL_ID> <PageSize> <access times>
  8. //
  9. // Part of the code comes from Steven Gribble's UCB trace parse codes
  10. // 
  11. // $Header: /cvsroot/nsnam/ns-2/indep-utils/webtrace-conv/nlanr/tr-stat.cc,v 1.3 2005/09/18 23:33:33 tomh Exp $
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <time.h>
  17. #include <sys/types.h>
  18. #include <sys/socket.h>
  19. #include <netinet/in.h>
  20. #include <arpa/inet.h>
  21. #include <tcl.h>
  22. #include "logparse.h"
  23. Tcl_HashTable cidHash;  // Client id (IP, port) hash
  24. int client = 0; // client sequence number
  25. Tcl_HashTable sidHash; // server id (IP, port) hash
  26. int server = 0; // server sequence number
  27. Tcl_HashTable urlHash; // URL id hash
  28. int url = 0; // URL sequence number
  29. int* umap; // URL mapping table, used for url sort
  30. struct URL {
  31. URL(int i, int sd, int sz) : access(1), id(i), sid(sd), size(sz) {}
  32. int access; // access counts
  33. int id;
  34. int sid, size;
  35. };
  36. FILE *cf, *sf;
  37. double initTime = -1;
  38. double duration = -1;
  39. double startTime = -1;
  40. struct ReqLog {
  41. ReqLog() {}
  42. ReqLog(double t, unsigned int c, unsigned int s, unsigned int u) :
  43. time(t), cid(c), sid(s), url(u) {}
  44. double time;
  45. unsigned int cid, sid, url;
  46. };
  47. ReqLog* rlog = NULL;
  48. unsigned int num_rlog = 0, sz_rlog = 0;
  49. int compare(const void *a1, const void *b1)
  50. {
  51. const ReqLog *a = (const ReqLog*)a1, *b = (const ReqLog*)b1;
  52. return (a->time > b->time) ? 1 : 
  53. (a->time == b->time) ? 0 : -1;
  54. }
  55. void sort_rlog()
  56. {
  57. qsort((void *)rlog, num_rlog, sizeof(ReqLog), compare);
  58. double t = rlog[0].time;
  59. for (unsigned int i = 0; i < num_rlog; i++) {
  60. rlog[i].time -= t;
  61. fprintf(cf, "%f %d %d %dn", rlog[i].time, 
  62. rlog[i].cid, rlog[i].sid, umap[rlog[i].url]);
  63. }
  64. delete []umap;
  65. // Record trace duration and # of unique urls
  66. fprintf(cf, "i %f %un", rlog[num_rlog-1].time, url);
  67. }
  68. int compare_url(const void* a1, const void* b1)
  69. {
  70. const URL **a = (const URL**)a1, **b = (const URL**)b1;
  71. return ((*a)->access > (*b)->access) ? -1:
  72. ((*a)->access == (*b)->access) ? 0 : 1;
  73. }
  74. void sort_url()
  75. {
  76. // XXX use an interval member of Tcl_HashTable
  77. URL** tbl = new URL*[urlHash.numEntries];
  78. Tcl_HashEntry *he;
  79. Tcl_HashSearch hs;
  80. int i = 0, sz = urlHash.numEntries;
  81. for (he = Tcl_FirstHashEntry(&urlHash, &hs);
  82.      he != NULL;
  83.      he = Tcl_NextHashEntry(&hs))
  84. tbl[i++] = (URL*)Tcl_GetHashValue(he);
  85. Tcl_DeleteHashTable(&urlHash);
  86. // sort using access frequencies
  87. qsort((void *)tbl, sz, sizeof(URL*), compare_url);
  88. umap = new int[url];
  89. // write sorted url to page table
  90. for (i = 0; i < sz; i++) {
  91. umap[tbl[i]->id] = i;
  92. fprintf(sf, "%d %d %d %un", tbl[i]->sid, i,
  93. tbl[i]->size, tbl[i]->access);
  94. delete tbl[i];
  95. }
  96. delete []tbl;
  97. }
  98. double lf_analyze(lf_entry& lfe)
  99. {
  100. double time;
  101. int ne, cid, sid, uid;
  102. Tcl_HashEntry *he;
  103. time = lfe.rt;
  104. if (initTime < 0) {
  105. initTime = time;
  106. time = 0;
  107. } else 
  108. time -= initTime;
  109. // If a trace start time is required, don't do anything
  110. if ((startTime > 0) && (time < startTime)) 
  111. return -1;
  112. // Ignore pages with size 0
  113. if (lfe.size == 0) 
  114. return -1;
  115. // check client id
  116. long clientKey = lfe.cid;
  117. if (!(he = Tcl_FindHashEntry(&cidHash, (const char *)clientKey))) {
  118. // new client, allocate a client id
  119. he = Tcl_CreateHashEntry(&cidHash, (const char *)clientKey, &ne);
  120. Tcl_SetHashValue(he, (long)++client);
  121. cid = client;
  122. } else {
  123. // existing entry, find its client seqno
  124. cid = (long)Tcl_GetHashValue(he);
  125. }
  126. // check server id
  127. if (!(he = Tcl_FindHashEntry(&sidHash, lfe.sid))) {
  128. // new server, assign a server id
  129. he = Tcl_CreateHashEntry(&sidHash, lfe.sid, &ne);
  130. server++;
  131. long serverValue = server;
  132. Tcl_SetHashValue(he, serverValue);
  133. sid = server;
  134. } else {
  135. // existing entry, find its client seqno
  136. sid = (long)Tcl_GetHashValue(he);
  137. }
  138. // check url id
  139. if (!(he = Tcl_FindHashEntry(&urlHash, lfe.url))) {
  140. // new client, allocate a client id
  141. he = Tcl_CreateHashEntry(&urlHash, lfe.url, &ne);
  142. URL* u = new URL(++url, sid, lfe.size);
  143. Tcl_SetHashValue(he, (const char*)u);
  144. uid = u->id;
  145. //fprintf(sf, "%d %d %ldn", sid, u->id, lfe.rhl+lfe.rdl);
  146. } else {
  147. // existing entry, find its client seqno
  148. URL* u = (URL*)Tcl_GetHashValue(he);
  149. u->access++;
  150. uid = u->id;
  151. }
  152. rlog[num_rlog++] = ReqLog(time, cid, sid, uid);
  153. //fprintf(cf, "%f %d %d %dn", time, cid, sid, uid);
  154. if (startTime > 0) 
  155. return time - startTime;
  156. else 
  157. return time;
  158. }
  159. int main(int argc, char**argv)
  160. {
  161. lf_entry lfntree;
  162. int      ret;
  163. double   ctime;
  164. // Init tcl
  165. Tcl_Interp *interp = Tcl_CreateInterp();
  166. if (Tcl_Init(interp) == TCL_ERROR) {
  167. printf("%sn", interp->result);
  168. abort();
  169. }
  170. Tcl_InitHashTable(&cidHash, TCL_ONE_WORD_KEYS);
  171. Tcl_InitHashTable(&sidHash, TCL_STRING_KEYS);
  172. Tcl_InitHashTable(&urlHash, TCL_STRING_KEYS);
  173. if ((cf = fopen("reqlog", "w")) == NULL) {
  174. printf("cannot open request log.n");
  175. exit(1);
  176. }
  177. if ((sf = fopen("pglog", "w")) == NULL) {
  178. printf("cannot open page log.n");
  179. exit(1);
  180. }
  181. if ((argc < 2) || (argc > 4)) {
  182. printf("Usage: %s <trace size> [<time duration>] [<start_time>]n", argv[0]);
  183. return 1;
  184. }
  185. if (argc >= 3) {
  186. duration = strtod(argv[2], NULL);
  187. if (argc == 4) {
  188. startTime = strtod(argv[3], NULL);
  189. printf("start time = %fn", startTime);
  190. }
  191. }
  192. sz_rlog = strtoul(argv[1], NULL, 10);
  193. rlog = new ReqLog[sz_rlog];
  194. while(1) {
  195. ret = lf_get_next_entry(stdin, lfntree);
  196. if (ret > 0) {
  197. if (ret == 1) {
  198. /* EOF */
  199. break;
  200. }
  201. fprintf(stderr, "Failed to get next entry.n");
  202. exit(1);
  203. } else if (ret < 0) {
  204. // Unusable entry, i.e., cache miss, cgi-bin, etc.
  205. continue;
  206. }
  207. // Analyse one log entry
  208. ctime = lf_analyze(lfntree);
  209. delete []lfntree.url;
  210. delete []lfntree.sid;
  211. if ((duration > 0) && (ctime > duration))
  212. break;
  213. }
  214. Tcl_DeleteHashTable(&cidHash);
  215. Tcl_DeleteHashTable(&sidHash);
  216. fprintf(stderr, "sort urln");
  217. sort_url();
  218. fclose(sf);
  219. fprintf(stderr, "sort requestsn");
  220. sort_rlog();
  221. fclose(cf);
  222. fprintf(stderr, 
  223. "%d unique clients, %d unique servers, %d unique urls.n", 
  224. client, server, url);
  225. return 0;
  226. }