diff --git a/opendj-doc-generated-ref/src/main/asciidoc/admin-guide/chap-indexing.adoc b/opendj-doc-generated-ref/src/main/asciidoc/admin-guide/chap-indexing.adoc index 6206f0e9e6..ec8c7f5fb0 100644 --- a/opendj-doc-generated-ref/src/main/asciidoc/admin-guide/chap-indexing.adoc +++ b/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 @@ $ stop-ds [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 diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java index 200c1b1805..c46ae2a13c 100644 --- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java +++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/BackendStat.java @@ -1062,9 +1062,10 @@ int appendIndexStatusTable(TableBuilder builder, EntryContainer ec, Map 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 @@ private void appendIndexStats(final TableBuilder builder, EntryContainer ec, fin @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 @@ public Void run(ReadableTransaction txn) throws Exception 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 @@ else if (entryIDSet.size() >= entryLimit * 0.9) } builder.appendCell(count); builder.appendCell(undefined); - builder.appendCell(ninetyFive); - builder.appendCell(ninety); - builder.appendCell(eighty); + for (long keys : nearLimit) + { + builder.appendCell(keys); + } return null; } }); diff --git a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/BackendStatTest.java b/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/BackendStatTest.java index 69321a1113..7cf883a0b1 100644 --- a/opendj-server-legacy/src/test/java/org/opends/server/backends/pluggable/BackendStatTest.java +++ b/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 @@ public class BackendStatTest extends DirectoryServerTestCase @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]); + } + } + } + } } }