in oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/MapRecord.java [406:536]
boolean compare(MapRecord before, final NodeStateDiff diff) {
if (Record.fastEquals(this, before)) {
return true;
}
Segment segment = getSegment();
int head = segment.readInt(getRecordNumber());
if (isDiff(head)) {
int hash = segment.readInt(getRecordNumber(), 4);
RecordId keyId = segment.readRecordId(getRecordNumber(), 8);
final String key = reader.readString(keyId);
final RecordId value = segment.readRecordId(getRecordNumber(), 8, 1);
MapRecord base = reader.readMap(segment.readRecordId(getRecordNumber(), 8, 2));
boolean rv = base.compare(before, new DefaultNodeStateDiff() {
@Override
public boolean childNodeAdded(String name, NodeState after) {
return name.equals(key)
|| diff.childNodeAdded(name, after);
}
@Override
public boolean childNodeChanged(
String name, NodeState before, NodeState after) {
return name.equals(key)
|| diff.childNodeChanged(name, before, after);
}
@Override
public boolean childNodeDeleted(String name, NodeState before) {
return diff.childNodeDeleted(name, before);
}
});
if (rv) {
MapEntry beforeEntry = before.getEntry(key);
if (beforeEntry == null) {
rv = diff.childNodeAdded(
key,
reader.readNode(value));
} else if (!value.equals(beforeEntry.getValue())) {
rv = diff.childNodeChanged(
key,
beforeEntry.getNodeState(),
reader.readNode(value));
}
}
return rv;
}
Segment beforeSegment = before.getSegment();
int beforeHead = beforeSegment.readInt(before.getRecordNumber());
if (isDiff(beforeHead)) {
int hash = beforeSegment.readInt(before.getRecordNumber(), 4);
RecordId keyId = beforeSegment.readRecordId(before.getRecordNumber(), 8);
final String key = reader.readString(keyId);
final RecordId value = beforeSegment.readRecordId(before.getRecordNumber(), 8, 1);
MapRecord base = reader.readMap(beforeSegment.readRecordId(before.getRecordNumber(), 8, 2));
boolean rv = this.compare(base, new DefaultNodeStateDiff() {
@Override
public boolean childNodeAdded(String name, NodeState after) {
return diff.childNodeAdded(name, after);
}
@Override
public boolean childNodeChanged(
String name, NodeState before, NodeState after) {
return name.equals(key)
|| diff.childNodeChanged(name, before, after);
}
@Override
public boolean childNodeDeleted(String name, NodeState before) {
return name.equals(key)
|| diff.childNodeDeleted(name, before);
}
});
if (rv) {
MapEntry afterEntry = this.getEntry(key);
if (afterEntry == null) {
rv = diff.childNodeDeleted(
key,
reader.readNode(value));
} else if (!value.equals(afterEntry.getValue())) {
rv = diff.childNodeChanged(
key,
reader.readNode(value),
afterEntry.getNodeState());
}
}
return rv;
}
if (isBranch(beforeHead) && isBranch(head)) {
return compareBranch(before, this, diff);
}
Iterator<MapEntry> beforeEntries = before.getEntries().iterator();
Iterator<MapEntry> afterEntries = this.getEntries().iterator();
MapEntry beforeEntry = nextOrNull(beforeEntries);
MapEntry afterEntry = nextOrNull(afterEntries);
while (beforeEntry != null || afterEntry != null) {
int d = compare(beforeEntry, afterEntry);
if (d < 0) {
assert beforeEntry != null;
if (!diff.childNodeDeleted(
beforeEntry.getName(), beforeEntry.getNodeState())) {
return false;
}
beforeEntry = nextOrNull(beforeEntries);
} else if (d == 0) {
assert beforeEntry != null;
assert afterEntry != null;
if (!beforeEntry.getValue().equals(afterEntry.getValue())
&& !diff.childNodeChanged(
beforeEntry.getName(),
beforeEntry.getNodeState(),
afterEntry.getNodeState())) {
return false;
}
beforeEntry = nextOrNull(beforeEntries);
afterEntry = nextOrNull(afterEntries);
} else {
assert afterEntry != null;
if (!diff.childNodeAdded(
afterEntry.getName(), afterEntry.getNodeState())) {
return false;
}
afterEntry = nextOrNull(afterEntries);
}
}
return true;
}