SqlStatistics.cs 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. //------------------------------------------------------------------------------
  2. // <copyright file="SqlStatistics.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. //------------------------------------------------------------------------------
  8. using System;
  9. using System.Collections;
  10. using System.Data.Common;
  11. using System.Diagnostics;
  12. namespace System.Data.SqlClient
  13. {
  14. internal sealed class SqlStatistics {
  15. static internal SqlStatistics StartTimer(SqlStatistics statistics) {
  16. if ((null != statistics) && !statistics.RequestExecutionTimer()) {
  17. // we're re-entrant -- don't bother.
  18. statistics = null;
  19. }
  20. return statistics;
  21. }
  22. static internal void StopTimer(SqlStatistics statistics) {
  23. if (null != statistics) {
  24. statistics.ReleaseAndUpdateExecutionTimer();
  25. }
  26. }
  27. // internal values that are not exposed through properties
  28. internal long _closeTimestamp;
  29. internal long _openTimestamp;
  30. internal long _startExecutionTimestamp;
  31. internal long _startFetchTimestamp;
  32. internal long _startNetworkServerTimestamp;
  33. // internal values that are exposed through properties
  34. internal long _buffersReceived;
  35. internal long _buffersSent;
  36. internal long _bytesReceived;
  37. internal long _bytesSent;
  38. internal long _connectionTime;
  39. internal long _cursorOpens;
  40. internal long _executionTime;
  41. internal long _iduCount;
  42. internal long _iduRows;
  43. internal long _networkServerTime;
  44. internal long _preparedExecs;
  45. internal long _prepares;
  46. internal long _selectCount;
  47. internal long _selectRows;
  48. internal long _serverRoundtrips;
  49. internal long _sumResultSets;
  50. internal long _transactions;
  51. internal long _unpreparedExecs;
  52. // these flags are required if statistics is turned on/off in the middle of command execution
  53. private bool _waitForDoneAfterRow;
  54. private bool _waitForReply;
  55. internal bool WaitForDoneAfterRow {
  56. get {
  57. return _waitForDoneAfterRow;
  58. }
  59. set {
  60. _waitForDoneAfterRow = value;
  61. }
  62. }
  63. internal bool WaitForReply {
  64. get {
  65. return _waitForReply;
  66. }
  67. }
  68. internal SqlStatistics () {
  69. }
  70. internal void ContinueOnNewConnection() {
  71. _startExecutionTimestamp = 0;
  72. _startFetchTimestamp = 0;
  73. _waitForDoneAfterRow = false;
  74. _waitForReply = false;
  75. }
  76. internal IDictionary GetHashtable() {
  77. Hashtable ht = new Hashtable();
  78. ht.Add("BuffersReceived", _buffersReceived);
  79. ht.Add("BuffersSent", _buffersSent);
  80. ht.Add("BytesReceived", _bytesReceived);
  81. ht.Add("BytesSent", _bytesSent);
  82. ht.Add("CursorOpens", _cursorOpens);
  83. ht.Add("IduCount", _iduCount);
  84. ht.Add("IduRows", _iduRows);
  85. ht.Add("PreparedExecs", _preparedExecs);
  86. ht.Add("Prepares", _prepares);
  87. ht.Add("SelectCount", _selectCount);
  88. ht.Add("SelectRows", _selectRows);
  89. ht.Add("ServerRoundtrips", _serverRoundtrips);
  90. ht.Add("SumResultSets", _sumResultSets);
  91. ht.Add("Transactions", _transactions);
  92. ht.Add("UnpreparedExecs", _unpreparedExecs);
  93. ht.Add ("ConnectionTime", ADP.TimerToMilliseconds(_connectionTime));
  94. ht.Add ("ExecutionTime", ADP.TimerToMilliseconds(_executionTime));
  95. ht.Add ("NetworkServerTime", ADP.TimerToMilliseconds(_networkServerTime));
  96. return ht;
  97. }
  98. internal bool RequestExecutionTimer () {
  99. if (_startExecutionTimestamp == 0) {
  100. ADP.TimerCurrent(out _startExecutionTimestamp);
  101. return true;
  102. }
  103. return false;
  104. }
  105. internal void RequestNetworkServerTimer () {
  106. Debug.Assert(_startExecutionTimestamp!=0, "No network time expected outside execution period");
  107. if (_startNetworkServerTimestamp == 0) {
  108. ADP.TimerCurrent(out _startNetworkServerTimestamp);
  109. }
  110. _waitForReply = true;
  111. }
  112. internal void ReleaseAndUpdateExecutionTimer () {
  113. if (_startExecutionTimestamp > 0) {
  114. _executionTime += (ADP.TimerCurrent() - _startExecutionTimestamp);
  115. _startExecutionTimestamp = 0;
  116. }
  117. }
  118. internal void ReleaseAndUpdateNetworkServerTimer () {
  119. if (_waitForReply && _startNetworkServerTimestamp > 0) {
  120. _networkServerTime += (ADP.TimerCurrent() - _startNetworkServerTimestamp);
  121. _startNetworkServerTimestamp = 0;
  122. }
  123. _waitForReply = false;
  124. }
  125. internal void Reset() {
  126. _buffersReceived = 0;
  127. _buffersSent = 0;
  128. _bytesReceived = 0;
  129. _bytesSent = 0;
  130. _connectionTime = 0;
  131. _cursorOpens = 0;
  132. _executionTime = 0;
  133. _iduCount = 0;
  134. _iduRows = 0;
  135. _networkServerTime = 0;
  136. _preparedExecs = 0;
  137. _prepares = 0;
  138. _selectCount = 0;
  139. _selectRows = 0;
  140. _serverRoundtrips = 0;
  141. _sumResultSets = 0;
  142. _transactions = 0;
  143. _unpreparedExecs = 0;
  144. _waitForDoneAfterRow = false;
  145. _waitForReply = false;
  146. _startExecutionTimestamp = 0;
  147. _startNetworkServerTimestamp = 0;
  148. }
  149. internal void SafeAdd (ref long value, long summand) {
  150. if (long.MaxValue - value > summand) {
  151. value += summand;
  152. }
  153. else {
  154. value = long.MaxValue;
  155. }
  156. }
  157. internal long SafeIncrement(ref long value) {
  158. if (value < long.MaxValue) value++;
  159. return value;
  160. }
  161. internal void UpdateStatistics() {
  162. // update connection time
  163. if (_closeTimestamp >= _openTimestamp) {
  164. SafeAdd(ref _connectionTime, _closeTimestamp - _openTimestamp);
  165. }
  166. else {
  167. _connectionTime = long.MaxValue;
  168. }
  169. }
  170. }
  171. }