| | |
| | | |
| | | import org.opends.server.types.*; |
| | | import org.opends.server.util.StaticUtils; |
| | | import org.opends.server.backends.jeb.importLDIF.IntegerImportIDSet; |
| | | import org.opends.server.backends.jeb.importLDIF.ImportIDSet; |
| | | import static org.opends.messages.JebMessages.*; |
| | | |
| | |
| | | /** |
| | | * The comparator for index keys. |
| | | */ |
| | | private Comparator<byte[]> comparator; |
| | | private final Comparator<byte[]> comparator; |
| | | |
| | | /** |
| | | * The limit on the number of entry IDs that may be indexed by one key. |
| | |
| | | * Limit on the number of entry IDs that may be retrieved by cursoring |
| | | * through an index. |
| | | */ |
| | | private int cursorEntryLimit; |
| | | private final int cursorEntryLimit; |
| | | |
| | | /** |
| | | * Number of keys that have exceeded the entry limit since this |
| | |
| | | */ |
| | | boolean maintainCount; |
| | | |
| | | private State state; |
| | | private final State state; |
| | | |
| | | /** |
| | | * A flag to indicate if this index should be trusted to be consistent |
| | |
| | | private boolean rebuildRunning = false; |
| | | |
| | | //Thread local area to store per thread cursors. |
| | | private ThreadLocal<Cursor> curLocal = new ThreadLocal<Cursor>(); |
| | | |
| | | private final ThreadLocal<Cursor> curLocal = new ThreadLocal<Cursor>(); |
| | | |
| | | /** |
| | | * Create a new index object. |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Insert the specified import ID set into this index a the provided key. |
| | | * |
| | | * @param key The key to add the set to. |
| | | * @param importIdSet The set of import IDs. |
| | | * @param data Database entry to reuse for read. |
| | | * @param cursor A database cursor to use. |
| | | * @throws DatabaseException If an database error occurs. |
| | | */ |
| | | |
| | | private void |
| | | insert(DatabaseEntry key, ImportIDSet importIdSet, |
| | | DatabaseEntry data, Cursor cursor) throws DatabaseException { |
| | | OperationStatus status = |
| | | cursor.getSearchKey(key, data, LockMode.DEFAULT); |
| | | insertKey(DatabaseEntry key, ImportIDSet importIdSet, |
| | | DatabaseEntry data) throws DatabaseException { |
| | | OperationStatus status = read(null, key, data, LockMode.RMW); |
| | | if(status == OperationStatus.SUCCESS) { |
| | | ImportIDSet newImportIDSet = new IntegerImportIDSet(); |
| | | if (newImportIDSet.merge(data.getData(), importIdSet, |
| | | indexEntryLimit, maintainCount) && importIdSet.isDirty()) { |
| | | ImportIDSet newImportIDSet = new ImportIDSet(); |
| | | if (newImportIDSet.merge(data.getData(), importIdSet, indexEntryLimit, |
| | | maintainCount)) |
| | | { |
| | | entryLimitExceededCount++; |
| | | importIdSet.setDirty(false); |
| | | } |
| | | data.setData(newImportIDSet.toDatabase()); |
| | | cursor.putCurrent(data); |
| | | put(null, key, data); |
| | | } else if(status == OperationStatus.NOTFOUND) { |
| | | if(!importIdSet.isDefined() && importIdSet.isDirty()) { |
| | | if(!importIdSet.isDefined()) { |
| | | entryLimitExceededCount++; |
| | | importIdSet.setDirty(false); |
| | | } |
| | | data.setData(importIdSet.toDatabase()); |
| | | cursor.put(key,data); |
| | | put(null, key, data); |
| | | } else { |
| | | //Should never happen during import. |
| | | throw new DatabaseException(); |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Insert the specified import ID set into this index. Creates a DB |
| | | * cursor if needed. |
| | |
| | | cursor = openCursor(null, null); |
| | | curLocal.set(cursor); |
| | | } |
| | | insert(key, importIdSet, data, cursor); |
| | | insertKey(key, importIdSet, data); |
| | | } |
| | | |
| | | |
| | |
| | | boolean insert(ImportIDSet importIDSet, Set<byte[]> keySet, |
| | | DatabaseEntry keyData, DatabaseEntry data) |
| | | throws DatabaseException { |
| | | Cursor cursor = curLocal.get(); |
| | | if(cursor == null) { |
| | | cursor = openCursor(null, null); |
| | | curLocal.set(cursor); |
| | | } |
| | | for(byte[] key : keySet) { |
| | | keyData.setData(key); |
| | | insert(keyData, importIDSet, data, cursor); |
| | | insert(keyData, importIDSet, data); |
| | | } |
| | | keyData.setData(null); |
| | | data.setData(null); |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Reads a range of keys and collects all their entry IDs into a |
| | | * single set. |
| | |
| | | curLocal.remove(); |
| | | } |
| | | } |
| | | /** |
| | | * Increment the count of the number of keys that have exceeded the entry |
| | | * limit since this object was created. |
| | | */ |
| | | public void incEntryLimitExceededCount() |
| | | { |
| | | entryLimitExceededCount++; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * Update the index buffer for a deleted entry. |
| | |
| | | { |
| | | return maintainCount; |
| | | } |
| | | |
| | | /** |
| | | * Return an indexes comparator. |
| | | * |
| | | * @return The comparator related to an index. |
| | | */ |
| | | public Comparator<byte[]> getComparator() |
| | | { |
| | | return this.comparator; |
| | | } |
| | | } |