in src/main/java/com/google/firebase/database/core/view/ViewProcessor.java [612:666]
public ViewCache revertUserWrite(
ViewCache viewCache,
Path path,
WriteTreeRef writesCache,
Node optCompleteServerCache,
ChildChangeAccumulator accumulator) {
if (writesCache.shadowingWrite(path) != null) {
return viewCache;
} else {
NodeFilter.CompleteChildSource source =
new WriteTreeCompleteChildSource(writesCache, viewCache, optCompleteServerCache);
IndexedNode oldEventCache = viewCache.getEventCache().getIndexedNode();
IndexedNode newEventCache;
if (path.isEmpty() || path.getFront().isPriorityChildName()) {
Node newNode;
if (viewCache.getServerCache().isFullyInitialized()) {
newNode = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());
} else {
newNode = writesCache.calcCompleteEventChildren(viewCache.getServerCache().getNode());
}
IndexedNode indexedNode = IndexedNode.from(newNode, this.filter.getIndex());
newEventCache = this.filter.updateFullNode(oldEventCache, indexedNode, accumulator);
} else {
ChildKey childKey = path.getFront();
Node newChild = writesCache.calcCompleteChild(childKey, viewCache.getServerCache());
if (newChild == null && viewCache.getServerCache().isCompleteForChild(childKey)) {
newChild = oldEventCache.getNode().getImmediateChild(childKey);
}
if (newChild != null) {
newEventCache =
this.filter.updateChild(
oldEventCache, childKey, newChild, path.popFront(), source, accumulator);
} else if (newChild == null && viewCache.getEventCache().getNode().hasChild(childKey)) {
// No complete child available, delete the existing one, if any
newEventCache =
this.filter.updateChild(
oldEventCache, childKey, EmptyNode.Empty(), path.popFront(), source, accumulator);
} else {
newEventCache = oldEventCache;
}
if (newEventCache.getNode().isEmpty() && viewCache.getServerCache().isFullyInitialized()) {
// We might have reverted all child writes. Maybe the old event was a leaf node
Node complete = writesCache.calcCompleteEventCache(viewCache.getCompleteServerSnap());
if (complete.isLeafNode()) {
IndexedNode indexedNode = IndexedNode.from(complete, this.filter.getIndex());
newEventCache = this.filter.updateFullNode(newEventCache, indexedNode, accumulator);
}
}
}
boolean complete =
viewCache.getServerCache().isFullyInitialized()
|| writesCache.shadowingWrite(Path.getEmptyPath()) != null;
return viewCache.updateEventSnap(newEventCache, complete, this.filter.filtersNodes());
}
}