in src/main/java/com/google/firebase/database/core/view/ViewProcessor.java [354:421]
private ViewCache applyUserOverwrite(
ViewCache oldViewCache,
Path changePath,
Node changedSnap,
WriteTreeRef writesCache,
Node optCompleteCache,
ChildChangeAccumulator accumulator) {
CacheNode oldEventSnap = oldViewCache.getEventCache();
ViewCache newViewCache;
NodeFilter.CompleteChildSource source =
new WriteTreeCompleteChildSource(writesCache, oldViewCache, optCompleteCache);
if (changePath.isEmpty()) {
IndexedNode newIndexed = IndexedNode.from(changedSnap, this.filter.getIndex());
IndexedNode newEventCache =
this.filter.updateFullNode(
oldViewCache.getEventCache().getIndexedNode(), newIndexed, accumulator);
newViewCache = oldViewCache.updateEventSnap(newEventCache, true, this.filter.filtersNodes());
} else {
ChildKey childKey = changePath.getFront();
if (childKey.isPriorityChildName()) {
IndexedNode newEventCache =
this.filter.updatePriority(oldViewCache.getEventCache().getIndexedNode(), changedSnap);
newViewCache =
oldViewCache.updateEventSnap(
newEventCache, oldEventSnap.isFullyInitialized(), oldEventSnap.isFiltered());
} else {
Path childChangePath = changePath.popFront();
Node oldChild = oldEventSnap.getNode().getImmediateChild(childKey);
Node newChild;
if (childChangePath.isEmpty()) {
// Child overwrite, we can replace the child
newChild = changedSnap;
} else {
Node childNode = source.getCompleteChild(childKey);
if (childNode != null) {
if (childChangePath.getBack().isPriorityChildName()
&& childNode.getChild(childChangePath.getParent()).isEmpty()) {
// This is a priority update on an empty node. If this node exists on
// the server, the
// server will send down the priority in the update, so ignore for now
newChild = childNode;
} else {
newChild = childNode.updateChild(childChangePath, changedSnap);
}
} else {
// There is no complete child node available
newChild = EmptyNode.Empty();
}
}
if (!oldChild.equals(newChild)) {
IndexedNode newEventSnap =
this.filter.updateChild(
oldEventSnap.getIndexedNode(),
childKey,
newChild,
childChangePath,
source,
accumulator);
newViewCache =
oldViewCache.updateEventSnap(
newEventSnap, oldEventSnap.isFullyInitialized(), this.filter.filtersNodes());
} else {
newViewCache = oldViewCache;
}
}
}
return newViewCache;
}