Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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!:
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1062,9 +1062,10 @@ int appendIndexStatusTable(TableBuilder builder, EntryContainer ec, Map<Index, S
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())
Expand Down Expand Up @@ -1113,12 +1114,30 @@ private void appendStatsNoData(TableBuilder builder, int columns)
}

/**
* 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 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 boolean nearLimit(long size, long entryLimit)
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,
Expand All @@ -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);
Expand All @@ -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
Expand All @@ -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;
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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]);
}
}
}
}
}
}
Loading