aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firebase/Database/Core/FWriteTreeRef.m
diff options
context:
space:
mode:
authorGravatar Paul Beusterien <paulbeusterien@google.com>2017-05-15 12:27:07 -0700
committerGravatar Paul Beusterien <paulbeusterien@google.com>2017-05-15 12:27:07 -0700
commit98ba64449a632518bd2b86fe8d927f4a960d3ddc (patch)
tree131d9c4272fa6179fcda6c5a33fcb3b1bd57ad2e /Firebase/Database/Core/FWriteTreeRef.m
parent32461366c9e204a527ca05e6e9b9404a2454ac51 (diff)
Initial
Diffstat (limited to 'Firebase/Database/Core/FWriteTreeRef.m')
-rw-r--r--Firebase/Database/Core/FWriteTreeRef.m133
1 files changed, 133 insertions, 0 deletions
diff --git a/Firebase/Database/Core/FWriteTreeRef.m b/Firebase/Database/Core/FWriteTreeRef.m
new file mode 100644
index 0000000..392369b
--- /dev/null
+++ b/Firebase/Database/Core/FWriteTreeRef.m
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2017 Google
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#import "FWriteTreeRef.h"
+#import "FPath.h"
+#import "FNode.h"
+#import "FWriteTree.h"
+#import "FChildrenNode.h"
+#import "FNamedNode.h"
+#import "FWriteRecord.h"
+#import "FIndex.h"
+#import "FCacheNode.h"
+
+@interface FWriteTreeRef ()
+/**
+* The path to this particular FWriteTreeRef. Used for calling methods on writeTree while exposing a simpler interface
+* to callers.
+*/
+@property (nonatomic, strong) FPath *path;
+/**
+* A reference to the actual tree of the write data. All methods are pass-through to the tree, but with the appropriate
+* path prefixed.
+*
+* This lets us make cheap references to points in the tree for sync points without having to copy and maintain all of
+* the data.
+*/
+@property (nonatomic, strong) FWriteTree *writeTree;
+@end
+
+/**
+* A FWriteTreeRef wraps a FWriteTree and a FPath, for convenient access to a particular subtree. All the methods just
+* proxy to the underlying FWriteTree.
+*/
+@implementation FWriteTreeRef
+- (id) initWithPath:(FPath *)aPath writeTree:(FWriteTree *)tree {
+ self = [super init];
+ if (self) {
+ self.path = aPath;
+ self.writeTree = tree;
+ }
+ return self;
+}
+
+/**
+* @return If possible, returns a complete event cache, using the underlying server data if possible. In addition, can
+* be used to get a cache that includes hidden writes, and excludes arbitrary writes. Note that customizing the returned
+* node can lead to a more expensive calculation.
+*/
+- (id <FNode>) calculateCompleteEventCacheWithCompleteServerCache:(id<FNode>)completeServerCache {
+ return [self.writeTree calculateCompleteEventCacheAtPath:self.path completeServerCache:completeServerCache excludeWriteIds:nil includeHiddenWrites:NO];
+}
+
+/**
+* @return If possible, returns a children node containing all of the complete children we have data for. The returned
+* data is a mix of the given server data and write data.
+*/
+- (FChildrenNode *) calculateCompleteEventChildrenWithCompleteServerChildren:(id<FNode>)completeServerChildren {
+ return [self.writeTree calculateCompleteEventChildrenAtPath:self.path completeServerChildren:completeServerChildren];
+}
+
+/**
+* Given that either the underlying server data has updated or the outstanding writes have been updating, determine what,
+* if anything, needs to be applied to the event cache.
+*
+* Possibilities:
+*
+* 1. No writes are shadowing. Events should be raised, the snap to be applied comes from the server data.
+*
+* 2. Some writes are completly shadowing. No events to be raised.
+*
+* 3. Is partially shadowed. Events should be raised.
+*
+* Either existingEventSnap or existingServerSnap must exist, this is validated via an assert.
+*/
+- (id<FNode>) calculateEventCacheAfterServerOverwriteWithChildPath:(FPath *)childPath existingEventSnap:(id <FNode>)existingEventSnap existingServerSnap:(id <FNode>)existingServerSnap {
+ return [self.writeTree calculateEventCacheAfterServerOverwriteAtPath:self.path childPath:childPath existingEventSnap:existingEventSnap existingServerSnap:existingServerSnap];
+}
+
+/**
+* Returns a node if there is a complete overwrite for this path. More specifically, if there is a write at a higher
+* path, this will return the child of that write relative to the write and this path.
+* Returns nil if there is no write at this path.
+*/
+- (id<FNode>) shadowingWriteAtPath:(FPath *)path {
+ return [self.writeTree shadowingWriteAtPath:[self.path child:path]];
+}
+
+/**
+* This method is used when processing child remove events on a query. If we can, we pull in children that are outside
+* the window, but may now be in the window.
+*/
+- (FNamedNode *)calculateNextNodeAfterPost:(FNamedNode *)post
+ completeServerData:(id<FNode>)completeServerData
+ reverse:(BOOL)reverse
+ index:(id<FIndex>)index
+{
+ return [self.writeTree calculateNextNodeAfterPost:post
+ atPath:self.path
+ completeServerData:completeServerData
+ reverse:reverse
+ index:index];
+}
+
+/**
+* Returns a complete child for a given server snap after applying all user writes or nil if there is no complete child
+* for this child key.
+*/
+- (id<FNode>) calculateCompleteChild:(NSString *)childKey cache:(FCacheNode *)existingServerCache {
+ return [self.writeTree calculateCompleteChildAtPath:self.path childKey:childKey cache:existingServerCache];
+}
+
+/**
+* @return a WriteTreeref for a child.
+*/
+- (FWriteTreeRef *) childWriteTreeRef:(NSString *)childKey {
+ return [[FWriteTreeRef alloc] initWithPath:[self.path childFromString:childKey] writeTree:self.writeTree];
+}
+
+
+@end