FServerValues.m 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 "FChildrenNode.h"
  18. #import "FConstants.h"
  19. #import "FLeafNode.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
  27. withServerValues:(NSDictionary *)serverValues {
  28. if ([val isKindOfClass:[NSDictionary class]]) {
  29. NSDictionary *dict = val;
  30. if (dict[kServerValueSubKey] != nil) {
  31. NSString *serverValueType = [dict objectForKey:kServerValueSubKey];
  32. if (serverValues[serverValueType] != nil) {
  33. return [serverValues objectForKey:serverValueType];
  34. } else {
  35. // TODO: Throw unrecognizedServerValue error here
  36. }
  37. }
  38. }
  39. return val;
  40. }
  41. + (FCompoundWrite *)resolveDeferredValueCompoundWrite:(FCompoundWrite *)write
  42. withServerValues:
  43. (NSDictionary *)serverValues {
  44. __block FCompoundWrite *resolved = write;
  45. [write enumerateWrites:^(FPath *path, id<FNode> node, BOOL *stop) {
  46. id<FNode> resolvedNode =
  47. [FServerValues resolveDeferredValueSnapshot:node
  48. withServerValues:serverValues];
  49. // Node actually changed, use pointer inequality here
  50. if (resolvedNode != node) {
  51. resolved = [resolved addWrite:resolvedNode atPath:path];
  52. }
  53. }];
  54. return resolved;
  55. }
  56. + (id)resolveDeferredValueTree:(FSparseSnapshotTree *)tree
  57. withServerValues:(NSDictionary *)serverValues {
  58. FSparseSnapshotTree *resolvedTree = [[FSparseSnapshotTree alloc] init];
  59. [tree
  60. forEachTreeAtPath:[FPath empty]
  61. do:^(FPath *path, id<FNode> node) {
  62. [resolvedTree
  63. rememberData:
  64. [FServerValues
  65. resolveDeferredValueSnapshot:node
  66. withServerValues:serverValues]
  67. onPath:path];
  68. }];
  69. return resolvedTree;
  70. }
  71. + (id<FNode>)resolveDeferredValueSnapshot:(id<FNode>)node
  72. withServerValues:(NSDictionary *)serverValues {
  73. id priorityVal =
  74. [FServerValues resolveDeferredValue:[[node getPriority] val]
  75. withServerValues:serverValues];
  76. id<FNode> priority = [FSnapshotUtilities nodeFrom:priorityVal];
  77. if ([node isLeafNode]) {
  78. id value = [self resolveDeferredValue:[node val]
  79. withServerValues:serverValues];
  80. if (![value isEqual:[node val]] ||
  81. ![priority isEqual:[node getPriority]]) {
  82. return [[FLeafNode alloc] initWithValue:value
  83. withPriority:priority];
  84. } else {
  85. return node;
  86. }
  87. } else {
  88. __block FChildrenNode *newNode = node;
  89. if (![priority isEqual:[node getPriority]]) {
  90. newNode = [newNode updatePriority:priority];
  91. }
  92. [node enumerateChildrenUsingBlock:^(NSString *childKey,
  93. id<FNode> childNode, BOOL *stop) {
  94. id newChildNode =
  95. [FServerValues resolveDeferredValueSnapshot:childNode
  96. withServerValues:serverValues];
  97. if (![newChildNode isEqual:childNode]) {
  98. newNode = [newNode updateImmediateChild:childKey
  99. withNewChild:newChildNode];
  100. }
  101. }];
  102. return newNode;
  103. }
  104. }
  105. @end