in src/main/java/com/google/firebase/database/core/view/ViewProcessor.java [292:352]
private ViewCache applyServerOverwrite(
ViewCache oldViewCache,
Path changePath,
Node changedSnap,
WriteTreeRef writesCache,
Node optCompleteCache,
boolean filterServerNode,
ChildChangeAccumulator accumulator) {
CacheNode oldServerSnap = oldViewCache.getServerCache();
IndexedNode newServerCache;
NodeFilter serverFilter = filterServerNode ? this.filter : this.filter.getIndexedFilter();
if (changePath.isEmpty()) {
newServerCache =
serverFilter.updateFullNode(
oldServerSnap.getIndexedNode(),
IndexedNode.from(changedSnap, serverFilter.getIndex()),
null);
} else if (serverFilter.filtersNodes() && !oldServerSnap.isFiltered()) {
// we want to filter the server node, but we didn't filter the server node yet, so
// simulate a
// full update
assert !changePath.isEmpty() : "An empty path should have been caught in the other branch";
ChildKey childKey = changePath.getFront();
Path updatePath = changePath.popFront();
Node newChild =
oldServerSnap.getNode().getImmediateChild(childKey).updateChild(updatePath, changedSnap);
IndexedNode newServerNode = oldServerSnap.getIndexedNode().updateChild(childKey, newChild);
newServerCache =
serverFilter.updateFullNode(oldServerSnap.getIndexedNode(), newServerNode, null);
} else {
ChildKey childKey = changePath.getFront();
if (!oldServerSnap.isCompleteForPath(changePath) && changePath.size() > 1) {
// We don't update incomplete nodes with updates intended for other listeners
return oldViewCache;
}
Path childChangePath = changePath.popFront();
Node childNode = oldServerSnap.getNode().getImmediateChild(childKey);
Node newChildNode = childNode.updateChild(childChangePath, changedSnap);
if (childKey.isPriorityChildName()) {
newServerCache = serverFilter.updatePriority(oldServerSnap.getIndexedNode(), newChildNode);
} else {
newServerCache =
serverFilter.updateChild(
oldServerSnap.getIndexedNode(),
childKey,
newChildNode,
childChangePath,
NO_COMPLETE_SOURCE,
null);
}
}
ViewCache newViewCache =
oldViewCache.updateServerSnap(
newServerCache,
oldServerSnap.isFullyInitialized() || changePath.isEmpty(),
serverFilter.filtersNodes());
NodeFilter.CompleteChildSource source =
new WriteTreeCompleteChildSource(writesCache, newViewCache, optCompleteCache);
return generateEventCacheAfterServerEvent(
newViewCache, changePath, writesCache, source, accumulator);
}