void (@NotNull Entry right, @NotNull List<? super Difference> result, boolean isRightContentCurrent) { DirectoryEntry e = (DirectoryEntry)right; if (!getPath().equals(e.getPath())) { result.add(new Difference(false, this, e, isRightContentCurrent)); } // most often we have the same children, so try processing it directly int commonIndex = 0; final int myChildrenSize = myChildren.size(); final int rightChildrenSize = e.myChildren.size(); final int minChildrenSize = Math.min(myChildrenSize, rightChildrenSize); while(commonIndex < minChildrenSize) { Entry childEntry = myChildren.get(commonIndex); Entry rightChildEntry = e.myChildren.get(commonIndex); if (childEntry.getNameId() == rightChildEntry.getNameId() && childEntry.isDirectory() == rightChildEntry.isDirectory()) { childEntry.collectDifferencesWith(rightChildEntry, result, isRightContentCurrent); } else { break; } ++commonIndex; } if (commonIndex == myChildrenSize && commonIndex == rightChildrenSize) return; Int2ObjectMap<Entry> uniqueNameIdToMyChildEntries = new Int2ObjectOpenHashMap<>(myChildrenSize - commonIndex); for (int i = commonIndex; i < myChildrenSize; ++i) { Entry childEntry = myChildren.get(i); uniqueNameIdToMyChildEntries.put(childEntry.getNameId(), childEntry); } Int2ObjectMap<Entry> uniqueNameIdToRightChildEntries = new Int2ObjectOpenHashMap<>(rightChildrenSize - commonIndex); Int2ObjectMap<Entry> myNameIdToRightChildEntries = new Int2ObjectOpenHashMap<>(rightChildrenSize - commonIndex); for(int i = commonIndex; i < rightChildrenSize; ++i) { Entry rightChildEntry = e.myChildren.get(i); int rightChildEntryNameId = rightChildEntry.getNameId(); Entry myChildEntry = uniqueNameIdToMyChildEntries.get(rightChildEntryNameId); if (myChildEntry != null && myChildEntry.isDirectory() == rightChildEntry.isDirectory()) { uniqueNameIdToMyChildEntries.remove(rightChildEntryNameId); myNameIdToRightChildEntries.put(rightChildEntryNameId, rightChildEntry); } else { uniqueNameIdToRightChildEntries.put(rightChildEntryNameId, rightChildEntry); } } if (!Paths.isCaseSensitive() && uniqueNameIdToMyChildEntries.size() > 0 && uniqueNameIdToRightChildEntries.size() > 0) { Map<String, Entry> nameToEntryMap = CollectionFactory.createCaseInsensitiveStringMap(uniqueNameIdToMyChildEntries.size()); for (Entry entry : uniqueNameIdToMyChildEntries.values()) { nameToEntryMap.put(entry.getName(), entry); } for (Entry rightChildEntry : uniqueNameIdToRightChildEntries.values()) { Entry myChildEntry = nameToEntryMap.get(rightChildEntry.getName()); if (myChildEntry != null && rightChildEntry.isDirectory() == myChildEntry.isDirectory()) { myNameIdToRightChildEntries.put(myChildEntry.getNameId(), rightChildEntry); uniqueNameIdToMyChildEntries.remove(myChildEntry.getNameId()); uniqueNameIdToRightChildEntries.remove(rightChildEntry.getNameId()); } } } for (Entry child : e.myChildren) { if (uniqueNameIdToRightChildEntries.containsKey(child.getNameId())) { child.collectCreatedDifferences(result, isRightContentCurrent); } } for (Entry child : myChildren) { if (uniqueNameIdToMyChildEntries.containsKey(child.getNameId())) { child.collectDeletedDifferences(result, isRightContentCurrent); } else { Entry itsChild = myNameIdToRightChildEntries.get(child.getNameId()); if (itsChild != null) child.collectDifferencesWith(itsChild, result, isRightContentCurrent); } } }