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