Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

596 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992.
  5. //
  6. // File: STAT.CXX
  7. //
  8. // Contents: Statistics support.
  9. //
  10. // Classes: CStat -- Basic statistics object
  11. //
  12. // History: 23-May-91 KyleP Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #define INPTR stm
  18. #define DEB_PRINTF( x ) fprintf x
  19. #include "stat.hxx"
  20. double _sqrt (double);
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Member: CStat::CStat, public
  24. //
  25. // Synopsis: Initializes statistics object.
  26. //
  27. // History: 24-May-91 KyleP Created.
  28. //
  29. //----------------------------------------------------------------------------
  30. CStat::CStat()
  31. {
  32. ClearCount();
  33. }
  34. //+---------------------------------------------------------------------------
  35. //
  36. // Member: CStat::ClearCount, public
  37. //
  38. // Synopsis: Clears the statistics object (Count() == 0).
  39. //
  40. // History: 24-May-91 KyleP Created.
  41. //
  42. //----------------------------------------------------------------------------
  43. void CStat::ClearCount()
  44. {
  45. _count = 0;
  46. _sigma = 0;
  47. _sigmaSquared = 0;
  48. _min = 0xFFFFFFFF;
  49. _max = 0;
  50. }
  51. //+---------------------------------------------------------------------------
  52. //
  53. // Member: CStat::Add, public
  54. //
  55. // Synopsis: Adds a data point.
  56. //
  57. // Arguments: [Item] -- New data item to add.
  58. //
  59. // History: 24-May-91 KyleP Created.
  60. //
  61. //----------------------------------------------------------------------------
  62. void CStat::Add(unsigned long Item)
  63. {
  64. _count++;
  65. _sigma += Item;
  66. _sigmaSquared += (Item * Item);
  67. _min = __min(_min, Item);
  68. _max = __max(_max, Item);
  69. }
  70. //+---------------------------------------------------------------------------
  71. //
  72. // Member: CStat::Count, public
  73. //
  74. // Returns: The number of data points which have been added.
  75. //
  76. // History: 24-May-91 KyleP Created.
  77. //
  78. //----------------------------------------------------------------------------
  79. int CStat::Count() const
  80. {
  81. return(_count);
  82. }
  83. //+---------------------------------------------------------------------------
  84. //
  85. // Member: CStat::Mean, public
  86. //
  87. // Returns: The mean of the data.
  88. //
  89. // History: 24-May-91 KyleP Created.
  90. //
  91. //----------------------------------------------------------------------------
  92. double CStat::Mean() const
  93. {
  94. if (_count == 0)
  95. return(0);
  96. else
  97. return((double)_sigma / (double)_count);
  98. }
  99. //+---------------------------------------------------------------------------
  100. //
  101. // Member: CStat::SDev, public
  102. //
  103. // Returns: The standard deviation of the data.
  104. //
  105. // History: 24-May-91 KyleP Created.
  106. //
  107. //----------------------------------------------------------------------------
  108. double CStat::SDev() const
  109. {
  110. if (_count < 2)
  111. return(0.0);
  112. else
  113. {
  114. //
  115. // __ /---------------------
  116. // SDev = \ / 1 n _ 2
  117. // \ / ------- SUM (x - x)
  118. // \/ n - 1 i=1 i
  119. //
  120. double mean = Mean();
  121. #if 1
  122. double TmpV = (1.0 /
  123. ((double)_count - 1.0)) *
  124. ((double)_sigmaSquared
  125. - 2.0 * mean * (double)_sigma
  126. + mean * mean * (double)_count);
  127. double SqrtTmpV = _sqrt(TmpV);
  128. ciDebugOut (( 0x30000000, "***** Value : %f Square Root : %f\n",
  129. TmpV, SqrtTmpV ));
  130. return(SqrtTmpV);
  131. #else
  132. return(_sqrt( (1.0 /
  133. ((double)_count - 1.0)) *
  134. ((double)_sigmaSquared
  135. - 2.0 * mean * (double)_sigma
  136. + mean * mean * (double)_count)));
  137. #endif
  138. }
  139. }
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Member: CStat::Total, public
  143. //
  144. // Returns: The sum of the data.
  145. //
  146. // History: 24-May-91 KyleP Created.
  147. //
  148. //----------------------------------------------------------------------------
  149. unsigned long CStat::Total() const
  150. {
  151. return(_sigma);
  152. }
  153. //+---------------------------------------------------------------------------
  154. //
  155. // Member: CStat::Min, public
  156. //
  157. // Returns: The minimum data point.
  158. //
  159. // History: 24-May-91 KyleP Created.
  160. //
  161. //----------------------------------------------------------------------------
  162. unsigned long CStat::Min() const
  163. {
  164. return(_min);
  165. }
  166. //+---------------------------------------------------------------------------
  167. //
  168. // Member: CStat::Max, public
  169. //
  170. // Returns: The maximum data point.
  171. //
  172. // History: 24-May-91 KyleP Created.
  173. //
  174. //----------------------------------------------------------------------------
  175. unsigned long CStat::Max() const
  176. {
  177. return(_max);
  178. }
  179. //+---------------------------------------------------------------------------
  180. //
  181. // Member: CStat::Print, public
  182. //
  183. // Synopsis: Print the statistical data.
  184. //
  185. // Arguments: [stm] -- Stream to print to.
  186. //
  187. // [szName] -- Descriptive string for these stats.
  188. //
  189. // [fHeader] -- Prints a header if non-zero.
  190. //
  191. // [Div] -- Factor to divide the results by. In general
  192. // this will be either 1 (counting bytes) or
  193. // 8 (counting bits, want to display bytes).
  194. //
  195. // History: 28-May-91 KyleP Created.
  196. //
  197. //----------------------------------------------------------------------------
  198. void CStat::Print(FILE * stm, char * szName, int fHeader, unsigned int Div)
  199. {
  200. if (fHeader)
  201. {
  202. //
  203. // 0 5 0 5 0 5 0 5 0 5 0 5 0 5
  204. //
  205. DEB_PRINTF((INPTR, " Mean SDev Min Max Count Sum\n" ));
  206. DEB_PRINTF((INPTR, " -------- -------- ------ ------ -------- ---------\n" ));
  207. }
  208. Win4Assert ( Div != 0 );
  209. DEB_PRINTF((INPTR, "%-13s: %8.2lf %8.2lf %6lu %6lu %8u %9lu\n",
  210. szName,
  211. Mean() / (double)Div,
  212. SDev() / (double)Div,
  213. Min() / (unsigned long)Div,
  214. Max() / (unsigned long)Div,
  215. Count(),
  216. Total() / (unsigned long)Div ));
  217. }
  218. //+---------------------------------------------------------------------------
  219. //
  220. // Member: CDistrib::CDistrib, public
  221. //
  222. // Synopsis: Constructor for statistical distribution object.
  223. //
  224. // Arguments: [cBuckets] -- Count of ranges for which counts will be
  225. // kept. A larger [cBuckets] --> greater accuracy.
  226. //
  227. // [min] -- Minimum value to be added.
  228. //
  229. // [max] -- Maximum value to be added.
  230. //
  231. // History: 07-Jun-91 KyleP Created.
  232. //
  233. //----------------------------------------------------------------------------
  234. CDistrib::CDistrib(
  235. unsigned int cBuckets,
  236. unsigned long min,
  237. unsigned long max)
  238. {
  239. _min = min;
  240. _cBuckets = cBuckets;
  241. unsigned long width = (max - min + 1) / cBuckets;
  242. if (width == 0)
  243. {
  244. width = 1;
  245. _cBuckets = (max - min + 1);
  246. }
  247. _maxcount = 0;
  248. _aBucket = new unsigned long [_cBuckets];
  249. _aMaxBucket = new unsigned long [_cBuckets];
  250. if ((_aBucket == 0) || (_aMaxBucket == 0))
  251. {
  252. _cBuckets = 0;
  253. delete _aBucket;
  254. delete _aMaxBucket;
  255. return;
  256. }
  257. for (unsigned int i = 0; i < _cBuckets; i++)
  258. {
  259. _aBucket[i] = 0;
  260. _aMaxBucket[i] = _min + width*(i+1) - 1;
  261. }
  262. }
  263. //+---------------------------------------------------------------------------
  264. //
  265. // Member: CDistrib::CDistrib, public
  266. //
  267. // Synopsis: Constructor for statistical distribution object.
  268. //
  269. // Arguments: [cBuckets] -- Count of ranges for which counts will be
  270. // kept. A larger [cBuckets] --> greater accuracy.
  271. //
  272. // [min] -- Minimum value to be added.
  273. //
  274. // [aMaxBucket] -- An array of maximums for each bucket.
  275. // Bucket #0 contains entries from [min] to
  276. // [aMaxBucket][0]. The ith bucket holds
  277. // entries from [aMaxBucket][i-1] + 1 to
  278. // [aMaxBucket][i].
  279. //
  280. // History: 18-Jun-91 KyleP Created.
  281. //
  282. //----------------------------------------------------------------------------
  283. CDistrib::CDistrib(
  284. unsigned int cBuckets,
  285. unsigned long min,
  286. unsigned long * aMaxBucket)
  287. {
  288. _min = min;
  289. _cBuckets = cBuckets;
  290. _maxcount = 0;
  291. _aBucket = new unsigned long [_cBuckets];
  292. _aMaxBucket = new unsigned long [_cBuckets];
  293. if ((_aBucket == 0) || (_aMaxBucket == 0))
  294. {
  295. _cBuckets = 0;
  296. delete _aBucket;
  297. delete _aMaxBucket;
  298. return;
  299. }
  300. memset(_aBucket, 0, sizeof(unsigned long) * _cBuckets);
  301. for (unsigned int i = 0; i < _cBuckets; i++)
  302. {
  303. _aMaxBucket[i] = aMaxBucket[i];
  304. }
  305. }
  306. //+---------------------------------------------------------------------------
  307. //
  308. // Member: CDistrib::~CDistrib, public
  309. //
  310. // Synopsis: Displays statistical distribution.
  311. //
  312. // History: 07-Jun-91 KyleP Created.
  313. //
  314. //----------------------------------------------------------------------------
  315. CDistrib::~CDistrib()
  316. {
  317. delete _aBucket;
  318. delete _aMaxBucket;
  319. }
  320. //+---------------------------------------------------------------------------
  321. //
  322. // Member: CDistrib::Add, public
  323. //
  324. // Synopsis: Add a new data point.
  325. //
  326. // Arguments: [Item] -- the data point.
  327. //
  328. // Requires: [Item] is between the min and max specified in the
  329. // constructor.
  330. //
  331. // History: 07-Jun-91 KyleP Created.
  332. //
  333. //----------------------------------------------------------------------------
  334. void CDistrib::Add(unsigned long Item)
  335. {
  336. if ((_cBuckets == 0) ||
  337. (Item < _min) ||
  338. (Item > _aMaxBucket[_cBuckets - 1]))
  339. {
  340. return;
  341. }
  342. for (unsigned int i = _cBuckets;
  343. (i > 0) && (Item <= _aMaxBucket[i-1]);
  344. i--);
  345. if (++_aBucket[i] > _maxcount)
  346. _maxcount = _aBucket[i];
  347. }
  348. //+---------------------------------------------------------------------------
  349. //
  350. // Member: CDistrib::Print, public
  351. //
  352. // Synopsis: Display the results.
  353. //
  354. // Arguments: [INPTR] -- Output stream.
  355. //
  356. // History: 07-Jun-91 KyleP Created.
  357. //
  358. //----------------------------------------------------------------------------
  359. void CDistrib::Print(FILE * stm)
  360. {
  361. unsigned long div = __max(_maxcount / 50, 1);
  362. unsigned int fEmpty = 0;
  363. for (unsigned int i = 1; i <= _cBuckets; i++)
  364. {
  365. if (_aBucket[_cBuckets - i] == 0)
  366. {
  367. if (!fEmpty)
  368. {
  369. fEmpty = 1;
  370. DEB_PRINTF((INPTR, " :\n" ));
  371. }
  372. continue;
  373. }
  374. fEmpty = 0;
  375. DEB_PRINTF((INPTR, "%ld - %ld: (%ld)\t",
  376. (i == _cBuckets ? _min : _aMaxBucket[_cBuckets - i - 1] + 1),
  377. _aMaxBucket[_cBuckets - i],
  378. _aBucket[_cBuckets - i] ));
  379. for (unsigned int j = 0; j < _aBucket[_cBuckets - i] / div; j++)
  380. {
  381. DEB_PRINTF((INPTR, "*"));
  382. }
  383. DEB_PRINTF((INPTR, "\n"));
  384. }
  385. }
  386. //+-------------------------------------------------------------------------
  387. //
  388. // Member: CPopularKeys::CPopularKeys, public
  389. //
  390. // Arguments: [cKeep] -- Keep track of top [cKeep] keys
  391. //
  392. // History: 14-May-93 KyleP Created
  393. //
  394. //--------------------------------------------------------------------------
  395. CPopularKeys::CPopularKeys( int cKeep )
  396. : _cKeep( cKeep )
  397. {
  398. _acWid = new unsigned long [cKeep];
  399. _aKey = new CKeyBuf [cKeep];
  400. for ( int i = 0; i < cKeep; i++ )
  401. {
  402. _acWid[i] = 0;
  403. }
  404. }
  405. CPopularKeys::~CPopularKeys()
  406. {
  407. delete [] _acWid;
  408. delete [] _aKey;
  409. }
  410. void CPopularKeys::Add( CKeyBuf const & key, unsigned long cWid )
  411. {
  412. if ( cWid > _acWid[0] )
  413. {
  414. for ( int i = 0; i < _cKeep && cWid > _acWid[i]; i++ )
  415. continue; // NULL Body
  416. i--;
  417. for ( int j = 0; j < i; j++ )
  418. {
  419. _acWid[j] = _acWid[j+1];
  420. _aKey[j] = _aKey[j+1];
  421. }
  422. _acWid[i] = cWid;
  423. _aKey[i] = key;
  424. }
  425. }
  426. void CPopularKeys::Print(FILE * stm)
  427. {
  428. #if CIDBG == 1
  429. DEB_PRINTF(( INPTR,
  430. " Count Key\n"
  431. "------- ----------------------------------\n" ));
  432. for ( int i = _cKeep - 1; i >= 0; i-- )
  433. {
  434. //
  435. // If this is a STRING in the contents, then print it out
  436. //
  437. if ( STRING_KEY == _aKey[i].Type() )
  438. {
  439. DEB_PRINTF(( INPTR, "%7u (CONT) \"%.*ws\"\n",
  440. _acWid[i], _aKey[i].StrLen(), _aKey[i].GetStr() ));
  441. }
  442. else if (_aKey[i].Count() > cbKeyPrefix)
  443. {
  444. //
  445. // This is one of the various properties. Dump it out
  446. //
  447. DEB_PRINTF(( INPTR, "%7u (PROP) Pid=0x%4.4x Type=%3.1d Len=%3.1d\t\t",
  448. _acWid[i],
  449. _aKey[i].Pid(),
  450. _aKey[i].Type(),
  451. _aKey[i].Count() - 1
  452. ));
  453. BYTE *pb = (UCHAR *) _aKey[i].GetBuf();
  454. pb += cbKeyPrefix; // Skip over key's prefix
  455. for ( unsigned j=cbKeyPrefix; j<_aKey[i].Count(); j++ )
  456. {
  457. DEB_PRINTF((INPTR, "%2.2x ", *pb));
  458. pb++;
  459. }
  460. DEB_PRINTF((INPTR, "\n"));
  461. }
  462. }
  463. #endif // CIDBG == 1
  464. }
  465. #define _u_ 0.000001
  466. inline double __Square ( double value )
  467. {
  468. return(value*value);
  469. }
  470. inline double __abs( double value )
  471. {
  472. return( value > 0.0 ? value : (0.0 - value) );
  473. }
  474. //+ --------------------------------------------------------------------
  475. //
  476. // Function Name : sqrt
  477. //
  478. // Argument : [value]
  479. //
  480. // Purpose : Find the square root of the "value"
  481. //
  482. // Created : t-joshh March 6, 1993
  483. //
  484. // ---------------------------------------------------------------------
  485. double _sqrt ( double value )
  486. {
  487. double LowValue = 0.0;
  488. double HighValue = value;
  489. double med_value = ( HighValue + LowValue ) / 2;
  490. for (; ; ) {
  491. double TmpValue = __Square(med_value) - value;
  492. if ( __abs(TmpValue) < _u_ )
  493. {
  494. break;
  495. }
  496. if ( TmpValue > 0 )
  497. {
  498. HighValue = med_value;
  499. }
  500. else
  501. {
  502. LowValue = med_value;
  503. }
  504. med_value = ( HighValue + LowValue ) / 2;
  505. }
  506. return(med_value);
  507. }