in core/src/main/java/com/jetbrains/youtrackdb/internal/core/db/tool/DatabaseCompare.java [345:510]
private void compareIndexes(EntityHelper.RIDMapper ridMapper) {
listener.onMessage("\nStarting index comparison:");
var ok = true;
final var indexManagerOne = sessionOne.getSharedContext().getIndexManager();
final var indexManagerTwo = sessionTwo.getSharedContext().getIndexManager();
final var indexesOne = indexManagerOne.getIndexes();
var indexesSizeOne = indexesOne.size();
var indexesSizeTwo = indexManagerTwo.getIndexes().size();
if (indexManagerTwo.getIndex(DatabaseImport.EXPORT_IMPORT_INDEX_NAME) != null) {
indexesSizeTwo--;
}
if (indexesSizeOne != indexesSizeTwo) {
ok = false;
listener.onMessage("\n- ERR: Amount of indexes are different.");
listener.onMessage("\n--- DB1: " + indexesSizeOne);
listener.onMessage("\n--- DB2: " + indexesSizeTwo);
listener.onMessage("\n");
++differences;
}
for (var indexOne : indexesOne) {
final var indexName = indexOne.getName();
if (excludeIndexes.contains(indexName)) {
continue;
}
final var indexTwo = indexManagerTwo.getIndex(indexOne.getName());
if (indexTwo == null) {
ok = false;
listener.onMessage("\n- ERR: Index " + indexOne.getName() + " is absent in DB2.");
++differences;
continue;
}
if (!indexOne.getType().equals(indexTwo.getType())) {
ok = false;
listener.onMessage(
"\n- ERR: Index types for index " + indexOne.getName() + " are different.");
listener.onMessage("\n--- DB1: " + indexOne.getType());
listener.onMessage("\n--- DB2: " + indexTwo.getType());
listener.onMessage("\n");
++differences;
continue;
}
if (!indexOne.getCollections().equals(indexTwo.getCollections())) {
ok = false;
listener.onMessage(
"\n- ERR: Collections to index for index " + indexOne.getName() + " are different.");
listener.onMessage("\n--- DB1: " + indexOne.getCollections());
listener.onMessage("\n--- DB2: " + indexTwo.getCollections());
listener.onMessage("\n");
++differences;
continue;
}
if (indexOne.getDefinition() == null && indexTwo.getDefinition() != null) {
// THIS IS NORMAL SINCE 3.0 DUE OF REMOVING OF INDEX WITHOUT THE DEFINITION, THE IMPORTER
// WILL CREATE THE DEFINITION
listener.onMessage(
"\n- WARN: Index definition for index " + indexOne.getName() + " for DB2 is not null.");
continue;
} else {
if (indexOne.getDefinition() != null && indexTwo.getDefinition() == null) {
ok = false;
listener.onMessage(
"\n- ERR: Index definition for index " + indexOne.getName() + " for DB2 is null.");
++differences;
continue;
} else {
if (indexOne.getDefinition() != null
&& !indexOne.getDefinition().equals(indexTwo.getDefinition())) {
ok = false;
listener.onMessage(
"\n- ERR: Index definitions for index " + indexOne.getName() + " are different.");
listener.onMessage("\n--- DB1: " + indexOne.getDefinition());
listener.onMessage("\n--- DB2: " + indexTwo.getDefinition());
listener.onMessage("\n");
++differences;
continue;
}
}
}
final var indexOneSize = indexOne.size(sessionOne);
final var indexTwoSize = indexTwo.size(sessionTwo);
if (indexOneSize != indexTwoSize) {
ok = false;
listener.onMessage(
"\n- ERR: Amount of entries for index " + indexOne.getName() + " are different.");
listener.onMessage("\n--- DB1: " + indexOneSize);
listener.onMessage("\n--- DB2: " + indexTwoSize);
listener.onMessage("\n");
++differences;
}
if (compareIndexMetadata) {
final var metadataOne = indexOne.getMetadata();
final var metadataTwo = indexTwo.getMetadata();
if (metadataOne == null && metadataTwo != null) {
ok = false;
listener.onMessage(
"\n- ERR: Metadata for index "
+ indexOne.getName()
+ " for DB1 is null but for DB2 is not.");
listener.onMessage("\n");
++differences;
} else {
if (metadataOne != null && metadataTwo == null) {
ok = false;
listener.onMessage(
"\n- ERR: Metadata for index "
+ indexOne.getName()
+ " for DB1 is not null but for DB2 is null.");
listener.onMessage("\n");
++differences;
} else {
if (!Objects.equals(metadataOne, metadataTwo)) {
ok = false;
listener.onMessage(
"\n- ERR: Metadata for index "
+ indexOne.getName()
+ " for DB1 and for DB2 are different.");
listener.onMessage("\n--- M1: " + metadataOne);
listener.onMessage("\n--- M2: " + metadataTwo);
listener.onMessage("\n");
++differences;
}
}
}
}
if (((compareEntriesForAutomaticIndexes && !indexOne.getType().equals("DICTIONARY"))
|| !indexOne.isAutomatic())) {
try (final var keyStream = indexOne.keyStream()) {
final var indexKeyIteratorOne = keyStream.iterator();
while (indexKeyIteratorOne.hasNext()) {
final var indexKey = indexKeyIteratorOne.next();
try (var indexOneStream = indexOne.getRids(sessionOne, indexKey)) {
try (var indexTwoValue = indexTwo.getRids(sessionTwo, indexKey)) {
differences +=
compareIndexStreams(
indexKey, indexOneStream, indexTwoValue, ridMapper, listener);
}
}
ok = ok && differences > 0;
}
}
}
}
if (ok) {
listener.onMessage("OK");
}
}