public void AddFieldPath() { FieldMaskTree tree = new FieldMaskTree(); RepeatedField <string> paths = tree.ToFieldMask().Paths; Assert.AreEqual(0, paths.Count); tree.AddFieldPath(""); paths = tree.ToFieldMask().Paths; Assert.AreEqual(1, paths.Count); Assert.Contains("", paths); // New branch. tree.AddFieldPath("foo"); paths = tree.ToFieldMask().Paths; Assert.AreEqual(2, paths.Count); Assert.Contains("foo", paths); // Redundant path. tree.AddFieldPath("foo"); paths = tree.ToFieldMask().Paths; Assert.AreEqual(2, paths.Count); // New branch. tree.AddFieldPath("bar.baz"); paths = tree.ToFieldMask().Paths; Assert.AreEqual(3, paths.Count); Assert.Contains("bar.baz", paths); // Redundant sub-path. tree.AddFieldPath("foo.bar"); paths = tree.ToFieldMask().Paths; Assert.AreEqual(3, paths.Count); // New branch from a non-root node. tree.AddFieldPath("bar.quz"); paths = tree.ToFieldMask().Paths; Assert.AreEqual(4, paths.Count); Assert.Contains("bar.quz", paths); // A path that matches several existing sub-paths. tree.AddFieldPath("bar"); paths = tree.ToFieldMask().Paths; Assert.AreEqual(3, paths.Count); Assert.Contains("foo", paths); Assert.Contains("bar", paths); }
public void IntersectFieldPath() { FieldMaskTree tree = new FieldMaskTree(); FieldMaskTree result = new FieldMaskTree(); tree.MergeFromFieldMask(new FieldMask { Paths = { "foo", "bar.baz", "bar.quz" } }); // Empty path. tree.IntersectFieldPath("", result); RepeatedField <string> paths = result.ToFieldMask().Paths; Assert.AreEqual(0, paths.Count); // Non-exist path. tree.IntersectFieldPath("quz", result); paths = result.ToFieldMask().Paths; Assert.AreEqual(0, paths.Count); // Sub-path of an existing leaf. tree.IntersectFieldPath("foo.bar", result); paths = result.ToFieldMask().Paths; Assert.AreEqual(1, paths.Count); Assert.Contains("foo.bar", paths); // Match an existing leaf node. tree.IntersectFieldPath("foo", result); paths = result.ToFieldMask().Paths; Assert.AreEqual(1, paths.Count); Assert.Contains("foo", paths); // Non-exist path. tree.IntersectFieldPath("bar.foo", result); paths = result.ToFieldMask().Paths; Assert.AreEqual(1, paths.Count); Assert.Contains("foo", paths); // Match a non-leaf node. tree.IntersectFieldPath("bar", result); paths = result.ToFieldMask().Paths; Assert.AreEqual(3, paths.Count); Assert.Contains("foo", paths); Assert.Contains("bar.baz", paths); Assert.Contains("bar.quz", paths); }
/// <summary> /// Adds the intersection of this tree with the given <paramref name="path"/> to <paramref name="output"/>. /// </summary> public void IntersectFieldPath(string path, FieldMaskTree output) { if (root.Children.Count == 0) { return; } var parts = path.Split(FIELD_PATH_SEPARATOR); if (parts.Length == 0) { return; } var node = root; foreach (var part in parts) { if (node != root && node.Children.Count == 0) { // The given path is a sub-path of an existing leaf node in the tree. output.AddFieldPath(path); return; } if (!node.Children.TryGetValue(part, out node)) { return; } } // We found a matching node for the path. All leaf children of this matching // node is in the intersection. var paths = new List <string>(); GetFieldPaths(node, path, paths); foreach (var value in paths) { output.AddFieldPath(value); } }
public void MergeFromFieldMask() { FieldMaskTree tree = new FieldMaskTree(); tree.MergeFromFieldMask(new FieldMask { Paths = { "foo", "bar.baz", "bar.quz" } }); RepeatedField <string> paths = tree.ToFieldMask().Paths; Assert.AreEqual(3, paths.Count); Assert.Contains("foo", paths); Assert.Contains("bar.baz", paths); Assert.Contains("bar.quz", paths); tree.MergeFromFieldMask(new FieldMask { Paths = { "foo.bar", "bar" } }); paths = tree.ToFieldMask().Paths; Assert.AreEqual(2, paths.Count); Assert.Contains("foo", paths); Assert.Contains("bar", paths); }
private void Merge(FieldMaskTree tree, IMessage source, IMessage destination, FieldMask.MergeOptions options, bool useDynamicMessage) { if (useDynamicMessage) { var newSource = source.Descriptor.Parser.CreateTemplate(); newSource.MergeFrom(source.ToByteString()); var newDestination = source.Descriptor.Parser.CreateTemplate(); newDestination.MergeFrom(destination.ToByteString()); tree.Merge(newSource, newDestination, options); // Clear before merging: foreach (var fieldDescriptor in destination.Descriptor.Fields.InFieldNumberOrder()) { fieldDescriptor.Accessor.Clear(destination); } destination.MergeFrom(newDestination.ToByteString()); } else { tree.Merge(source, destination, options); } }