FServerValues.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright 2017 Google
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import "FServerValues.h"
  17. #import "FConstants.h"
  18. #import "FLeafNode.h"
  19. #import "FChildrenNode.h"
  20. #import "FSnapshotUtilities.h"
  21. @implementation FServerValues
  22. + (NSDictionary*) generateServerValues:(id<FClock>)clock {
  23. long long millis = (long long)([clock currentTime] * 1000);
  24. return @{ @"timestamp": [NSNumber numberWithLongLong:millis] };
  25. }
  26. + (id) resolveDeferredValue:(id)val withServerValues:(NSDictionary*)serverValues {
  27. if ([val isKindOfClass:[NSDictionary class]]) {
  28. NSDictionary* dict = val;
  29. if (dict[kServerValueSubKey] != nil) {
  30. NSString* serverValueType = [dict objectForKey:kServerValueSubKey];
  31. if (serverValues[serverValueType] != nil) {
  32. return [serverValues objectForKey:serverValueType];
  33. } else {
  34. // TODO: Throw unrecognizedServerValue error here
  35. }
  36. }
  37. }
  38. return val;
  39. }
  40. + (FCompoundWrite *) resolveDeferredValueCompoundWrite:(FCompoundWrite *)write withServerValues:(NSDictionary *)serverValues {
  41. __block FCompoundWrite *resolved = write;
  42. [write enumerateWrites:^(FPath *path, id<FNode> node, BOOL *stop) {
  43. id<FNode> resolvedNode = [FServerValues resolveDeferredValueSnapshot:node withServerValues:serverValues];
  44. // Node actually changed, use pointer inequality here
  45. if (resolvedNode != node) {
  46. resolved = [resolved addWrite:resolvedNode atPath:path];
  47. }
  48. }];
  49. return resolved;
  50. }
  51. + (id) resolveDeferredValueTree:(FSparseSnapshotTree*)tree withServerValues:(NSDictionary*)serverValues {
  52. FSparseSnapshotTree* resolvedTree = [[FSparseSnapshotTree alloc] init];
  53. [tree forEachTreeAtPath:[FPath empty] do:^(FPath* path, id<FNode> node) {
  54. [resolvedTree rememberData:[FServerValues resolveDeferredValueSnapshot:node withServerValues:serverValues] onPath:path];
  55. }];
  56. return resolvedTree;
  57. }
  58. + (id<FNode>) resolveDeferredValueSnapshot:(id<FNode>)node withServerValues:(NSDictionary*)serverValues {
  59. id priorityVal = [FServerValues resolveDeferredValue:[[node getPriority] val] withServerValues:serverValues];
  60. id<FNode> priority = [FSnapshotUtilities nodeFrom:priorityVal];
  61. if ([node isLeafNode]) {
  62. id value = [self resolveDeferredValue:[node val] withServerValues:serverValues];
  63. if (![value isEqual:[node val]] || ![priority isEqual:[node getPriority]]) {
  64. return [[FLeafNode alloc] initWithValue:value withPriority:priority];
  65. } else {
  66. return node;
  67. }
  68. } else {
  69. __block FChildrenNode* newNode = node;
  70. if (![priority isEqual:[node getPriority]]) {
  71. newNode = [newNode updatePriority:priority];
  72. }
  73. [node enumerateChildrenUsingBlock:^(NSString *childKey, id<FNode> childNode, BOOL *stop) {
  74. id newChildNode = [FServerValues resolveDeferredValueSnapshot:childNode withServerValues:serverValues];
  75. if (![newChildNode isEqual:childNode]) {
  76. newNode = [newNode updateImmediateChild:childKey withNewChild:newChildNode];
  77. }
  78. }];
  79. return newNode;
  80. }
  81. }
  82. @end