From 9f0904fda87bfcf921deeccdbaeafe834fbad696 Mon Sep 17 00:00:00 2001
From: Yannick Lecaillez <yannick.lecaillez@forgerock.com>
Date: Fri, 24 Apr 2015 14:30:47 +0000
Subject: [PATCH] OPENDJ-1725: Persistit: very long recovery and many discarded txns after addrate test
---
opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java | 423 ++++++++++++++++++++--------------------------------
1 files changed, 166 insertions(+), 257 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
index 786251f..bba447a 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/backends/pluggable/EntryContainer.java
@@ -27,13 +27,12 @@
*/
package org.opends.server.backends.pluggable;
-import static org.forgerock.util.Utils.closeSilently;
+import static org.forgerock.util.Utils.*;
import static org.opends.messages.JebMessages.*;
import static org.opends.server.backends.pluggable.EntryIDSet.*;
import static org.opends.server.backends.pluggable.IndexFilter.*;
import static org.opends.server.backends.pluggable.JebFormat.*;
-import static org.opends.server.backends.pluggable.VLVIndex.encodeTargetAssertion;
-import static org.opends.server.backends.pluggable.VLVIndex.encodeVLVKey;
+import static org.opends.server.backends.pluggable.VLVIndex.*;
import static org.opends.server.core.DirectoryServer.*;
import static org.opends.server.protocols.ldap.LDAPResultCode.*;
import static org.opends.server.types.AdditionalLogItem.*;
@@ -47,6 +46,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.TreeMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -61,6 +61,7 @@
import org.forgerock.opendj.ldap.ByteStringBuilder;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.SearchScope;
+import org.opends.messages.CoreMessages;
import org.opends.server.admin.server.ConfigurationAddListener;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ConfigurationDeleteListener;
@@ -73,10 +74,10 @@
import org.opends.server.api.VirtualAttributeProvider;
import org.opends.server.api.plugin.PluginResult.SubordinateDelete;
import org.opends.server.api.plugin.PluginResult.SubordinateModifyDN;
-import org.opends.server.backends.pluggable.State.IndexFlag;
import org.opends.server.backends.pluggable.spi.Cursor;
import org.opends.server.backends.pluggable.spi.ReadOperation;
import org.opends.server.backends.pluggable.spi.ReadableTransaction;
+import org.opends.server.backends.pluggable.spi.SequentialCursor;
import org.opends.server.backends.pluggable.spi.Storage;
import org.opends.server.backends.pluggable.spi.StorageRuntimeException;
import org.opends.server.backends.pluggable.spi.TreeName;
@@ -124,14 +125,14 @@
{
private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
+ /** Number of EntryID to considers when building EntryIDSet from DN2ID. */
+ private static final int SCOPE_IDSET_LIMIT = 4096;
/** The name of the entry database. */
private static final String ID2ENTRY_DATABASE_NAME = ID2ENTRY_INDEX_NAME;
/** The name of the DN database. */
private static final String DN2ID_DATABASE_NAME = DN2ID_INDEX_NAME;
/** The name of the children index database. */
- private static final String ID2CHILDREN_DATABASE_NAME = ID2CHILDREN_INDEX_NAME;
- /** The name of the subtree index database. */
- private static final String ID2SUBTREE_DATABASE_NAME = ID2SUBTREE_INDEX_NAME;
+ private static final String ID2CHILDREN_COUNT_DATABASE_NAME = ID2CHILDREN_COUNT_NAME;
/** The name of the referral database. */
private static final String REFERRAL_DATABASE_NAME = REFERRAL_INDEX_NAME;
/** The name of the state database. */
@@ -158,17 +159,15 @@
private final Storage storage;
/** The DN database maps a normalized DN string to an entry ID (8 bytes). */
- private DN2ID dn2id;
+ private final DN2ID dn2id;
/** The entry database maps an entry ID (8 bytes) to a complete encoded entry. */
private ID2Entry id2entry;
- /** Index maps entry ID to an entry ID list containing its children. */
- private Index id2children;
- /** Index maps entry ID to an entry ID list containing its subordinates. */
- private Index id2subtree;
+ /** Store the number of children for each entry. */
+ private final ID2Count id2childrenCount;
/** The referral database maps a normalized DN string to labeled URIs. */
- private DN2URI dn2uri;
+ private final DN2URI dn2uri;
/** The state database maps a config DN to config entries. */
- private State state;
+ private final State state;
/** The set of attribute indexes. */
private final HashMap<AttributeType, AttributeIndex> attrIndexMap = new HashMap<AttributeType, AttributeIndex>();
@@ -455,6 +454,10 @@
this.storage = env;
this.rootContainer = rootContainer;
this.databasePrefix = baseDN.toNormalizedUrlSafeString();
+ this.id2childrenCount = new ID2Count(getIndexName(ID2CHILDREN_COUNT_DATABASE_NAME));
+ this.dn2id = new DN2ID(getIndexName(DN2ID_DATABASE_NAME), baseDN);
+ this.dn2uri = new DN2URI(getIndexName(REFERRAL_DATABASE_NAME), this);
+ this.state = new State(getIndexName(STATE_DATABASE_NAME));
config.addPluggableChangeListener(this);
@@ -490,16 +493,9 @@
id2entry = new ID2Entry(getIndexName(ID2ENTRY_DATABASE_NAME), entryDataConfig);
id2entry.open(txn);
-
- dn2id = new DN2ID(getIndexName(DN2ID_DATABASE_NAME), this);
+ id2childrenCount.open(txn);
dn2id.open(txn);
-
- state = new State(getIndexName(STATE_DATABASE_NAME));
state.open(txn);
-
- openSubordinateIndexes(txn, config);
-
- dn2uri = new DN2URI(getIndexName(REFERRAL_DATABASE_NAME), this);
dn2uri.open(txn);
for (String idx : config.listBackendIndexes())
@@ -538,15 +534,6 @@
}
}
- private NullIndex openNewNullIndex(WriteableTransaction txn, String name)
- {
- final TreeName treeName = getIndexName(name);
- final NullIndex index = new NullIndex(treeName);
- state.removeFlagsFromIndex(txn, treeName, IndexFlag.TRUSTED);
- txn.deleteTree(treeName);
- return index;
- }
-
/**
* Closes the entry container.
*
@@ -617,20 +604,9 @@
*
* @return The children database.
*/
- Index getID2Children()
+ ID2Count getID2ChildrenCount()
{
- return id2children;
- }
-
- /**
- * Get the subtree database used by this entry container.
- * The entryContainer must have been opened.
- *
- * @return The subtree database.
- */
- Index getID2Subtree()
- {
- return id2subtree;
+ return id2childrenCount;
}
/**
@@ -711,19 +687,37 @@
}
}
+ boolean hasSubordinates(final DN dn)
+ {
+ try
+ {
+ return storage.read(new ReadOperation<Boolean>()
+ {
+ @Override
+ public Boolean run(final ReadableTransaction txn) throws Exception
+ {
+ try (final SequentialCursor<?, ?> cursor = dn2id.openChildrenCursor(txn, dn))
+ {
+ return cursor.next();
+ }
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new StorageRuntimeException(e);
+ }
+ }
+
/**
- * Determine the number of subordinate entries for a given entry.
+ * Determine the number of children entries for a given entry.
*
* @param entryDN The distinguished name of the entry.
- * @param subtree <code>true</code> will include all the entries under the
- * given entries. <code>false</code> will only return the
- * number of entries immediately under the given entry.
- * @return The number of subordinate entries for the given entry or -1 if
+ * @return The number of children entries for the given entry or -1 if
* the entry does not exist.
* @throws StorageRuntimeException If an error occurs in the database.
*/
- long getNumSubordinates(final DN entryDN, final boolean subtree)
- throws StorageRuntimeException
+ long getNumberOfChildren(final DN entryDN) throws StorageRuntimeException
{
try
{
@@ -732,18 +726,8 @@
@Override
public Long run(ReadableTransaction txn) throws Exception
{
- EntryID entryID = dn2id.get(txn, entryDN);
- if (entryID != null)
- {
- final Index index = subtree ? id2subtree : id2children;
- final EntryIDSet entryIDSet = index.get(txn, entryID.toByteString());
- long count = entryIDSet.size();
- if (count != Long.MAX_VALUE)
- {
- return count;
- }
- }
- return -1L;
+ final EntryID entryID = dn2id.get(txn, entryDN);
+ return entryID != null ? id2childrenCount.getCount(txn, entryID) : -1;
}
});
}
@@ -897,30 +881,7 @@
if (!isBelowFilterThreshold(entryIDSet))
{
- // Evaluate the search scope against the id2children and id2subtree indexes
- EntryID baseID = dn2id.get(txn, aBaseDN);
- if (baseID == null)
- {
- LocalizableMessage message = ERR_JEB_SEARCH_NO_SUCH_OBJECT.get(aBaseDN);
- DN matchedDN = getMatchedDN(txn, aBaseDN);
- throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
- }
- ByteString baseIDData = baseID.toByteString();
-
- EntryIDSet scopeSet;
- if (searchScope == SearchScope.SINGLE_LEVEL)
- {
- scopeSet = id2children.get(txn, baseIDData);
- }
- else
- {
- scopeSet = id2subtree.get(txn, baseIDData);
- if (searchScope == SearchScope.WHOLE_SUBTREE)
- {
- // The id2subtree list does not include the base entry ID.
- scopeSet.add(baseID);
- }
- }
+ final EntryIDSet scopeSet = getIDSetFromScope(txn, aBaseDN, searchScope);
entryIDSet.retainAll(scopeSet);
if (debugBuffer != null)
{
@@ -1023,6 +984,46 @@
}
return null;
}
+
+ private EntryIDSet getIDSetFromScope(final ReadableTransaction txn, DN aBaseDN, SearchScope searchScope)
+ throws DirectoryException
+ {
+ final EntryIDSet scopeSet;
+ try
+ {
+ switch (searchScope.asEnum())
+ {
+ case BASE_OBJECT:
+ try (final SequentialCursor<?, EntryID> scopeCursor = dn2id.openCursor(txn, aBaseDN))
+ {
+ scopeSet = EntryIDSet.newDefinedSet(scopeCursor.getValue().longValue());
+ }
+ break;
+ case SINGLE_LEVEL:
+ try (final SequentialCursor<?, EntryID> scopeCursor = dn2id.openChildrenCursor(txn, aBaseDN))
+ {
+ scopeSet = newIDSetFromCursor(scopeCursor, false);
+ }
+ break;
+ case SUBORDINATES:
+ case WHOLE_SUBTREE:
+ try (final SequentialCursor<?, EntryID> scopeCursor = dn2id.openSubordinatesCursor(txn, aBaseDN))
+ {
+ scopeSet = newIDSetFromCursor(scopeCursor, searchScope.equals(SearchScope.WHOLE_SUBTREE));
+ }
+ break;
+ default:
+ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM,
+ CoreMessages.INFO_ERROR_SEARCH_SCOPE_NOT_ALLOWED.get());
+ }
+ }
+ catch (NoSuchElementException e)
+ {
+ throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, ERR_JEB_SEARCH_NO_SUCH_OBJECT.get(aBaseDN),
+ getMatchedDN(txn, aBaseDN), e);
+ }
+ return scopeSet;
+ }
});
}
catch (Exception e)
@@ -1031,6 +1032,21 @@
}
}
+ private static EntryIDSet newIDSetFromCursor(SequentialCursor<?, EntryID> cursor, boolean includeCurrent)
+ {
+ final long ids[] = new long[SCOPE_IDSET_LIMIT];
+ int offset = 0;
+ if (includeCurrent) {
+ ids[offset++] = cursor.getValue().longValue();
+ }
+ for(; offset < ids.length && cursor.next() ; offset++) {
+ ids[offset] = cursor.getValue().longValue();
+ }
+ return offset == SCOPE_IDSET_LIMIT
+ ? EntryIDSet.newUndefinedSet()
+ : EntryIDSet.newDefinedSet(Arrays.copyOf(ids, offset));
+ }
+
private <E1 extends Exception, E2 extends Exception>
void throwAllowedExceptionTypes(Exception e, Class<E1> clazz1, Class<E2> clazz2)
throws E1, E2
@@ -1515,6 +1531,7 @@
DN matchedDN = getMatchedDN(txn, baseDN);
throw new DirectoryException(ResultCode.NO_SUCH_OBJECT, message, matchedDN, null);
}
+ id2childrenCount.addDelta(txn, parentID, 1);
}
EntryID entryID = rootContainer.getNextEntryID();
@@ -1526,31 +1543,6 @@
final IndexBuffer indexBuffer = new IndexBuffer(EntryContainer.this);
indexInsertEntry(indexBuffer, entry, entryID);
- // Insert into id2children and id2subtree.
- // The database transaction locks on these records will be hotly
- // contested so we do them last so as to hold the locks for the
- // shortest duration.
- if (parentDN != null)
- {
- final ByteString parentIDKeyBytes = parentID.toByteString();
- indexBuffer.put(id2children, parentIDKeyBytes, entryID);
- indexBuffer.put(id2subtree, parentIDKeyBytes, entryID);
-
- // Iterate up through the superior entries, starting above the
- // parent.
- for (DN dn = getParentWithinBase(parentDN); dn != null; dn = getParentWithinBase(dn))
- {
- // Read the ID from dn2id.
- EntryID nodeID = dn2id.get(txn, dn);
- if (nodeID == null)
- {
- throw new StorageRuntimeException(ERR_JEB_MISSING_DN2ID_RECORD.get(dn).toString());
- }
-
- // Insert into id2subtree for this node.
- indexBuffer.put(id2subtree, nodeID.toByteString(), entryID);
- }
- }
indexBuffer.flush(txn);
if (addOperation != null)
@@ -1827,31 +1819,19 @@
// Remove from the indexes, in index config order.
indexRemoveEntry(indexBuffer, entry, leafID);
- // Remove the id2c and id2s records for this entry.
- final ByteString leafIDKeyBytes = leafID.toByteString();
- indexBuffer.remove(id2children, leafIDKeyBytes);
- indexBuffer.remove(id2subtree, leafIDKeyBytes);
+ // Remove the children counter for this entry.
+ id2childrenCount.deleteCount(txn, leafID);
// Iterate up through the superior entries from the target entry.
- boolean isParent = true;
- for (DN parentDN = getParentWithinBase(targetDN); parentDN != null;
- parentDN = getParentWithinBase(parentDN))
+ final DN parentDN = getParentWithinBase(targetDN);
+ if (parentDN != null)
{
- // Read the ID from dn2id.
- EntryID parentID = dn2id.get(txn, parentDN);
+ final EntryID parentID = dn2id.get(txn, parentDN);
if (parentID == null)
{
throw new StorageRuntimeException(ERR_JEB_MISSING_DN2ID_RECORD.get(parentDN).toString());
}
-
- ByteString parentIDBytes = parentID.toByteString();
- // Remove from id2children.
- if (isParent)
- {
- indexBuffer.remove(id2children, parentIDBytes, leafID);
- isParent = false;
- }
- indexBuffer.remove(id2subtree, parentIDBytes, leafID);
+ id2childrenCount.addDelta(txn, parentID, -1);
}
// Remove the entry from the entry cache.
@@ -1884,6 +1864,32 @@
return dn2id.get(txn, entryDN) != null;
}
+
+ boolean entryExists(final DN entryDN) throws StorageRuntimeException
+ {
+ final EntryCache<?> entryCache = DirectoryServer.getEntryCache();
+ if (entryCache != null && entryCache.containsEntry(entryDN))
+ {
+ return true;
+ }
+
+ try
+ {
+ return storage.read(new ReadOperation<Boolean>()
+ {
+ @Override
+ public Boolean run(ReadableTransaction txn) throws Exception
+ {
+ return dn2id.get(txn, entryDN) != null;
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new StorageRuntimeException(e);
+ }
+ }
+
/**
* Fetch an entry by DN, trying the entry cache first, then the database.
* Retrieves the requested entry, trying the entry cache first,
@@ -2346,21 +2352,12 @@
indexInsertEntry(buffer, newEntry, newID);
}
- // Add the new ID to id2children and id2subtree of new apex parent entry.
if(isApexEntryMoved)
{
- boolean isParent = true;
- for (DN dn = getParentWithinBase(newEntry.getName()); dn != null;
- dn = getParentWithinBase(dn))
+ final DN parentDN = getParentWithinBase(newEntry.getName());
+ if (parentDN != null)
{
- EntryID parentID = dn2id.get(txn, dn);
- ByteString parentIDKeyBytes = parentID.toByteString();
- if(isParent)
- {
- buffer.put(id2children, parentIDKeyBytes, newID);
- isParent = false;
- }
- buffer.put(id2subtree, parentIDKeyBytes, newID);
+ id2childrenCount.addDelta(txn, dn2id.get(txn, parentDN), 1);
}
}
}
@@ -2391,32 +2388,19 @@
tail.next = new MovedEntry(newID, newEntry, !newID.equals(oldID));
- // Remove the old ID from id2children and id2subtree of
- // the old apex parent entry.
if(oldSuperiorDN != null && isApexEntryMoved)
{
- boolean isParent = true;
- for (DN dn = oldSuperiorDN; dn != null; dn = getParentWithinBase(dn))
- {
- EntryID parentID = dn2id.get(txn, dn);
- ByteString parentIDKeyBytes = parentID.toByteString();
- if(isParent)
- {
- buffer.remove(id2children, parentIDKeyBytes, oldID);
- isParent = false;
- }
- buffer.remove(id2subtree, parentIDKeyBytes, oldID);
- }
+ // Since entry has moved, oldSuperiorDN has lost a child
+ id2childrenCount.addDelta(txn, dn2id.get(txn, oldSuperiorDN), -1);
+ }
+
+ if (!newID.equals(oldID))
+ {
+ id2childrenCount.addDelta(txn, newID, id2childrenCount.deleteCount(txn, oldID));
}
if (!newID.equals(oldID) || modifyDNOperation == null)
{
- // All the subordinates will be renumbered so we have to rebuild
- // id2c and id2s with the new ID.
- ByteString oldIDKeyBytes = oldID.toByteString();
- buffer.remove(id2children, oldIDKeyBytes);
- buffer.remove(id2subtree, oldIDKeyBytes);
-
// Reindex the entry with the new ID.
indexRemoveEntry(buffer, oldEntry, oldID);
}
@@ -2499,24 +2483,9 @@
tail.next = new MovedEntry(newID, newEntry, !newID.equals(oldID));
- if(isApexEntryMoved)
- {
- // Remove the old ID from id2subtree of old apex superior entries.
- for (DN dn = oldSuperiorDN; dn != null; dn = getParentWithinBase(dn))
- {
- EntryID parentID = dn2id.get(txn, dn);
- ByteString parentIDKeyBytes = parentID.toByteString();
- buffer.remove(id2subtree, parentIDKeyBytes, oldID);
- }
- }
-
if (!newID.equals(oldID))
{
- // All the subordinates will be renumbered so we have to rebuild
- // id2c and id2s with the new ID.
- ByteString oldIDKeyBytes = oldID.toByteString();
- buffer.remove(id2children, oldIDKeyBytes);
- buffer.remove(id2subtree, oldIDKeyBytes);
+ id2childrenCount.deleteCount(txn, oldID);
// Reindex the entry with the new ID.
indexRemoveEntry(buffer, oldEntry, oldID);
@@ -2642,35 +2611,31 @@
}
/**
- * Get a count of the number of entries stored in this entry container.
+ * Get a count of the number of entries stored in this entry container including the baseDN
*
- * @param txn a non null database transaction
- * @return The number of entries stored in this entry container.
- * @throws StorageRuntimeException If an error occurs in the database.
+ * @param txn
+ * a non null database transaction
+ * @return The number of entries stored in this entry container including the baseDN.
+ * @throws StorageRuntimeException
+ * If an error occurs in the database.
*/
- long getEntryCount(ReadableTransaction txn) throws StorageRuntimeException
+ long getNumberOfEntriesInBaseDN() throws StorageRuntimeException
{
- final EntryID entryID = dn2id.get(txn, baseDN);
- if (entryID != null)
+ try
{
- final EntryIDSet entryIDSet = id2subtree.get(txn, entryID.toByteString());
- long count = entryIDSet.size();
- if(count != Long.MAX_VALUE)
+ return storage.read(new ReadOperation<Long>()
{
- // Add the base entry itself
- return ++count;
- }
- else
- {
- // The count is not maintained. Fall back to the slow method
- return id2entry.getRecordCount(txn);
- }
+ @Override
+ public Long run(ReadableTransaction txn) throws Exception
+ {
+ final int baseDnIfExists = dn2id.get(txn, baseDN) != null ? 1 : 0;
+ return id2childrenCount.getTotalCount(txn) + baseDnIfExists;
+ }
+ });
}
- else
+ catch (Exception e)
{
- // Base entry doesn't not exist so this entry container
- // must not have any entries
- return 0;
+ throw new StorageRuntimeException(e);
}
}
@@ -2870,26 +2835,6 @@
@Override
public void run(WriteableTransaction txn) throws Exception
{
- if (config.isSubordinateIndexesEnabled() != cfg.isSubordinateIndexesEnabled())
- {
- openSubordinateIndexes(txn, cfg);
- }
-
- if (config.getIndexEntryLimit() != cfg.getIndexEntryLimit())
- {
- if (id2children.setIndexEntryLimit(cfg.getIndexEntryLimit()))
- {
- ccr.setAdminActionRequired(true);
- ccr.addMessage(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(id2children.getName()));
- }
-
- if (id2subtree.setIndexEntryLimit(cfg.getIndexEntryLimit()))
- {
- ccr.setAdminActionRequired(true);
- ccr.addMessage(NOTE_JEB_CONFIG_INDEX_ENTRY_LIMIT_REQUIRES_REBUILD.get(id2subtree.getName()));
- }
- }
-
DataConfig entryDataConfig = new DataConfig(cfg.isEntriesCompressed(),
cfg.isCompactEncoding(), rootContainer.getCompressedSchema());
id2entry.setDataConfig(entryDataConfig);
@@ -2969,11 +2914,7 @@
databases.add(dn2id);
databases.add(id2entry);
databases.add(dn2uri);
- if (config.isSubordinateIndexesEnabled())
- {
- databases.add(id2children);
- databases.add(id2subtree);
- }
+ databases.add(id2childrenCount);
databases.add(state);
for (AttributeIndex index : attrIndexMap.values())
@@ -3032,38 +2973,6 @@
return null;
}
- /** Opens the id2children and id2subtree indexes. */
- private void openSubordinateIndexes(WriteableTransaction txn, PluggableBackendCfg cfg)
- {
- if (cfg.isSubordinateIndexesEnabled())
- {
- TreeName name = getIndexName(ID2CHILDREN_DATABASE_NAME);
- id2children = new DefaultIndex(name, state, config.getIndexEntryLimit(), true, txn, this);
- id2children.open(txn);
- if (!id2children.isTrusted())
- {
- logger.info(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD, name);
- }
-
- name = getIndexName(ID2SUBTREE_DATABASE_NAME);
- id2subtree = new DefaultIndex(name, state, config.getIndexEntryLimit(), true, txn, this);
- id2subtree.open(txn);
- if (!id2subtree.isTrusted())
- {
- logger.info(NOTE_JEB_INDEX_ADD_REQUIRES_REBUILD, name);
- }
- }
- else
- {
- // Disabling subordinate indexes. Use a null index and ensure that
- // future attempts to use the real indexes will fail.
- id2children = openNewNullIndex(txn, ID2CHILDREN_DATABASE_NAME);
- id2subtree = openNewNullIndex(txn, ID2SUBTREE_DATABASE_NAME);
- logger.info(NOTE_JEB_SUBORDINATE_INDEXES_DISABLED, cfg.getBackendId());
- }
- }
-
-
/**
* Checks if any modifications apply to this indexed attribute.
* @param index the indexed attributes.
--
Gitblit v1.10.0