mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Valery Kharseko
6 hours ago 8c75bb517a6687a9e91389dafaf895f09927aa01
[#1135] Head the last near-limit column of backendstat show-index-status 80%, the threshold it counts from (#1138)
3 files modified
114 ■■■■■ changed files
opendj-doc-generated-ref/src/main/asciidoc/admin-guide/chap-indexing.adoc 4 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java 60 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/BackendStatTest.java 50 ●●●●● patch | view | raw | blame | history
opendj-doc-generated-ref/src/main/asciidoc/admin-guide/chap-indexing.adoc
@@ -12,7 +12,7 @@
  information: "Portions copyright [year] [name of copyright owner]".
 
  Copyright 2017 ForgeRock AS.
  Portions Copyright 2024 3A Systems LLC.
  Portions Copyright 2024-2026 3A Systems LLC.
////
:figure-caption!:
@@ -849,7 +849,7 @@
[source, console]
----
$ backendstat show-index-status --backendID userRoot --baseDN dc=example,dc=com
Index Name                            ... Index Valid  Record Count  Over Entry Limit  95%  90%  85%
Index Name                            ... Index Valid  Record Count  Over Entry Limit  95%  90%  80%
--------------------------------------...-----------------------------------------------------------
uniqueMember.uniqueMemberMatch        ... true         0             0                 0    0    0
mail.caseIgnoreIA5Match               ... true         10000         0                 0    0    0
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java
@@ -1062,9 +1062,10 @@
    builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_INDEX_CONFIDENTIAL.get());
    builder.appendHeading(INFO_LABEL_BACKEND_DEBUG_RECORD_COUNT.get());
    builder.appendHeading(INFO_LABEL_BACKEND_TOOL_INDEX_UNDEFINED_RECORD_COUNT.get());
    builder.appendHeading(LocalizableMessage.raw("95%"));
    builder.appendHeading(LocalizableMessage.raw("90%"));
    builder.appendHeading(LocalizableMessage.raw("85%"));
    for (int percent : NEAR_LIMIT_PERCENTS)
    {
      builder.appendHeading(LocalizableMessage.raw(percent + "%"));
    }
    int count = 0;
    for (AttributeIndex attrIndex : ec.getAttributeIndexes())
@@ -1113,12 +1114,30 @@
  }
  /**
   * Whether a key holding this many entries has come near the entry limit of its index. An
   * index-entry-limit of 0 is no limit at all, and no key is near it.
   * The percentages of the index entry limit heading the columns of keys near the limit, highest
   * first. Each column counts the keys holding from its percentage of the limit up to the
   * percentage of the column before it.
   */
  static boolean nearLimit(long size, long entryLimit)
  static final int[] NEAR_LIMIT_PERCENTS = { 95, 90, 80 };
  /**
   * The column of {@link #NEAR_LIMIT_PERCENTS} that counts a key holding this many entries, or -1
   * when the key has not come near the entry limit of its index. An index-entry-limit of 0 is no
   * limit at all, and no key is near it.
   */
  static int nearLimitColumn(long size, long entryLimit)
  {
    return entryLimit > 0 && size >= entryLimit * 0.8;
    if (entryLimit > 0)
    {
      for (int column = 0; column < NEAR_LIMIT_PERCENTS.length; column++)
      {
        if (size * 100 >= entryLimit * NEAR_LIMIT_PERCENTS[column])
        {
          return column;
        }
      }
    }
    return -1;
  }
  private void appendIndexStats(final TableBuilder builder, EntryContainer ec, final Index index,
@@ -1133,9 +1152,7 @@
        @Override
        public Void run(ReadableTransaction txn) throws Exception
        {
          long eighty = 0;
          long ninety = 0;
          long ninetyFive = 0;
          long[] nearLimit = new long[NEAR_LIMIT_PERCENTS.length];
          long undefined = 0;
          long count = 0;
          BackendTreeKeyValue keyDecoder = new BackendTreeKeyValue(index);
@@ -1157,20 +1174,10 @@
              if (entryIDSet.isDefined())
              {
                if (nearLimit(entryIDSet.size(), entryLimit))
                int column = nearLimitColumn(entryIDSet.size(), entryLimit);
                if (column >= 0)
                {
                  if (entryIDSet.size() >= entryLimit * 0.95)
                  {
                    ninetyFive++;
                  }
                  else if (entryIDSet.size() >= entryLimit * 0.9)
                  {
                    ninety++;
                  }
                  else
                  {
                    eighty++;
                  }
                  nearLimit[column]++;
                }
              }
              else
@@ -1192,9 +1199,10 @@
          }
          builder.appendCell(count);
          builder.appendCell(undefined);
          builder.appendCell(ninetyFive);
          builder.appendCell(ninety);
          builder.appendCell(eighty);
          for (long keys : nearLimit)
          {
            builder.appendCell(keys);
          }
          return null;
        }
      });
opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/BackendStatTest.java
@@ -16,6 +16,7 @@
package org.opends.server.backends.pluggable;
import static org.assertj.core.api.Assertions.*;
import static org.opends.server.backends.pluggable.BackendStat.*;
import org.opends.server.DirectoryServerTestCase;
import org.testng.annotations.Test;
@@ -29,15 +30,56 @@
  @Test
  public void testAKeyIsNearItsLimitFromEightyPercentOn()
  {
    assertThat(BackendStat.nearLimit(79, 100)).isFalse();
    assertThat(BackendStat.nearLimit(80, 100)).isTrue();
    assertThat(nearLimitColumn(79, 100)).isEqualTo(-1);
    assertThat(nearLimitColumn(80, 100)).isNotEqualTo(-1);
  }
  /** An index-entry-limit of 0 is no limit at all, and no key is near it (#1059). */
  @Test
  public void testNoKeyIsNearNoLimit()
  {
    assertThat(BackendStat.nearLimit(1, 0)).isFalse();
    assertThat(BackendStat.nearLimit(Integer.MAX_VALUE, 0)).isFalse();
    assertThat(nearLimitColumn(1, 0)).isEqualTo(-1);
    assertThat(nearLimitColumn(Integer.MAX_VALUE, 0)).isEqualTo(-1);
  }
  /** The columns are headed 95%, 90% and 80%: the last one counts keys from 80% of the limit (#1135). */
  @Test
  public void testTheColumnsAreHeadedByTheirThresholds()
  {
    assertThat(NEAR_LIMIT_PERCENTS).containsExactly(95, 90, 80);
    assertThat(NEAR_LIMIT_PERCENTS[nearLimitColumn(80, 100)]).isEqualTo(80);
    assertThat(NEAR_LIMIT_PERCENTS[nearLimitColumn(89, 100)]).isEqualTo(80);
    assertThat(NEAR_LIMIT_PERCENTS[nearLimitColumn(90, 100)]).isEqualTo(90);
    assertThat(NEAR_LIMIT_PERCENTS[nearLimitColumn(94, 100)]).isEqualTo(90);
    assertThat(NEAR_LIMIT_PERCENTS[nearLimitColumn(95, 100)]).isEqualTo(95);
    assertThat(NEAR_LIMIT_PERCENTS[nearLimitColumn(100, 100)]).isEqualTo(95);
  }
  /**
   * Every key a column counts holds at least the percentage of the limit that heads the column, and
   * less than the percentage heading the column before it.
   */
  @Test
  public void testEachColumnCountsTheKeysFromItsHeadingUpToThePreviousOne()
  {
    for (long entryLimit : new long[] { 1, 7, 100, 4000, 4001 })
    {
      for (long size = 0; size <= entryLimit; size++)
      {
        int column = nearLimitColumn(size, entryLimit);
        boolean nearLimit = size * 100 >= entryLimit * NEAR_LIMIT_PERCENTS[NEAR_LIMIT_PERCENTS.length - 1];
        assertThat(column >= 0).as("size %d of %d", size, entryLimit).isEqualTo(nearLimit);
        if (column >= 0)
        {
          assertThat(size * 100).as("size %d of %d", size, entryLimit)
              .isGreaterThanOrEqualTo(entryLimit * NEAR_LIMIT_PERCENTS[column]);
          if (column > 0)
          {
            assertThat(size * 100).as("size %d of %d", size, entryLimit)
                .isLessThan(entryLimit * NEAR_LIMIT_PERCENTS[column - 1]);
          }
        }
      }
    }
  }
}