001/*
002 * Copyright 2010-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2019 Ping Identity Corporation
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.unboundidds.monitors;
022
023
024
025import java.util.Collections;
026import java.util.LinkedHashMap;
027import java.util.Map;
028
029import com.unboundid.ldap.sdk.Entry;
030import com.unboundid.util.NotMutable;
031import com.unboundid.util.StaticUtils;
032import com.unboundid.util.ThreadSafety;
033import com.unboundid.util.ThreadSafetyLevel;
034
035import static com.unboundid.ldap.sdk.unboundidds.monitors.MonitorMessages.*;
036
037
038
039/**
040 * This class defines a monitor entry that provides general information about
041 * the state of an index in a Directory Server backend.  Note that the term
042 * "index" may refer to a number of different things, including attribute
043 * indexes (in which each individual index type will be considered a separate
044 * index, so if "cn" has equality and substring index types then that will be
045 * considered two separate indexes), VLV indexes, and system indexes (for
046 * databases that are maintained internally, like id2entry, dn2id, id2children,
047 * and id2subtree).
048 * <BR>
049 * <BLOCKQUOTE>
050 *   <B>NOTE:</B>  This class, and other classes within the
051 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
052 *   supported for use against Ping Identity, UnboundID, and
053 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
054 *   for proprietary functionality or for external specifications that are not
055 *   considered stable or mature enough to be guaranteed to work in an
056 *   interoperable way with other types of LDAP servers.
057 * </BLOCKQUOTE>
058 * <BR>
059 * The set of index monitor entries published by the directory server can be
060 * obtained using the {@link MonitorManager#getIndexMonitorEntries} method.
061 * Specific methods are available for accessing the associated monitor data
062 * (e.g., {@link IndexMonitorEntry#getBackendID} to retrieve the backend ID),
063 * and there are also methods for accessing this information in a generic manner
064 * (e.g., {@link IndexMonitorEntry#getMonitorAttributes} to retrieve all of
065 * the monitor attributes).  See the {@link MonitorManager} class documentation
066 * for an example that demonstrates the use of the generic API for accessing
067 * monitor data.
068 */
069@NotMutable()
070@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
071public final class IndexMonitorEntry
072       extends MonitorEntry
073{
074  /**
075   * The structural object class used in index monitor entries.
076   */
077  static final String INDEX_MONITOR_OC = "ds-index-monitor-entry";
078
079
080
081  /**
082   * The name of the attribute that contains the index name.
083   */
084  private static final String ATTR_INDEX_NAME = "ds-index-name";
085
086
087
088  /**
089   * The name of the attribute that contains the backend ID.
090   */
091  private static final String ATTR_BACKEND_ID = "ds-index-backend-id";
092
093
094
095  /**
096   * The name of the attribute that contains the backend base DN.
097   */
098  private static final String ATTR_BASE_DN = "ds-index-backend-base-dn";
099
100
101
102  /**
103   * The name of the attribute that contains the name of the associated
104   * attribute type.
105   */
106  private static final String ATTR_INDEX_ATTR = "ds-index-attribute-type";
107
108
109
110  /**
111   * The name of the attribute that contains the name of the associated
112   * attribute index type.
113   */
114  private static final String ATTR_INDEX_TYPE = "ds-index-type";
115
116
117
118  /**
119   * The name of the attribute that contains the string representation of a
120   * filter used for the index.
121   */
122  private static final String ATTR_INDEX_FILTER = "ds-index-filter";
123
124
125
126  /**
127   * The name of the attribute that indicates whether the index is trusted.
128   */
129  private static final String ATTR_INDEX_TRUSTED = "ds-index-trusted";
130
131
132
133  /**
134   * The name of the attribute that contains the index entry limit.
135   */
136  private static final String ATTR_ENTRY_LIMIT = "ds-index-entry-limit";
137
138
139
140  /**
141   * The name of the attribute that contains the number of index keys for which
142   * the entry count has exceeded the limit since the index DB was opened.
143   */
144  private static final String ATTR_EXCEEDED_COUNT =
145       "ds-index-exceeded-entry-limit-count-since-db-open";
146
147
148
149  /**
150   * The name of the attribute that contains the number of unique index keys
151   * accessed by search operations that are near (typically, within 80% of) the
152   * index entry limit since the index DB was opened.
153   */
154  private static final String ATTR_SEARCH_KEYS_NEAR_LIMIT =
155       "ds-index-unique-keys-near-entry-limit-accessed-by-search-since-db-open";
156
157
158
159  /**
160   * The name of the attribute that contains the number of unique index keys
161   * accessed by search operations that are over the index entry limit since the
162   * index DB was opened.
163   */
164  private static final String ATTR_SEARCH_KEYS_OVER_LIMIT =
165       "ds-index-unique-keys-exceeding-entry-limit-accessed-by-search-since-" +
166            "db-open";
167
168
169
170  /**
171   * The name of the attribute that contains the number of unique index keys
172   * accessed by write operations that are near (typically, within 80% of) the
173   * index entry limit since the index DB was opened.
174   */
175  private static final String ATTR_WRITE_KEYS_NEAR_LIMIT =
176       "ds-index-unique-keys-near-entry-limit-accessed-by-write-since-db-open";
177
178
179
180  /**
181   * The name of the attribute that contains the number of unique index keys
182   * accessed by write operations that are over the index entry limit since the
183   * index DB was opened.
184   */
185  private static final String ATTR_WRITE_KEYS_OVER_LIMIT =
186       "ds-index-unique-keys-exceeding-entry-limit-accessed-by-write-since-" +
187            "db-open";
188
189
190
191  /**
192   * The name of the attribute that indicates whether a matching count should be
193   * maintained for a key that has exceeded the entry limit.
194   */
195  private static final String ATTR_MAINTAIN_COUNT =
196       "ds-index-maintain-count";
197
198
199
200  /**
201   * The name of the attribute that indicates whether the index was fully
202   * primed.
203   */
204  private static final String ATTR_FULLY_PRIMED =
205       "ds-index-fully-primed-at-backend-open";
206
207
208
209  /**
210   * The name of the attribute that contains a reason explaining why the prime
211   * was not completed.
212   */
213  private static final String ATTR_PRIME_INCOMPLETE_REASON =
214       "ds-index-prime-incomplete-reason";
215
216
217
218  /**
219   * The name of the attribute that contains information about an exception that
220   * was encountered while performing the prime.
221   */
222  private static final String ATTR_PRIME_EXCEPTION =
223       "ds-index-prime-exception";
224
225
226
227  /**
228   * The name of the attribute that contains the number of keys that were
229   * primed when the backend was opened.
230   */
231  private static final String ATTR_PRIMED_KEYS =
232       "ds-index-num-primed-keys-at-backend-open";
233
234
235
236  /**
237   * The name of the attribute that contains the number of times the index has
238   * been updated since the database was opened.
239   */
240  private static final String ATTR_WRITE_COUNT =
241       "ds-index-write-count-since-db-open";
242
243
244
245  /**
246   * The name of the attribute that contains the number of keys deleted from the
247   * index since the database was opened.
248   */
249  private static final String ATTR_DELETE_COUNT =
250       "ds-index-remove-count-since-db-open";
251
252
253
254  /**
255   * The name of the attribute that contains the number of read operations
256   * against the index since the database was opened.
257   */
258  private static final String ATTR_READ_COUNT =
259       "ds-index-read-count-since-db-open";
260
261
262
263  /**
264   * The name of the attribute that contains the number of read operations
265   * performed during search filter evaluation since the database was opened.
266   */
267  private static final String ATTR_READ_FOR_SEARCH_COUNT =
268       "ds-index-read-for-search-count-since-db-open";
269
270
271
272  /**
273   * The name of the attribute that contains the number of cursors created for
274   * the index.
275   */
276  private static final String ATTR_CURSOR_COUNT =
277       "ds-index-open-cursor-count-since-db-open";
278
279
280
281  /**
282   * The serial version UID for this serializable class.
283   */
284  private static final long serialVersionUID = 9182830448328951893L;
285
286
287
288  // Indicates whether the index was fully primed when the backend came online.
289  private final Boolean fullyPrimed;
290
291  // Indicates whether the index should be considered trusted.
292  private final Boolean indexTrusted;
293
294  // Indicates whether to maintain a count of matching entries even when the ID
295  // list is not maintained.
296  private final Boolean maintainCount;
297
298  // The index entry limit for the index.
299  private final Long entryLimit;
300
301  // The number of keys that have exceeded the entry limit since coming online.
302  private final Long exceededCount;
303
304  // The number of cursors created in the index since coming online.
305  private final Long numCursors;
306
307  // The number of index keys deleted from the index since coming online.
308  private final Long numDeletes;
309
310  // The number of reads from the index since coming online.
311  private final Long numReads;
312
313  // The number of reads as a result of filter processing from the index since
314  // coming online.
315  private final Long numReadsForSearch;
316
317  // The number of writes to the index since coming online.
318  private final Long numWrites;
319
320  // The number of keys that were primed when the backend came online.
321  private final Long primedKeys;
322
323  // The number of keys near the index entry limit that have been accessed by
324  // search operations since the index came online.
325  private final Long searchKeysNearLimit;
326
327  // The number of keys over the index entry limit that have been accessed by
328  // search operations since the index came online.
329  private final Long searchKeysOverLimit;
330
331  // The number of keys near the index entry limit that have been accessed by
332  // write operations since the index came online.
333  private final Long writeKeysNearLimit;
334
335  // The number of keys over the index entry limit that have been accessed by
336  // write operations since the index came online.
337  private final Long writeKeysOverLimit;
338
339  // The name of the associated attribute type.
340  private final String attributeType;
341
342  // The name of the associated backend ID.
343  private final String backendID;
344
345  // The base DN for the associated backend.
346  private final String baseDN;
347
348  // The filter for the associated index.
349  private final String indexFilter;
350
351  // The index name for the associated index.
352  private final String indexName;
353
354  // The index name of the index type for the index.
355  private final String indexType;
356
357  // Information about an exception caught during prime processing.
358  private final String primeException;
359
360  // Information about the reason the prime was not completed.
361  private final String primeIncompleteReason;
362
363
364
365  /**
366   * Creates a new index monitor entry from the provided entry.
367   *
368   * @param  entry  The entry to be parsed as an index monitor entry.  It must
369   *                not be {@code null}.
370   */
371  public IndexMonitorEntry(final Entry entry)
372  {
373    super(entry);
374
375    fullyPrimed           = getBoolean(ATTR_FULLY_PRIMED);
376    indexTrusted          = getBoolean(ATTR_INDEX_TRUSTED);
377    maintainCount         = getBoolean(ATTR_MAINTAIN_COUNT);
378    entryLimit            = getLong(ATTR_ENTRY_LIMIT);
379    exceededCount         = getLong(ATTR_EXCEEDED_COUNT);
380    numCursors            = getLong(ATTR_CURSOR_COUNT);
381    numDeletes            = getLong(ATTR_DELETE_COUNT);
382    numReads              = getLong(ATTR_READ_COUNT);
383    numReadsForSearch     = getLong(ATTR_READ_FOR_SEARCH_COUNT);
384    numWrites             = getLong(ATTR_WRITE_COUNT);
385    primedKeys            = getLong(ATTR_PRIMED_KEYS);
386    searchKeysNearLimit   = getLong(ATTR_SEARCH_KEYS_NEAR_LIMIT);
387    searchKeysOverLimit   = getLong(ATTR_SEARCH_KEYS_OVER_LIMIT);
388    writeKeysNearLimit    = getLong(ATTR_WRITE_KEYS_NEAR_LIMIT);
389    writeKeysOverLimit    = getLong(ATTR_WRITE_KEYS_OVER_LIMIT);
390    attributeType         = getString(ATTR_INDEX_ATTR);
391    backendID             = getString(ATTR_BACKEND_ID);
392    baseDN                = getString(ATTR_BASE_DN);
393    indexFilter           = getString(ATTR_INDEX_FILTER);
394    indexName             = getString(ATTR_INDEX_NAME);
395    indexType             = getString(ATTR_INDEX_TYPE);
396    primeException        = getString(ATTR_PRIME_EXCEPTION);
397    primeIncompleteReason = getString(ATTR_PRIME_INCOMPLETE_REASON);
398  }
399
400
401
402  /**
403   * Retrieves the name of the index database.
404   *
405   * @return  The name of the index database, or {@code null} if it was not
406   *          included in the monitor entry.
407   */
408  public String getIndexName()
409  {
410    return indexName;
411  }
412
413
414
415  /**
416   * Retrieves the backend ID for the associated backend.
417   *
418   * @return  The backend ID for the associated backend, or {@code null} if it
419   *          was not included in the monitor entry.
420   */
421  public String getBackendID()
422  {
423    return backendID;
424  }
425
426
427
428  /**
429   * Retrieves the base DN for the data with which the index is associated.
430   *
431   * @return  The base DN for the data with which the index is associated, or
432   *          {@code null} if it was not included in the monitor entry.
433   */
434  public String getBaseDN()
435  {
436    return baseDN;
437  }
438
439
440
441  /**
442   * Retrieves the name of the attribute type with which the index is
443   * associated.  It will only be available for attribute indexes.
444   *
445   * @return  The name of the attribute type with which the index is associated,
446   *          or {@code null} if it was not included in the monitor entry.
447   */
448  public String getAttributeType()
449  {
450    return attributeType;
451  }
452
453
454
455  /**
456   * Retrieves the name of the attribute index type.  It will only be available
457   * for attribute indexes.
458   *
459   * @return  The name of the attribute index type, or {@code null} if it was
460   *          not included in the monitor entry.
461   */
462  public String getAttributeIndexType()
463  {
464    return indexType;
465  }
466
467
468
469  /**
470   * Retrieves the filter used for the index.  It will only be available for
471   * filter indexes.
472   *
473   * @return  The filter used for the index, or {@code null} if it was not
474   *          included in the monitor entry.
475   */
476  public String getIndexFilter()
477  {
478    return indexFilter;
479  }
480
481
482
483  /**
484   * Indicates whether the index may be considered trusted.  It will only be
485   * available for attribute indexes.
486   *
487   * @return  {@code true} if the index may be considered trusted,
488   *          {@code false} if it is not trusted, or {@code null} if it was not
489   *          included in the monitor entry.
490   */
491  public Boolean isIndexTrusted()
492  {
493    return indexTrusted;
494  }
495
496
497
498  /**
499   * Retrieves the index entry limit, which is the maximum number of entries
500   * that will be allowed to match a key before the ID list for that key will
501   * stop being maintained.
502   *
503   * @return  The index entry limit, or {@code null} if was not included in the
504   *          monitor entry.
505   */
506  public Long getIndexEntryLimit()
507  {
508    return entryLimit;
509  }
510
511
512
513  /**
514   * Retrieves the number of index keys which have stopped being maintained
515   * because the number of matching entries has exceeded the entry limit since
516   * the index was brought online.
517   *
518   * @return  The number of index keys which have exceeded the entry limit since
519   *          the index was brought online, or {@code null} if it was not
520   *          included in the monitor entry.
521   */
522  public Long getEntryLimitExceededCountSinceComingOnline()
523  {
524    return exceededCount;
525  }
526
527
528
529  /**
530   * Retrieves the number of unique index keys near (typically, within 80% of)
531   * the index entry limit that have been accessed by search operations since
532   * the index was brought online.
533   *
534   * @return  The number of unique index keys near the index entry limit that
535   *          have been accessed by search operations since the index was
536   *          brought online, or {@code null} if it was not included in the
537   *          entry.
538   */
539  public Long getUniqueKeysNearEntryLimitAccessedBySearchSinceComingOnline()
540  {
541    return searchKeysNearLimit;
542  }
543
544
545
546  /**
547   * Retrieves the number of unique index keys over the index entry limit that
548   * have been accessed by search operations since the index was brought online.
549   *
550   * @return  The number of unique index keys over the index entry limit that
551   *          have been accessed by search operations since the index was
552   *          brought online, or {@code null} if it was not included in the
553   *          entry.
554   */
555  public Long getUniqueKeysOverEntryLimitAccessedBySearchSinceComingOnline()
556  {
557    return searchKeysOverLimit;
558  }
559
560
561
562  /**
563   * Retrieves the number of unique index keys near (typically, within 80% of)
564   * the index entry limit that have been accessed by add, delete, modify, or
565   * modify DN operations since the index was brought online.
566   *
567   * @return  The number of unique index keys near the index entry limit that
568   *          have been accessed by write operations since the index was
569   *          brought online, or {@code null} if it was not included in the
570   *          entry.
571   */
572  public Long getUniqueKeysNearEntryLimitAccessedByWriteSinceComingOnline()
573  {
574    return writeKeysNearLimit;
575  }
576
577
578
579  /**
580   * Retrieves the number of unique index keys over the index entry limit that
581   * have been accessed by add, delete, modify, or modify DN operations since
582   * the index was brought online.
583   *
584   * @return  The number of unique index keys over the index entry limit that
585   *          have been accessed by write operations since the index was
586   *          brought online, or {@code null} if it was not included in the
587   *          entry.
588   */
589  public Long getUniqueKeysOverEntryLimitAccessedByWriteSinceComingOnline()
590  {
591    return writeKeysOverLimit;
592  }
593
594
595
596  /**
597   * Indicates whether the count of matching entries will be maintained for
598   * index keys that have exceeded the entry limit.  In that case, the entry IDs
599   * for the matching entries will not be available, but the number of matching
600   * entries will be.
601   *
602   * @return  {@code true} if the count of matching entries will be maintained
603   *          for index keys that have exceeded the entry limit, {@code false}
604   *          if not, or {@code null} if it was not included in the monitor
605   *          entry.
606   */
607  public Boolean maintainCountForExceededKeys()
608  {
609    return maintainCount;
610  }
611
612
613
614  /**
615   * Indicates whether this index was fully primed when it was brought online.
616   *
617   * @return  {@code true} if the index was fully primed when it was brought
618   *          online, {@code false} if not, or {@code null} if it was not
619   *          included in the monitor entry.
620   */
621  public Boolean fullyPrimedWhenBroughtOnline()
622  {
623    return fullyPrimed;
624  }
625
626
627
628  /**
629   * Retrieves information about the reason that the index was not fully primed
630   * when the backend was brought online (e.g., the database cache became full,
631   * the prime took too long to complete, or an exception was caught during
632   * processing).
633   *
634   * @return  Information about the reason that the index was not fully primed
635   *          when the backend was brought online, or {@code null} if it was not
636   *          included in the monitor entry.
637   */
638  public String getPrimeIncompleteReason()
639  {
640    return primeIncompleteReason;
641  }
642
643
644
645  /**
646   * Retrieves information about any exception caught during prime processing.
647   *
648   * @return  Information about any exception caught during prime processing, or
649   *          {@code null} if it was not included in the monitor entry.
650   */
651  public String getPrimeException()
652  {
653    return primeException;
654  }
655
656
657
658  /**
659   * Retrieves the number of index keys that were primed when the index was
660   * brought online.
661   *
662   * @return  The number of index keys that were primed when the backend was
663   *          brought online, or {@code null} if it was not included in the
664   *          monitor entry.
665   */
666  public Long getKeysPrimedWhenBroughtOnline()
667  {
668    return primedKeys;
669  }
670
671
672
673  /**
674   * Retrieves the number of index keys that have been inserted or replaced
675   * since the index was brought online.
676   *
677   * @return  The number of index keys that have been inserted or replaced since
678   *          the index was brought online, or {@code null} if it was not
679   *          included in the monitor entry.
680   */
681  public Long getKeysWrittenSinceComingOnline()
682  {
683    return numWrites;
684  }
685
686
687
688  /**
689   * Retrieves the number of index keys that have been deleted since the index
690   * was brought online.
691   *
692   * @return  The number of index keys that have been deleted since the index
693   *          was brought online, or {@code null} if it was not included in the
694   *          monitor entry.
695   */
696  public Long getKeysDeletedSinceComingOnline()
697  {
698    return numDeletes;
699  }
700
701
702
703  /**
704   * Retrieves the number of index keys that have been read since the index was
705   * brought online.
706   *
707   * @return  The number of index keys that have been read since the index was
708   *          brought online, or {@code null} if it was not included in the
709   *          monitor entry.
710   */
711  public Long getKeysReadSinceComingOnline()
712  {
713    return numReads;
714  }
715
716
717
718  /**
719   * Retrieves the number of index reads that have been initiated because the
720   * associated attribute type was included in the filter for a search operation
721   * with a non-base scope since the index was brought online.
722   *
723   * @return  The number of index reads that have been initiated as a result of
724   *          filter processing, or {@code null} if it was not included in the
725   *          monitor entry.
726   */
727  public Long getFilterInitiatedReadsSinceComingOnline()
728  {
729    return numReadsForSearch;
730  }
731
732
733
734  /**
735   * Retrieves the number of cursors created in the index for reading ranges of
736   * keys.  Cursors may be used for processing in a variety of contexts,
737   * including processing for substring or range searches, subtree deletes,
738   * stream values operations, etc.
739   *
740   * @return  The number of cursors created in the index for reading ranges of
741   *          keys, or {@code null} if it was not included in the monitor entry.
742   */
743  public Long getCursorsCreatedSinceComingOnline()
744  {
745    return numCursors;
746  }
747
748
749
750  /**
751   * {@inheritDoc}
752   */
753  @Override()
754  public String getMonitorDisplayName()
755  {
756    return INFO_INDEX_MONITOR_DISPNAME.get();
757  }
758
759
760
761  /**
762   * {@inheritDoc}
763   */
764  @Override()
765  public String getMonitorDescription()
766  {
767    return INFO_INDEX_MONITOR_DESC.get();
768  }
769
770
771
772  /**
773   * {@inheritDoc}
774   */
775  @Override()
776  public Map<String,MonitorAttribute> getMonitorAttributes()
777  {
778    final LinkedHashMap<String,MonitorAttribute> attrs =
779         new LinkedHashMap<>(StaticUtils.computeMapCapacity(19));
780
781    if (indexName != null)
782    {
783      addMonitorAttribute(attrs,
784           ATTR_INDEX_NAME,
785           INFO_INDEX_DISPNAME_INDEX_NAME.get(),
786           INFO_INDEX_DESC_INDEX_NAME.get(),
787           indexName);
788    }
789
790    if (backendID != null)
791    {
792      addMonitorAttribute(attrs,
793           ATTR_BACKEND_ID,
794           INFO_INDEX_DISPNAME_BACKEND_ID.get(),
795           INFO_INDEX_DESC_BACKEND_ID.get(),
796           backendID);
797    }
798
799    if (baseDN != null)
800    {
801      addMonitorAttribute(attrs,
802           ATTR_BASE_DN,
803           INFO_INDEX_DISPNAME_BASE_DN.get(),
804           INFO_INDEX_DESC_BASE_DN.get(),
805           baseDN);
806    }
807
808    if (attributeType != null)
809    {
810      addMonitorAttribute(attrs,
811           ATTR_INDEX_ATTR,
812           INFO_INDEX_DISPNAME_ATTR_TYPE.get(),
813           INFO_INDEX_DESC_ATTR_TYPE.get(),
814           attributeType);
815    }
816
817    if (indexType != null)
818    {
819      addMonitorAttribute(attrs,
820           ATTR_INDEX_TYPE,
821           INFO_INDEX_DISPNAME_INDEX_TYPE.get(),
822           INFO_INDEX_DESC_INDEX_TYPE.get(),
823           indexType);
824    }
825
826    if (indexFilter != null)
827    {
828      addMonitorAttribute(attrs,
829           ATTR_INDEX_FILTER,
830           INFO_INDEX_DISPNAME_FILTER.get(),
831           INFO_INDEX_DESC_FILTER.get(),
832           indexFilter);
833    }
834
835    if (indexTrusted != null)
836    {
837      addMonitorAttribute(attrs,
838           ATTR_INDEX_TRUSTED,
839           INFO_INDEX_DISPNAME_TRUSTED.get(),
840           INFO_INDEX_DESC_TRUSTED.get(),
841           indexTrusted);
842    }
843
844    if (entryLimit != null)
845    {
846      addMonitorAttribute(attrs,
847           ATTR_ENTRY_LIMIT,
848           INFO_INDEX_DISPNAME_ENTRY_LIMIT.get(),
849           INFO_INDEX_DESC_ENTRY_LIMIT.get(),
850           entryLimit);
851    }
852
853    if (exceededCount != null)
854    {
855      addMonitorAttribute(attrs,
856           ATTR_EXCEEDED_COUNT,
857           INFO_INDEX_DISPNAME_EXCEEDED_COUNT.get(),
858           INFO_INDEX_DESC_EXCEEDED_COUNT.get(),
859           exceededCount);
860    }
861
862    if (searchKeysNearLimit != null)
863    {
864      addMonitorAttribute(attrs,
865           ATTR_SEARCH_KEYS_NEAR_LIMIT,
866           INFO_INDEX_DISPNAME_SEARCH_KEYS_NEAR_LIMIT.get(),
867           INFO_INDEX_DESC_SEARCH_KEYS_NEAR_LIMIT.get(),
868           searchKeysNearLimit);
869    }
870
871    if (searchKeysOverLimit != null)
872    {
873      addMonitorAttribute(attrs,
874           ATTR_SEARCH_KEYS_OVER_LIMIT,
875           INFO_INDEX_DISPNAME_SEARCH_KEYS_OVER_LIMIT.get(),
876           INFO_INDEX_DESC_SEARCH_KEYS_OVER_LIMIT.get(),
877           searchKeysOverLimit);
878    }
879
880    if (writeKeysNearLimit != null)
881    {
882      addMonitorAttribute(attrs,
883           ATTR_WRITE_KEYS_NEAR_LIMIT,
884           INFO_INDEX_DISPNAME_WRITE_KEYS_NEAR_LIMIT.get(),
885           INFO_INDEX_DESC_WRITE_KEYS_NEAR_LIMIT.get(),
886           writeKeysNearLimit);
887    }
888
889    if (writeKeysOverLimit != null)
890    {
891      addMonitorAttribute(attrs,
892           ATTR_WRITE_KEYS_OVER_LIMIT,
893           INFO_INDEX_DISPNAME_WRITE_KEYS_OVER_LIMIT.get(),
894           INFO_INDEX_DESC_WRITE_KEYS_OVER_LIMIT.get(),
895           writeKeysOverLimit);
896    }
897
898    if (maintainCount != null)
899    {
900      addMonitorAttribute(attrs,
901           ATTR_MAINTAIN_COUNT,
902           INFO_INDEX_DISPNAME_MAINTAIN_COUNT.get(),
903           INFO_INDEX_DESC_MAINTAIN_COUNT.get(),
904           maintainCount);
905    }
906
907    if (fullyPrimed != null)
908    {
909      addMonitorAttribute(attrs,
910           ATTR_FULLY_PRIMED,
911           INFO_INDEX_DISPNAME_FULLY_PRIMED.get(),
912           INFO_INDEX_DESC_FULLY_PRIMED.get(),
913           fullyPrimed);
914    }
915
916    if (primeIncompleteReason != null)
917    {
918      addMonitorAttribute(attrs,
919           ATTR_PRIME_INCOMPLETE_REASON,
920           INFO_INDEX_DISPNAME_PRIME_INCOMPLETE_REASON.get(),
921           INFO_INDEX_DESC_PRIME_INCOMPLETE_REASON.get(),
922           primeIncompleteReason);
923    }
924
925    if (primeException != null)
926    {
927      addMonitorAttribute(attrs,
928           ATTR_PRIME_EXCEPTION,
929           INFO_INDEX_DISPNAME_PRIME_EXCEPTION.get(),
930           INFO_INDEX_DESC_PRIME_EXCEPTION.get(),
931           primeException);
932    }
933
934    if (primedKeys != null)
935    {
936      addMonitorAttribute(attrs,
937           ATTR_PRIMED_KEYS,
938           INFO_INDEX_DISPNAME_PRIMED_KEYS.get(),
939           INFO_INDEX_DESC_PRIMED_KEYS.get(),
940           primedKeys);
941    }
942
943    if (numWrites != null)
944    {
945      addMonitorAttribute(attrs,
946           ATTR_WRITE_COUNT,
947           INFO_INDEX_DISPNAME_WRITE_COUNT.get(),
948           INFO_INDEX_DESC_WRITE_COUNT.get(),
949           numWrites);
950    }
951
952    if (numDeletes != null)
953    {
954      addMonitorAttribute(attrs,
955           ATTR_DELETE_COUNT,
956           INFO_INDEX_DISPNAME_DELETE_COUNT.get(),
957           INFO_INDEX_DESC_DELETE_COUNT.get(),
958           numDeletes);
959    }
960
961    if (numReads != null)
962    {
963      addMonitorAttribute(attrs,
964           ATTR_READ_COUNT,
965           INFO_INDEX_DISPNAME_READ_COUNT.get(),
966           INFO_INDEX_DESC_READ_COUNT.get(),
967           numReads);
968    }
969
970    if (numReadsForSearch != null)
971    {
972      addMonitorAttribute(attrs,
973           ATTR_READ_FOR_SEARCH_COUNT,
974           INFO_INDEX_DISPNAME_FILTER_INITIATED_READ_COUNT.get(),
975           INFO_INDEX_DESC_FILTER_INITIATED_READ_COUNT.get(),
976           numReadsForSearch);
977    }
978
979    if (numCursors != null)
980    {
981      addMonitorAttribute(attrs,
982           ATTR_CURSOR_COUNT,
983           INFO_INDEX_DISPNAME_CURSOR_COUNT.get(),
984           INFO_INDEX_DESC_CURSOR_COUNT.get(),
985           numCursors);
986    }
987
988    return Collections.unmodifiableMap(attrs);
989  }
990}