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