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

通讯编程

开发平台:

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>
  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/dec/tr-stat.cc,v 1.3 2005/09/18 23:33:32 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 "proxytrace.h"
  23. FILE *cf, *sf;
  24. double initTime = -1;
  25. double duration = -1;
  26. double startTime = -1;
  27. Tcl_HashTable cidHash;  // Client id (IP, port) hash
  28. static int client = 0; // client sequence number
  29. Tcl_HashTable sidHash; // server id (IP, port) hash
  30. static int server = 0; // server sequence number
  31. Tcl_HashTable urlHash; // URL id hash
  32. static int url = 0; // URL sequence number
  33. static int* umap; // URL mapping table, used for url sort
  34. ReqLog* rlog = NULL;
  35. unsigned int num_rlog = 0, sz_rlog = 0;
  36. static int compare(const void *a1, const void *b1)
  37. {
  38. const ReqLog *a = (const ReqLog*)a1, *b = (const ReqLog*)b1;
  39. return (a->time > b->time) ? 1 : 
  40. (a->time == b->time) ? 0 : -1;
  41. }
  42. void sort_rlog()
  43. {
  44. qsort((void *)rlog, num_rlog, sizeof(ReqLog), compare);
  45. double t = rlog[0].time;
  46. for (unsigned int i = 0; i < num_rlog; i++) {
  47. rlog[i].time -= t;
  48. fprintf(cf, "%f %d %d %dn", rlog[i].time, 
  49. rlog[i].cid, rlog[i].sid, umap[rlog[i].url]);
  50. }
  51. // Record trace duration and # of unique urls
  52. fprintf(cf, "i %f %un", rlog[num_rlog-1].time, url);
  53. fprintf(stderr, 
  54. "%d unique clients, %d unique servers, %d unique urls.n", 
  55. client, server, url);
  56. }
  57. static int compare_url(const void* a1, const void* b1)
  58. {
  59. const URL **a = (const URL**)a1, **b = (const URL**)b1;
  60. return ((*a)->access > (*b)->access) ? -1:
  61. ((*a)->access == (*b)->access) ? 0 : 1;
  62. }
  63. void sort_url()
  64. {
  65. // XXX use an interval member of Tcl_HashTable
  66. URL** tbl = new URL*[urlHash.numEntries];
  67. Tcl_HashEntry *he;
  68. Tcl_HashSearch hs;
  69. int i = 0, sz = urlHash.numEntries;
  70. for (he = Tcl_FirstHashEntry(&urlHash, &hs);
  71.      he != NULL;
  72.      he = Tcl_NextHashEntry(&hs))
  73. tbl[i++] = (URL*)Tcl_GetHashValue(he);
  74. Tcl_DeleteHashTable(&urlHash);
  75. // sort using access frequencies
  76. qsort((void *)tbl, sz, sizeof(URL*), compare_url);
  77. umap = new int[url];
  78. // write sorted url to page table
  79. for (i = 0; i < sz; i++) {
  80. umap[tbl[i]->id] = i;
  81. fprintf(sf, "%d %d %d %un", tbl[i]->sid, i,
  82. tbl[i]->size, tbl[i]->access);
  83. delete tbl[i];
  84. }
  85. delete []tbl;
  86. }
  87. const unsigned long MAX_FILESIZE = 10000000;
  88. double lf_analyze(TEntry& lfe)
  89. {
  90. double time;
  91. int ne, cid, sid, uid;
  92. Tcl_HashEntry *he;
  93. // Filter out entries with 'post', 'head' etc. only keep 'get'
  94. // Also filter out 
  95. if (lfe.tail.method != METHOD_GET)
  96. return -1;
  97. if ((lfe.tail.flags & QUERY_FOUND_FLAG) || 
  98.     (lfe.tail.flags & CGI_BIN_FLAG))
  99. return -1;
  100. if ((lfe.tail.status != 200) && (lfe.tail.status != 304))
  101. return -1;
  102. // We don't consider pages with size 0
  103. if (lfe.head.size == 0)
  104. return -1;
  105. // We don't consider file size larger than 10MB
  106. if (lfe.head.size > MAX_FILESIZE)
  107. return -1;
  108. time = (double)lfe.head.time_sec + (double)lfe.head.time_usec/(double)1000000.0;
  109. if (initTime < 0) {
  110. initTime = time;
  111. time = 0;
  112. } else 
  113. time -= initTime;
  114. // If a trace start time is required, don't do anything
  115. if ((startTime > 0) && (time < startTime)) 
  116. return -1;
  117. // check client id
  118. long clientKey = lfe.head.client;
  119. if (!(he = Tcl_FindHashEntry(&cidHash, (const char *)clientKey))) {
  120. // new client, allocate a client id
  121. he = Tcl_CreateHashEntry(&cidHash, (const char *)clientKey, &ne);
  122. client++;
  123. long clientValue = client;
  124. Tcl_SetHashValue(he, clientValue);
  125. cid = client;
  126. } else {
  127. // existing entry, find its client seqno
  128. cid = (long)Tcl_GetHashValue(he);
  129. }
  130. // check server id
  131. long serverKey = lfe.head.server;
  132. if (!(he = Tcl_FindHashEntry(&sidHash, (const char *)serverKey))) {
  133. // new client, allocate a client id
  134. he = Tcl_CreateHashEntry(&sidHash, (const char *)serverKey, &ne);
  135. server++;
  136. long serverValue = server;
  137. Tcl_SetHashValue(he, serverValue);
  138. sid = server;
  139. } else {
  140. // existing entry, find its client seqno
  141. sid = (long)Tcl_GetHashValue(he);
  142. }
  143. // check url id
  144. long urlKey = lfe.url;
  145. if (!(he = Tcl_FindHashEntry(&urlHash, (const char*)urlKey))) {
  146. // new client, allocate a client id
  147. he = Tcl_CreateHashEntry(&urlHash, (const char*)urlKey, &ne);
  148. URL* u = new URL(++url, sid, lfe.head.size);
  149. Tcl_SetHashValue(he, (const char*)u);
  150. uid = u->id;
  151. } else {
  152. // existing entry, find its client seqno
  153. URL* u = (URL*)Tcl_GetHashValue(he);
  154. u->access++;
  155. uid = u->id;
  156. }
  157. rlog[num_rlog++] = ReqLog(time, cid, sid, uid);
  158. //fprintf(cf, "%f %d %d %dn", time, cid, sid, uid);
  159. if (startTime > 0) 
  160. return time - startTime;
  161. else 
  162. return time;
  163. }