public List addEventRegistration()

in firebase-database/src/main/java/com/google/firebase/database/core/SyncTree.java [542:645]


  public List<? extends Event> addEventRegistration(
      @NotNull final EventRegistration eventRegistration) {
    return persistenceManager.runInTransaction(
        new Callable<List<? extends Event>>() {
          @Override
          public List<? extends Event> call() {
            final QuerySpec query = eventRegistration.getQuerySpec();
            Path path = query.getPath();

            Node serverCacheNode = null;
            boolean foundAncestorDefaultView = false;
            // Any covering writes will necessarily be at the root, so really all we need to find is
            // the server cache. Consider optimizing this once there's a better understanding of
            // what actual behavior will be.
            // for (Map.Entry<QuerySpec, View> entry: views.entrySet()) {
            {
              ImmutableTree<SyncPoint> tree = syncPointTree;
              Path currentPath = path;
              while (!tree.isEmpty()) {
                SyncPoint currentSyncPoint = tree.getValue();
                if (currentSyncPoint != null) {
                  serverCacheNode =
                      serverCacheNode != null
                          ? serverCacheNode
                          : currentSyncPoint.getCompleteServerCache(currentPath);
                  foundAncestorDefaultView =
                      foundAncestorDefaultView || currentSyncPoint.hasCompleteView();
                }
                ChildKey front =
                    currentPath.isEmpty() ? ChildKey.fromString("") : currentPath.getFront();
                tree = tree.getChild(front);
                currentPath = currentPath.popFront();
              }
            }

            SyncPoint syncPoint = syncPointTree.get(path);
            if (syncPoint == null) {
              syncPoint = new SyncPoint(persistenceManager);
              syncPointTree = syncPointTree.set(path, syncPoint);
            } else {
              foundAncestorDefaultView = foundAncestorDefaultView || syncPoint.hasCompleteView();
              serverCacheNode =
                  serverCacheNode != null
                      ? serverCacheNode
                      : syncPoint.getCompleteServerCache(Path.getEmptyPath());
            }

            persistenceManager.setQueryActive(query);

            CacheNode serverCache;
            if (serverCacheNode != null) {
              serverCache =
                  new CacheNode(IndexedNode.from(serverCacheNode, query.getIndex()), true, false);
            } else {
              // Hit persistence
              CacheNode persistentServerCache = persistenceManager.serverCache(query);
              if (persistentServerCache.isFullyInitialized()) {
                serverCache = persistentServerCache;
              } else {
                serverCacheNode = EmptyNode.Empty();
                ImmutableTree<SyncPoint> subtree = syncPointTree.subtree(path);
                for (Map.Entry<ChildKey, ImmutableTree<SyncPoint>> child : subtree.getChildren()) {
                  SyncPoint childSyncPoint = child.getValue().getValue();
                  if (childSyncPoint != null) {
                    Node completeCache = childSyncPoint.getCompleteServerCache(Path.getEmptyPath());
                    if (completeCache != null) {
                      serverCacheNode =
                          serverCacheNode.updateImmediateChild(child.getKey(), completeCache);
                    }
                  }
                }
                // Fill the node with any available children we have
                for (NamedNode child : persistentServerCache.getNode()) {
                  if (!serverCacheNode.hasChild(child.getName())) {
                    serverCacheNode =
                        serverCacheNode.updateImmediateChild(child.getName(), child.getNode());
                  }
                }
                serverCache =
                    new CacheNode(
                        IndexedNode.from(serverCacheNode, query.getIndex()), false, false);
              }
            }

            boolean viewAlreadyExists = syncPoint.viewExistsForQuery(query);
            if (!viewAlreadyExists && !query.loadsAllData()) {
              // We need to track a tag for this query
              hardAssert(
                  !queryToTagMap.containsKey(query), "View does not exist but we have a tag");
              Tag tag = getNextQueryTag();
              queryToTagMap.put(query, tag);
              tagToQueryMap.put(tag, query);
            }
            WriteTreeRef writesCache = pendingWriteTree.childWrites(path);
            List<? extends Event> events =
                syncPoint.addEventRegistration(eventRegistration, writesCache, serverCache);
            if (!viewAlreadyExists && !foundAncestorDefaultView) {
              View view = syncPoint.viewForQuery(query);
              setupListener(query, view);
            }
            return events;
          }
        });
  }