001/*
002 * Copyright 2009-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2009-2020 Ping Identity Corporation
007 *
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *    http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 */
020/*
021 * Copyright (C) 2009-2020 Ping Identity Corporation
022 *
023 * This program is free software; you can redistribute it and/or modify
024 * it under the terms of the GNU General Public License (GPLv2 only)
025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
026 * as published by the Free Software Foundation.
027 *
028 * This program is distributed in the hope that it will be useful,
029 * but WITHOUT ANY WARRANTY; without even the implied warranty of
030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
031 * GNU General Public License for more details.
032 *
033 * You should have received a copy of the GNU General Public License
034 * along with this program; if not, see <http://www.gnu.org/licenses>.
035 */
036package com.unboundid.ldap.sdk;
037
038
039
040import java.io.Serializable;
041import java.text.DecimalFormat;
042import java.util.concurrent.atomic.AtomicLong;
043
044import com.unboundid.util.Mutable;
045import com.unboundid.util.ThreadSafety;
046import com.unboundid.util.ThreadSafetyLevel;
047
048
049
050/**
051 * This class provides a data structure with information about operations
052 * performed on an associated LDAP connection.  Calls to update statistics
053 * maintained by this class are threadsafe, but attempts to access different
054 * statistics may not be consistent if other operations may be in progress on
055 * the connection.
056 * <BR><BR>
057 * The set of statistics maintained for connections:
058 * <UL>
059 *   <LI>The number of attempts made to establish the connection.</LI>
060 *   <LI>The number of times the connection has been closed.</LI>
061 *   <LI>The number of requests of each type that have been sent over the
062 *       connection.</LI>
063 *   <LI>The number of responses of each type that have been received over the
064 *       connection.</LI>
065 *   <LI>The average response time (in milliseconds or nanoseconds) for each
066 *       type of operation processed on the connection.</LI>
067 * </UL>
068 */
069@Mutable()
070@ThreadSafety(level=ThreadSafetyLevel.MOSTLY_THREADSAFE)
071public final class LDAPConnectionStatistics
072       implements Serializable
073{
074  /**
075   * The serial version UID for this serializable class.
076   */
077  private static final long serialVersionUID = -1096417617572481790L;
078
079
080
081  // The number of abandon requests sent over the associated connection.
082  private final AtomicLong numAbandonRequests;
083
084  // The number of add requests sent over the associated connection.
085  private final AtomicLong numAddRequests;
086
087  // The number of add responses received on the associated connection.
088  private final AtomicLong numAddResponses;
089
090  // The number of bind requests sent over the associated connection.
091  private final AtomicLong numBindRequests;
092
093  // The number of bind responses received on the associated connection.
094  private final AtomicLong numBindResponses;
095
096  // The number of compare requests sent over the associated connection.
097  private final AtomicLong numCompareRequests;
098
099  // The number of compare responses received on the associated connection.
100  private final AtomicLong numCompareResponses;
101
102  // The number of times the associated connection has been connected to a
103  // server.
104  private final AtomicLong numConnects;
105
106  // The number of delete requests sent over the associated connection.
107  private final AtomicLong numDeleteRequests;
108
109  // The number of delete responses received on the associated connection.
110  private final AtomicLong numDeleteResponses;
111
112  // The number of times the associated connection has been disconnected from a
113  // server.
114  private final AtomicLong numDisconnects;
115
116  // The number of extended requests sent over the associated connection.
117  private final AtomicLong numExtendedRequests;
118
119  // The number of extended responses received on the associated connection.
120  private final AtomicLong numExtendedResponses;
121
122  // The number of modify requests sent over the associated connection.
123  private final AtomicLong numModifyRequests;
124
125  // The number of modify responses received on the associated connection.
126  private final AtomicLong numModifyResponses;
127
128  // The number of modify DN requests sent over the associated connection.
129  private final AtomicLong numModifyDNRequests;
130
131  // The number of modify DN responses received on the associated connection.
132  private final AtomicLong numModifyDNResponses;
133
134  // The number of search requests sent over the associated connection.
135  private final AtomicLong numSearchRequests;
136
137  // The number of search result entry responses received on the associated
138  // connection.
139  private final AtomicLong numSearchEntryResponses;
140
141  // The number of search result reference responses received on the associated
142  // connection.
143  private final AtomicLong numSearchReferenceResponses;
144
145  // The number of search result done responses received on the associated
146  // connection.
147  private final AtomicLong numSearchDoneResponses;
148
149  // The number of unbind requests sent over the associated connection.
150  private final AtomicLong numUnbindRequests;
151
152  // The total length of time spent waiting for add responses.
153  private final AtomicLong totalAddResponseTime;
154
155  // The total length of time spent waiting for bind responses.
156  private final AtomicLong totalBindResponseTime;
157
158  // The total length of time spent waiting for compare responses.
159  private final AtomicLong totalCompareResponseTime;
160
161  // The total length of time spent waiting for delete responses.
162  private final AtomicLong totalDeleteResponseTime;
163
164  // The total length of time spent waiting for extended responses.
165  private final AtomicLong totalExtendedResponseTime;
166
167  // The total length of time spent waiting for modify responses.
168  private final AtomicLong totalModifyResponseTime;
169
170  // The total length of time spent waiting for modify DN responses.
171  private final AtomicLong totalModifyDNResponseTime;
172
173  // The total length of time spent waiting for search done responses.
174  private final AtomicLong totalSearchResponseTime;
175
176
177
178  /**
179   * Creates a new instance of this LDAP connection statistics object.  All of
180   * the counts will be initialized to zero.
181   */
182  public LDAPConnectionStatistics()
183  {
184    numAbandonRequests          = new AtomicLong(0L);
185    numAddRequests              = new AtomicLong(0L);
186    numAddResponses             = new AtomicLong(0L);
187    numBindRequests             = new AtomicLong(0L);
188    numBindResponses            = new AtomicLong(0L);
189    numCompareRequests          = new AtomicLong(0L);
190    numCompareResponses         = new AtomicLong(0L);
191    numConnects                 = new AtomicLong(0L);
192    numDeleteRequests           = new AtomicLong(0L);
193    numDeleteResponses          = new AtomicLong(0L);
194    numDisconnects              = new AtomicLong(0L);
195    numExtendedRequests         = new AtomicLong(0L);
196    numExtendedResponses        = new AtomicLong(0L);
197    numModifyRequests           = new AtomicLong(0L);
198    numModifyResponses          = new AtomicLong(0L);
199    numModifyDNRequests         = new AtomicLong(0L);
200    numModifyDNResponses        = new AtomicLong(0L);
201    numSearchRequests           = new AtomicLong(0L);
202    numSearchEntryResponses     = new AtomicLong(0L);
203    numSearchReferenceResponses = new AtomicLong(0L);
204    numSearchDoneResponses      = new AtomicLong(0L);
205    numUnbindRequests           = new AtomicLong(0L);
206    totalAddResponseTime        = new AtomicLong(0L);
207    totalBindResponseTime       = new AtomicLong(0L);
208    totalCompareResponseTime    = new AtomicLong(0L);
209    totalDeleteResponseTime     = new AtomicLong(0L);
210    totalExtendedResponseTime   = new AtomicLong(0L);
211    totalModifyResponseTime     = new AtomicLong(0L);
212    totalModifyDNResponseTime   = new AtomicLong(0L);
213    totalSearchResponseTime     = new AtomicLong(0L);
214  }
215
216
217
218  /**
219   * Resets all counters back to zero.
220   */
221  public void reset()
222  {
223    numAbandonRequests.set(0L);
224    numAddRequests.set(0L);
225    numAddResponses.set(0L);
226    numBindRequests.set(0L);
227    numBindResponses.set(0L);
228    numCompareRequests.set(0L);
229    numCompareResponses.set(0L);
230    numConnects.set(0L);
231    numDeleteRequests.set(0L);
232    numDeleteResponses.set(0L);
233    numDisconnects.set(0L);
234    numExtendedRequests.set(0L);
235    numExtendedResponses.set(0L);
236    numModifyRequests.set(0L);
237    numModifyResponses.set(0L);
238    numModifyDNRequests.set(0L);
239    numModifyDNResponses.set(0L);
240    numSearchRequests.set(0L);
241    numSearchEntryResponses.set(0L);
242    numSearchReferenceResponses.set(0L);
243    numSearchDoneResponses.set(0L);
244    numUnbindRequests.set(0L);
245    totalAddResponseTime.set(0L);
246    totalBindResponseTime.set(0L);
247    totalCompareResponseTime.set(0L);
248    totalDeleteResponseTime.set(0L);
249    totalExtendedResponseTime.set(0L);
250    totalModifyResponseTime.set(0L);
251    totalModifyDNResponseTime.set(0L);
252    totalSearchResponseTime.set(0L);
253  }
254
255
256
257  /**
258   * Retrieves the number of times an attempt has been made to establish the
259   * associated connection.
260   *
261   * @return  The number of times an attempt has been made to establish the
262   *          associated connection.
263   */
264  public long getNumConnects()
265  {
266    return numConnects.get();
267  }
268
269
270
271  /**
272   * Increments the number of times an attempt has been made to establish the
273   * associated connection.
274   */
275  void incrementNumConnects()
276  {
277    numConnects.incrementAndGet();
278  }
279
280
281
282  /**
283   * Retrieves the number of times the associated connection has been
284   * terminated.  Note that this may exceed the number of connection attempts
285   * because there may be cases in which an attempt is made to close a
286   * connection after it has already been closed or otherwise disconnected.
287   *
288   * @return  The number of times the associated connection has been terminated.
289   */
290  public long getNumDisconnects()
291  {
292    return numDisconnects.get();
293  }
294
295
296
297  /**
298   * Increments the number of times an attempt has been made to terminate the
299   * associated connection.
300   */
301  void incrementNumDisconnects()
302  {
303    numDisconnects.incrementAndGet();
304  }
305
306
307
308  /**
309   * Retrieves the number of abandon requests sent on the associated connection.
310   *
311   * @return  The number of abandon requests sent on the associated connection.
312   */
313  public long getNumAbandonRequests()
314  {
315    return numAbandonRequests.get();
316  }
317
318
319
320  /**
321   * Increments the number of abandon requests sent on the associated
322   * connection.
323   */
324  void incrementNumAbandonRequests()
325  {
326    numAbandonRequests.incrementAndGet();
327  }
328
329
330
331  /**
332   * Retrieves the number of add requests sent on the associated connection.
333   *
334   * @return  The number of add requests sent on the associated connection.
335   */
336  public long getNumAddRequests()
337  {
338    return numAddRequests.get();
339  }
340
341
342
343  /**
344   * Increments the number of add requests sent on the associated connection.
345   */
346  void incrementNumAddRequests()
347  {
348    numAddRequests.incrementAndGet();
349  }
350
351
352
353  /**
354   * Retrieves the number of add responses sent on the associated connection.
355   *
356   * @return  The number of add responses sent on the associated connection.
357   */
358  public long getNumAddResponses()
359  {
360    return numAddResponses.get();
361  }
362
363
364
365  /**
366   * Increments the number of add responses sent on the associated connection.
367   *
368   * @param  responseTime  The length of time in nanoseconds between sending
369   *                       the request and receiving the response.
370   */
371  void incrementNumAddResponses(final long responseTime)
372  {
373    numAddResponses.incrementAndGet();
374
375    if (responseTime > 0)
376    {
377      totalAddResponseTime.addAndGet(responseTime);
378    }
379  }
380
381
382
383  /**
384   * Retrieves the total response time in nanoseconds for all add operations
385   * processed on the associated connection.
386   *
387   * @return  The total response time in nanoseconds for all add operations
388   *          processed on the associated connection.
389   */
390  public long getTotalAddResponseTimeNanos()
391  {
392    return totalAddResponseTime.get();
393  }
394
395
396
397  /**
398   * Retrieves the total response time in milliseconds for all add operations
399   * processed on the associated connection.
400   *
401   * @return  The total response time in milliseconds for all add operations
402   *          processed on the associated connection.
403   */
404  public long getTotalAddResponseTimeMillis()
405  {
406    return Math.round(totalAddResponseTime.get() / 1_000_000.0d);
407  }
408
409
410
411  /**
412   * Retrieves the average response time in nanoseconds for all add operations
413   * processed on the associated connection.
414   *
415   * @return  The average response time in nanoseconds for all add operations
416   *          processed on the associated connection, or {@code Double.NaN} if
417   *          no add operations have yet been performed.
418   */
419  public double getAverageAddResponseTimeNanos()
420  {
421    final long totalTime  = totalAddResponseTime.get();
422    final long totalCount = numAddResponses.get();
423
424    if (totalTime > 0)
425    {
426      return (1.0d * totalTime / totalCount);
427    }
428    else
429    {
430      return Double.NaN;
431    }
432  }
433
434
435
436  /**
437   * Retrieves the average response time in milliseconds for all add operations
438   * processed on the associated connection.
439   *
440   * @return  The average response time in milliseconds for all add operations
441   *          processed on the associated connection, or {@code Double.NaN} if
442   *          no add operations have yet been performed.
443   */
444  public double getAverageAddResponseTimeMillis()
445  {
446    final long totalTime  = totalAddResponseTime.get();
447    final long totalCount = numAddResponses.get();
448
449    if (totalTime > 0)
450    {
451      return (totalTime / 1_000_000.0d / totalCount);
452    }
453    else
454    {
455      return Double.NaN;
456    }
457  }
458
459
460
461  /**
462   * Retrieves the number of bind requests sent on the associated connection.
463   *
464   * @return  The number of bind requests sent on the associated connection.
465   */
466  public long getNumBindRequests()
467  {
468    return numBindRequests.get();
469  }
470
471
472
473  /**
474   * Increments the number of bind requests sent on the associated connection.
475   */
476  void incrementNumBindRequests()
477  {
478    numBindRequests.incrementAndGet();
479  }
480
481
482
483  /**
484   * Retrieves the number of bind responses sent on the associated connection.
485   *
486   * @return  The number of bind responses sent on the associated connection.
487   */
488  public long getNumBindResponses()
489  {
490    return numBindResponses.get();
491  }
492
493
494
495  /**
496   * Increments the number of bind responses sent on the associated connection.
497   *
498   * @param  responseTime  The length of time in nanoseconds between sending
499   *                       the request and receiving the response.
500   */
501  void incrementNumBindResponses(final long responseTime)
502  {
503    numBindResponses.incrementAndGet();
504
505    if (responseTime > 0)
506    {
507      totalBindResponseTime.addAndGet(responseTime);
508    }
509  }
510
511
512
513  /**
514   * Retrieves the total response time in nanoseconds for all bind operations
515   * processed on the associated connection.
516   *
517   * @return  The total response time in nanoseconds for all bind operations
518   *          processed on the associated connection.
519   */
520  public long getTotalBindResponseTimeNanos()
521  {
522    return totalBindResponseTime.get();
523  }
524
525
526
527  /**
528   * Retrieves the total response time in milliseconds for all bind operations
529   * processed on the associated connection.
530   *
531   * @return  The total response time in milliseconds for all bind operations
532   *          processed on the associated connection.
533   */
534  public long getTotalBindResponseTimeMillis()
535  {
536    return Math.round(totalBindResponseTime.get() / 1_000_000.0d);
537  }
538
539
540
541  /**
542   * Retrieves the average response time in nanoseconds for all bind operations
543   * processed on the associated connection.
544   *
545   * @return  The average response time in nanoseconds for all bind operations
546   *          processed on the associated connection, or {@code Double.NaN} if
547   *          no bind operations have yet been performed.
548   */
549  public double getAverageBindResponseTimeNanos()
550  {
551    final long totalTime  = totalBindResponseTime.get();
552    final long totalCount = numBindResponses.get();
553
554    if (totalTime > 0)
555    {
556      return (1.0d * totalTime / totalCount);
557    }
558    else
559    {
560      return Double.NaN;
561    }
562  }
563
564
565
566  /**
567   * Retrieves the average response time in milliseconds for all bind operations
568   * processed on the associated connection.
569   *
570   * @return  The average response time in milliseconds for all bind operations
571   *          processed on the associated connection, or {@code Double.NaN} if
572   *          no bind operations have yet been performed.
573   */
574  public double getAverageBindResponseTimeMillis()
575  {
576    final long totalTime  = totalBindResponseTime.get();
577    final long totalCount = numBindResponses.get();
578
579    if (totalTime > 0)
580    {
581      return (totalTime / 1_000_000.0d / totalCount);
582    }
583    else
584    {
585      return Double.NaN;
586    }
587  }
588
589
590
591  /**
592   * Retrieves the number of compare requests sent on the associated connection.
593   *
594   * @return  The number of compare requests sent on the associated connection.
595   */
596  public long getNumCompareRequests()
597  {
598    return numCompareRequests.get();
599  }
600
601
602
603  /**
604   * Increments the number of compare requests sent on the associated
605   * connection.
606   */
607  void incrementNumCompareRequests()
608  {
609    numCompareRequests.incrementAndGet();
610  }
611
612
613
614  /**
615   * Retrieves the number of compare responses sent on the associated
616   * connection.
617   *
618   * @return  The number of compare responses sent on the associated connection.
619   */
620  public long getNumCompareResponses()
621  {
622    return numCompareResponses.get();
623  }
624
625
626
627  /**
628   * Increments the number of compare responses sent on the associated
629   * connection.
630   *
631   * @param  responseTime  The length of time in nanoseconds between sending
632   *                       the request and receiving the response.
633   */
634  void incrementNumCompareResponses(final long responseTime)
635  {
636    numCompareResponses.incrementAndGet();
637
638    if (responseTime > 0)
639    {
640      totalCompareResponseTime.addAndGet(responseTime);
641    }
642  }
643
644
645
646  /**
647   * Retrieves the total response time in nanoseconds for all compare
648   * operations processed on the associated connection.
649   *
650   * @return  The total response time in nanoseconds for all compare operations
651   *          processed on the associated connection.
652   */
653  public long getTotalCompareResponseTimeNanos()
654  {
655    return totalCompareResponseTime.get();
656  }
657
658
659
660  /**
661   * Retrieves the total response time in milliseconds for all compare
662   * operations processed on the associated connection.
663   *
664   * @return  The total response time in milliseconds for all compare operations
665   *          processed on the associated connection.
666   */
667  public long getTotalCompareResponseTimeMillis()
668  {
669    return Math.round(totalCompareResponseTime.get() / 1_000_000.0d);
670  }
671
672
673
674  /**
675   * Retrieves the average response time in nanoseconds for all compare
676   * operations processed on the associated connection.
677   *
678   * @return  The average response time in nanoseconds for all compare
679   *          operations processed on the associated connection, or
680   *          {@code Double.NaN} if no compare operations have yet been
681   *          performed.
682   */
683  public double getAverageCompareResponseTimeNanos()
684  {
685    final long totalTime  = totalCompareResponseTime.get();
686    final long totalCount = numCompareResponses.get();
687
688    if (totalTime > 0)
689    {
690      return (1.0d * totalTime / totalCount);
691    }
692    else
693    {
694      return Double.NaN;
695    }
696  }
697
698
699
700  /**
701   * Retrieves the average response time in milliseconds for all compare
702   * operations processed on the associated connection.
703   *
704   * @return  The average response time in milliseconds for all compare
705   *          operations processed on the associated connection, or
706   *          {@code Double.NaN} if no compare operations have yet been
707   *          performed.
708   */
709  public double getAverageCompareResponseTimeMillis()
710  {
711    final long totalTime  = totalCompareResponseTime.get();
712    final long totalCount = numCompareResponses.get();
713
714    if (totalTime > 0)
715    {
716      return (totalTime / 1_000_000.0d / totalCount);
717    }
718    else
719    {
720      return Double.NaN;
721    }
722  }
723
724
725
726  /**
727   * Retrieves the number of delete requests sent on the associated connection.
728   *
729   * @return  The number of delete requests sent on the associated connection.
730   */
731  public long getNumDeleteRequests()
732  {
733    return numDeleteRequests.get();
734  }
735
736
737
738  /**
739   * Increments the number of delete requests sent on the associated connection.
740   */
741  void incrementNumDeleteRequests()
742  {
743    numDeleteRequests.incrementAndGet();
744  }
745
746
747
748  /**
749   * Retrieves the number of delete responses sent on the associated connection.
750   *
751   * @return  The number of delete responses sent on the associated connection.
752   */
753  public long getNumDeleteResponses()
754  {
755    return numDeleteResponses.get();
756  }
757
758
759
760  /**
761   * Increments the number of delete responses sent on the associated
762   * connection.
763   *
764   * @param  responseTime  The length of time in nanoseconds between sending
765   *                       the request and receiving the response.
766   */
767  void incrementNumDeleteResponses(final long responseTime)
768  {
769    numDeleteResponses.incrementAndGet();
770
771    if (responseTime > 0)
772    {
773      totalDeleteResponseTime.addAndGet(responseTime);
774    }
775  }
776
777
778
779  /**
780   * Retrieves the total response time in nanoseconds for all delete
781   * operations processed on the associated connection.
782   *
783   * @return  The total response time in nanoseconds for all delete operations
784   *          processed on the associated connection.
785   */
786  public long getTotalDeleteResponseTimeNanos()
787  {
788    return totalDeleteResponseTime.get();
789  }
790
791
792
793  /**
794   * Retrieves the total response time in milliseconds for all delete
795   * operations processed on the associated connection.
796   *
797   * @return  The total response time in milliseconds for all delete operations
798   *          processed on the associated connection.
799   */
800  public long getTotalDeleteResponseTimeMillis()
801  {
802    return Math.round(totalDeleteResponseTime.get() / 1_000_000.0d);
803  }
804
805
806
807  /**
808   * Retrieves the average response time in nanoseconds for all delete
809   * operations processed on the associated connection.
810   *
811   * @return  The average response time in nanoseconds for all delete
812   *          operations processed on the associated connection, or
813   *          {@code Double.NaN} if no delete operations have yet been
814   *          performed.
815   */
816  public double getAverageDeleteResponseTimeNanos()
817  {
818    final long totalTime  = totalDeleteResponseTime.get();
819    final long totalCount = numDeleteResponses.get();
820
821    if (totalTime > 0)
822    {
823      return (1.0d * totalTime / totalCount);
824    }
825    else
826    {
827      return Double.NaN;
828    }
829  }
830
831
832
833  /**
834   * Retrieves the average response time in milliseconds for all delete
835   * operations processed on the associated connection.
836   *
837   * @return  The average response time in milliseconds for all delete
838   *          operations processed on the associated connection, or
839   *          {@code Double.NaN} if no delete operations have yet been
840   *          performed.
841   */
842  public double getAverageDeleteResponseTimeMillis()
843  {
844    final long totalTime  = totalDeleteResponseTime.get();
845    final long totalCount = numDeleteResponses.get();
846
847    if (totalTime > 0)
848    {
849      return (totalTime / 1_000_000.0d / totalCount);
850    }
851    else
852    {
853      return Double.NaN;
854    }
855  }
856
857
858
859  /**
860   * Retrieves the number of extended requests sent on the associated
861   * connection.
862   *
863   * @return  The number of extended requests sent on the associated connection.
864   */
865  public long getNumExtendedRequests()
866  {
867    return numExtendedRequests.get();
868  }
869
870
871
872  /**
873   * Increments the number of extended requests sent on the associated
874   * connection.
875   */
876  void incrementNumExtendedRequests()
877  {
878    numExtendedRequests.incrementAndGet();
879  }
880
881
882
883  /**
884   * Retrieves the number of extended responses sent on the associated
885   * connection.
886   *
887   * @return  The number of extended responses sent on the associated
888   *          connection.
889   */
890  public long getNumExtendedResponses()
891  {
892    return numExtendedResponses.get();
893  }
894
895
896
897  /**
898   * Increments the number of extended responses sent on the associated
899   * connection.
900   *
901   * @param  responseTime  The length of time in nanoseconds between sending
902   *                       the request and receiving the response.
903   */
904  void incrementNumExtendedResponses(final long responseTime)
905  {
906    numExtendedResponses.incrementAndGet();
907
908    if (responseTime > 0)
909    {
910      totalExtendedResponseTime.addAndGet(responseTime);
911    }
912  }
913
914
915
916  /**
917   * Retrieves the total response time in nanoseconds for all extended
918   * operations processed on the associated connection.
919   *
920   * @return  The total response time in nanoseconds for all extended
921   *          operations processed on the associated connection.
922   */
923  public long getTotalExtendedResponseTimeNanos()
924  {
925    return totalExtendedResponseTime.get();
926  }
927
928
929
930  /**
931   * Retrieves the total response time in milliseconds for all extended
932   * operations processed on the associated connection.
933   *
934   * @return  The total response time in milliseconds for all extended
935   *          operations processed on the associated connection.
936   */
937  public long getTotalExtendedResponseTimeMillis()
938  {
939    return Math.round(totalExtendedResponseTime.get() / 1_000_000.0d);
940  }
941
942
943
944  /**
945   * Retrieves the average response time in nanoseconds for all extended
946   * operations processed on the associated connection.
947   *
948   * @return  The average response time in nanoseconds for all extended
949   *          operations processed on the associated connection, or
950   *          {@code Double.NaN} if no extended operations have yet been
951   *          performed.
952   */
953  public double getAverageExtendedResponseTimeNanos()
954  {
955    final long totalTime  = totalExtendedResponseTime.get();
956    final long totalCount = numExtendedResponses.get();
957
958    if (totalTime > 0)
959    {
960      return (1.0d * totalTime / totalCount);
961    }
962    else
963    {
964      return Double.NaN;
965    }
966  }
967
968
969
970  /**
971   * Retrieves the average response time in milliseconds for all extended
972   * operations processed on the associated connection.
973   *
974   * @return  The average response time in milliseconds for all extended
975   *          operations processed on the associated connection, or
976   *          {@code Double.NaN} if no extended operations have yet been
977   *          performed.
978   */
979  public double getAverageExtendedResponseTimeMillis()
980  {
981    final long totalTime  = totalExtendedResponseTime.get();
982    final long totalCount = numExtendedResponses.get();
983
984    if (totalTime > 0)
985    {
986      return (totalTime / 1_000_000.0d / totalCount);
987    }
988    else
989    {
990      return Double.NaN;
991    }
992  }
993
994
995
996  /**
997   * Retrieves the number of modify requests sent on the associated connection.
998   *
999   * @return  The number of modify requests sent on the associated connection.
1000   */
1001  public long getNumModifyRequests()
1002  {
1003    return numModifyRequests.get();
1004  }
1005
1006
1007
1008  /**
1009   * Increments the number of modify requests sent on the associated connection.
1010   */
1011  void incrementNumModifyRequests()
1012  {
1013    numModifyRequests.incrementAndGet();
1014  }
1015
1016
1017
1018  /**
1019   * Retrieves the number of modify responses sent on the associated connection.
1020   *
1021   * @return  The number of modify responses sent on the associated connection.
1022   */
1023  public long getNumModifyResponses()
1024  {
1025    return numModifyResponses.get();
1026  }
1027
1028
1029
1030  /**
1031   * Increments the number of modify responses sent on the associated
1032   * connection.
1033   *
1034   * @param  responseTime  The length of time in nanoseconds between sending
1035   *                       the request and receiving the response.
1036   */
1037  void incrementNumModifyResponses(final long responseTime)
1038  {
1039    numModifyResponses.incrementAndGet();
1040
1041    if (responseTime > 0)
1042    {
1043      totalModifyResponseTime.addAndGet(responseTime);
1044    }
1045  }
1046
1047
1048
1049  /**
1050   * Retrieves the total response time in nanoseconds for all modify
1051   * operations processed on the associated connection.
1052   *
1053   * @return  The total response time in nanoseconds for all modify operations
1054   *          processed on the associated connection.
1055   */
1056  public long getTotalModifyResponseTimeNanos()
1057  {
1058    return totalModifyResponseTime.get();
1059  }
1060
1061
1062
1063  /**
1064   * Retrieves the total response time in milliseconds for all modify
1065   * operations processed on the associated connection.
1066   *
1067   * @return  The total response time in milliseconds for all modify operations
1068   *          processed on the associated connection.
1069   */
1070  public long getTotalModifyResponseTimeMillis()
1071  {
1072    return Math.round(totalModifyResponseTime.get() / 1_000_000.0d);
1073  }
1074
1075
1076
1077  /**
1078   * Retrieves the average response time in nanoseconds for all modify
1079   * operations processed on the associated connection.
1080   *
1081   * @return  The average response time in nanoseconds for all modify
1082   *          operations processed on the associated connection, or
1083   *          {@code Double.NaN} if no modify operations have yet been
1084   *          performed.
1085   */
1086  public double getAverageModifyResponseTimeNanos()
1087  {
1088    final long totalTime  = totalModifyResponseTime.get();
1089    final long totalCount = numModifyResponses.get();
1090
1091    if (totalTime > 0)
1092    {
1093      return (1.0d * totalTime / totalCount);
1094    }
1095    else
1096    {
1097      return Double.NaN;
1098    }
1099  }
1100
1101
1102
1103  /**
1104   * Retrieves the average response time in milliseconds for all modify
1105   * operations processed on the associated connection.
1106   *
1107   * @return  The average response time in milliseconds for all modify
1108   *          operations processed on the associated connection, or
1109   *          {@code Double.NaN} if no modify operations have yet been
1110   *          performed.
1111   */
1112  public double getAverageModifyResponseTimeMillis()
1113  {
1114    final long totalTime  = totalModifyResponseTime.get();
1115    final long totalCount = numModifyResponses.get();
1116
1117    if (totalTime > 0)
1118    {
1119      return (totalTime / 1_000_000.0d / totalCount);
1120    }
1121    else
1122    {
1123      return Double.NaN;
1124    }
1125  }
1126
1127
1128
1129  /**
1130   * Retrieves the number of modify DN requests sent on the associated
1131   * connection.
1132   *
1133   * @return  The number of modify DN requests sent on the associated
1134   *          connection.
1135   */
1136  public long getNumModifyDNRequests()
1137  {
1138    return numModifyDNRequests.get();
1139  }
1140
1141
1142
1143  /**
1144   * Increments the number of modify DN requests sent on the associated
1145   * connection.
1146   */
1147  void incrementNumModifyDNRequests()
1148  {
1149    numModifyDNRequests.incrementAndGet();
1150  }
1151
1152
1153
1154  /**
1155   * Retrieves the number of modify DN responses sent on the associated
1156   * connection.
1157   *
1158   * @return  The number of modify DN responses sent on the associated
1159   *          connection.
1160   */
1161  public long getNumModifyDNResponses()
1162  {
1163    return numModifyDNResponses.get();
1164  }
1165
1166
1167
1168  /**
1169   * Increments the number of modify DN responses sent on the associated
1170   * connection.
1171   *
1172   * @param  responseTime  The length of time in nanoseconds between sending
1173   *                       the request and receiving the response.
1174   */
1175  void incrementNumModifyDNResponses(final long responseTime)
1176  {
1177    numModifyDNResponses.incrementAndGet();
1178
1179    if (responseTime > 0)
1180    {
1181      totalModifyDNResponseTime.addAndGet(responseTime);
1182    }
1183  }
1184
1185
1186
1187  /**
1188   * Retrieves the total response time in nanoseconds for all modify DN
1189   * operations processed on the associated connection.
1190   *
1191   * @return  The total response time in nanoseconds for all modify DN
1192   *          operations processed on the associated connection.
1193   */
1194  public long getTotalModifyDNResponseTimeNanos()
1195  {
1196    return totalModifyDNResponseTime.get();
1197  }
1198
1199
1200
1201  /**
1202   * Retrieves the total response time in milliseconds for all modify DN
1203   * operations processed on the associated connection.
1204   *
1205   * @return  The total response time in milliseconds for all modify DN
1206   *          operations processed on the associated connection.
1207   */
1208  public long getTotalModifyDNResponseTimeMillis()
1209  {
1210    return Math.round(totalModifyDNResponseTime.get() / 1_000_000.0d);
1211  }
1212
1213
1214
1215  /**
1216   * Retrieves the average response time in nanoseconds for all modify DN
1217   * operations processed on the associated connection.
1218   *
1219   * @return  The average response time in nanoseconds for all modify DN
1220   *          operations processed on the associated connection, or
1221   *          {@code Double.NaN} if no modify DN operations have yet been
1222   *          performed.
1223   */
1224  public double getAverageModifyDNResponseTimeNanos()
1225  {
1226    final long totalTime  = totalModifyDNResponseTime.get();
1227    final long totalCount = numModifyDNResponses.get();
1228
1229    if (totalTime > 0)
1230    {
1231      return (1.0d * totalTime / totalCount);
1232    }
1233    else
1234    {
1235      return Double.NaN;
1236    }
1237  }
1238
1239
1240
1241  /**
1242   * Retrieves the average response time in milliseconds for all modify DN
1243   * operations processed on the associated connection.
1244   *
1245   * @return  The average response time in milliseconds for all modify DN
1246   *          operations processed on the associated connection, or
1247   *          {@code Double.NaN} if no modify DN operations have yet been
1248   *          performed.
1249   */
1250  public double getAverageModifyDNResponseTimeMillis()
1251  {
1252    final long totalTime  = totalModifyDNResponseTime.get();
1253    final long totalCount = numModifyDNResponses.get();
1254
1255    if (totalTime > 0)
1256    {
1257      return (totalTime / 1_000_000.0d / totalCount);
1258    }
1259    else
1260    {
1261      return Double.NaN;
1262    }
1263  }
1264
1265
1266
1267  /**
1268   * Retrieves the number of search requests sent on the associated connection.
1269   *
1270   * @return  The number of search requests sent on the associated connection.
1271   */
1272  public long getNumSearchRequests()
1273  {
1274    return numSearchRequests.get();
1275  }
1276
1277
1278
1279  /**
1280   * Increments the number of search requests sent on the associated
1281   * connection.
1282   */
1283  void incrementNumSearchRequests()
1284  {
1285    numSearchRequests.incrementAndGet();
1286  }
1287
1288
1289
1290  /**
1291   * Retrieves the number of search result entry responses received on the
1292   * associated connection.
1293   *
1294   * @return  The number of search result entry responses received on the
1295   *          associated connection.
1296   */
1297  public long getNumSearchEntryResponses()
1298  {
1299    return numSearchEntryResponses.get();
1300  }
1301
1302
1303
1304  /**
1305   * Retrieves the number of search result reference responses received on the
1306   * associated connection.
1307   *
1308   * @return  The number of search result reference responses received on the
1309   *          associated connection.
1310   */
1311  public long getNumSearchReferenceResponses()
1312  {
1313    return numSearchReferenceResponses.get();
1314  }
1315
1316
1317
1318  /**
1319   * Retrieves the number of search result done responses received on the
1320   * associated connection.
1321   *
1322   * @return  The number of search result done responses received on the
1323   *          associated connection.
1324   */
1325  public long getNumSearchDoneResponses()
1326  {
1327    return numSearchDoneResponses.get();
1328  }
1329
1330
1331
1332  /**
1333   * Increments the number of search result done responses received on the
1334   * associated connection.
1335   *
1336   * @param  numEntries     The number of search result entries returned for the
1337   *                        search.
1338   * @param  numReferences  The number of search result references returned for
1339   *                        the search.
1340   * @param  responseTime   The length of time in nanoseconds between sending
1341   *                        the search request and receiving the search result
1342   *                        done response.
1343   */
1344  void incrementNumSearchResponses(final int numEntries,
1345                                   final int numReferences,
1346                                   final long responseTime)
1347  {
1348    numSearchEntryResponses.addAndGet(numEntries);
1349    numSearchReferenceResponses.addAndGet(numReferences);
1350    numSearchDoneResponses.incrementAndGet();
1351
1352    if (responseTime > 0)
1353    {
1354      totalSearchResponseTime.addAndGet(responseTime);
1355    }
1356  }
1357
1358
1359
1360  /**
1361   * Retrieves the total response time in nanoseconds for all search
1362   * operations processed on the associated connection.
1363   *
1364   * @return  The total response time in nanoseconds for all search operations
1365   *          processed on the associated connection.
1366   */
1367  public long getTotalSearchResponseTimeNanos()
1368  {
1369    return totalSearchResponseTime.get();
1370  }
1371
1372
1373
1374  /**
1375   * Retrieves the total response time in milliseconds for all search
1376   * operations processed on the associated connection.
1377   *
1378   * @return  The total response time in milliseconds for all search operations
1379   *          processed on the associated connection.
1380   */
1381  public long getTotalSearchResponseTimeMillis()
1382  {
1383    return Math.round(totalSearchResponseTime.get() / 1_000_000.0d);
1384  }
1385
1386
1387
1388  /**
1389   * Retrieves the average response time in nanoseconds for all search
1390   * operations processed on the associated connection.
1391   *
1392   * @return  The average response time in nanoseconds for all search
1393   *          operations processed on the associated connection, or
1394   *          {@code Double.NaN} if no compare operations have yet been
1395   *          performed.
1396   */
1397  public double getAverageSearchResponseTimeNanos()
1398  {
1399    final long totalTime  = totalSearchResponseTime.get();
1400    final long totalCount = numSearchDoneResponses.get();
1401
1402    if (totalTime > 0)
1403    {
1404      return (1.0d * totalTime / totalCount);
1405    }
1406    else
1407    {
1408      return Double.NaN;
1409    }
1410  }
1411
1412
1413
1414  /**
1415   * Retrieves the average response time in milliseconds for all search
1416   * operations processed on the associated connection.
1417   *
1418   * @return  The average response time in milliseconds for all search
1419   *          operations processed on the associated connection, or
1420   *          {@code Double.NaN} if no compare operations have yet been
1421   *          performed.
1422   */
1423  public double getAverageSearchResponseTimeMillis()
1424  {
1425    final long totalTime  = totalSearchResponseTime.get();
1426    final long totalCount = numSearchDoneResponses.get();
1427
1428    if (totalTime > 0)
1429    {
1430      return (totalTime / 1_000_000.0d / totalCount);
1431    }
1432    else
1433    {
1434      return Double.NaN;
1435    }
1436  }
1437
1438
1439
1440  /**
1441   * Retrieves the number of unbind requests sent on the associated connection.
1442   *
1443   * @return  The number of unbind requests sent on the associated connection.
1444   */
1445  public long getNumUnbindRequests()
1446  {
1447    return numUnbindRequests.get();
1448  }
1449
1450
1451
1452  /**
1453   * Increments the number of unbind requests sent on the associated
1454   * connection.
1455   */
1456  void incrementNumUnbindRequests()
1457  {
1458    numUnbindRequests.incrementAndGet();
1459  }
1460
1461
1462
1463  /**
1464   * Retrieves a string representation of this LDAP connection statistics
1465   * object.
1466   *
1467   * @return  A string representation of this LDAP connection statistics object.
1468   */
1469  @Override()
1470  public String toString()
1471  {
1472    final StringBuilder buffer = new StringBuilder();
1473    toString(buffer);
1474    return buffer.toString();
1475  }
1476
1477
1478
1479  /**
1480   * Appends a string representation of this LDAP connection statistics object
1481   * to the provided buffer.
1482   *
1483   * @param  buffer  The buffer to which the string representation should be
1484   *                 appended.
1485   */
1486  public void toString(final StringBuilder buffer)
1487  {
1488    final long connects          = numConnects.get();
1489    final long disconnects       = numDisconnects.get();
1490    final long abandonRequests   = numAbandonRequests.get();
1491    final long addRequests       = numAddRequests.get();
1492    final long addResponses      = numAddResponses.get();
1493    final long addTimes          = totalAddResponseTime.get();
1494    final long bindRequests      = numBindRequests.get();
1495    final long bindResponses     = numBindResponses.get();
1496    final long bindTimes         = totalBindResponseTime.get();
1497    final long compareRequests   = numCompareRequests.get();
1498    final long compareResponses  = numCompareResponses.get();
1499    final long compareTimes      = totalCompareResponseTime.get();
1500    final long deleteRequests    = numDeleteRequests.get();
1501    final long deleteResponses   = numDeleteResponses.get();
1502    final long deleteTimes       = totalDeleteResponseTime.get();
1503    final long extendedRequests  = numExtendedRequests.get();
1504    final long extendedResponses = numExtendedResponses.get();
1505    final long extendedTimes     = totalExtendedResponseTime.get();
1506    final long modifyRequests    = numModifyRequests.get();
1507    final long modifyResponses   = numModifyResponses.get();
1508    final long modifyTimes       = totalModifyResponseTime.get();
1509    final long modifyDNRequests  = numModifyDNRequests.get();
1510    final long modifyDNResponses = numModifyDNResponses.get();
1511    final long modifyDNTimes     = totalModifyDNResponseTime.get();
1512    final long searchRequests    = numSearchRequests.get();
1513    final long searchEntries     = numSearchEntryResponses.get();
1514    final long searchReferences  = numSearchReferenceResponses.get();
1515    final long searchDone        = numSearchDoneResponses.get();
1516    final long searchTimes       = totalSearchResponseTime.get();
1517    final long unbindRequests    = numUnbindRequests.get();
1518
1519    final DecimalFormat f = new DecimalFormat("0.000");
1520
1521    buffer.append("LDAPConnectionStatistics(numConnects=");
1522    buffer.append(connects);
1523    buffer.append(", numDisconnects=");
1524    buffer.append(disconnects);
1525
1526    buffer.append(", numAbandonRequests=");
1527    buffer.append(abandonRequests);
1528
1529    buffer.append(", numAddRequests=");
1530    buffer.append(addRequests);
1531    buffer.append(", numAddResponses=");
1532    buffer.append(addResponses);
1533    buffer.append(", totalAddResponseTimeNanos=");
1534    buffer.append(addTimes);
1535    if (addTimes > 0L)
1536    {
1537      buffer.append(", averageAddResponseTimeNanos=");
1538      buffer.append(f.format(1.0d * addResponses / addTimes));
1539    }
1540
1541    buffer.append(", numBindRequests=");
1542    buffer.append(bindRequests);
1543    buffer.append(", numBindResponses=");
1544    buffer.append(bindResponses);
1545    buffer.append(", totalBindResponseTimeNanos=");
1546    buffer.append(bindTimes);
1547    if (bindTimes > 0L)
1548    {
1549      buffer.append(", averageBindResponseTimeNanos=");
1550      buffer.append(f.format(1.0d * bindResponses / bindTimes));
1551    }
1552
1553    buffer.append(", numCompareRequests=");
1554    buffer.append(compareRequests);
1555    buffer.append(", numCompareResponses=");
1556    buffer.append(compareResponses);
1557    buffer.append(", totalCompareResponseTimeNanos=");
1558    buffer.append(compareTimes);
1559    if (compareTimes > 0L)
1560    {
1561      buffer.append(", averageCompareResponseTimeNanos=");
1562      buffer.append(f.format(1.0d * compareResponses / compareTimes));
1563    }
1564
1565    buffer.append(", numDeleteRequests=");
1566    buffer.append(deleteRequests);
1567    buffer.append(", numDeleteResponses=");
1568    buffer.append(deleteResponses);
1569    buffer.append(", totalDeleteResponseTimeNanos=");
1570    buffer.append(deleteTimes);
1571    if (deleteTimes > 0L)
1572    {
1573      buffer.append(", averageDeleteResponseTimeNanos=");
1574      buffer.append(f.format(1.0d * deleteResponses / deleteTimes));
1575    }
1576
1577    buffer.append(", numExtendedRequests=");
1578    buffer.append(extendedRequests);
1579    buffer.append(", numExtendedResponses=");
1580    buffer.append(extendedResponses);
1581    buffer.append(", totalExtendedResponseTimeNanos=");
1582    buffer.append(extendedTimes);
1583    if (extendedTimes > 0L)
1584    {
1585      buffer.append(", averageExtendedResponseTimeNanos=");
1586      buffer.append(f.format(1.0d * extendedResponses / extendedTimes));
1587    }
1588
1589    buffer.append(", numModifyRequests=");
1590    buffer.append(modifyRequests);
1591    buffer.append(", numModifyResponses=");
1592    buffer.append(modifyResponses);
1593    buffer.append(", totalModifyResponseTimeNanos=");
1594    buffer.append(modifyTimes);
1595    if (modifyTimes > 0L)
1596    {
1597      buffer.append(", averageModifyResponseTimeNanos=");
1598      buffer.append(f.format(1.0d * modifyResponses / modifyTimes));
1599    }
1600
1601    buffer.append(", numModifyDNRequests=");
1602    buffer.append(modifyDNRequests);
1603    buffer.append(", numModifyDNResponses=");
1604    buffer.append(modifyDNResponses);
1605    buffer.append(", totalModifyDNResponseTimeNanos=");
1606    buffer.append(modifyDNTimes);
1607    if (modifyDNTimes > 0L)
1608    {
1609      buffer.append(", averageModifyDNResponseTimeNanos=");
1610      buffer.append(f.format(1.0d * modifyDNResponses / modifyDNTimes));
1611    }
1612
1613    buffer.append(", numSearchRequests=");
1614    buffer.append(searchRequests);
1615    buffer.append(", numSearchEntries=");
1616    buffer.append(searchEntries);
1617    buffer.append(", numSearchReferences=");
1618    buffer.append(searchReferences);
1619    buffer.append(", numSearchDone=");
1620    buffer.append(searchDone);
1621    buffer.append(", totalSearchResponseTimeNanos=");
1622    buffer.append(searchTimes);
1623    if (searchTimes > 0L)
1624    {
1625      buffer.append(", averageSearchResponseTimeNanos=");
1626      buffer.append(f.format(1.0d * searchDone / searchTimes));
1627    }
1628
1629    buffer.append(", numUnbindRequests=");
1630    buffer.append(unbindRequests);
1631
1632    buffer.append(')');
1633  }
1634}