private static TreeResponse projectTreeJSON(TreeNode tree) { return new TreeResponse { id = tree.ID.ToString(), blobs = tree.Blobs.SelectAsArray(bl => new TreeBlobRefResponse { name = bl.Name, blobid = bl.BlobID.ToString() }), trees = tree.Trees.SelectAsArray(tr => new TreeTreeRefResponse { name = tr.Name, treeid = tr.TreeID.ToString() }) }; }
public Builder(TreeNode imm) { this.Trees = (imm.Trees).ToList((imm.Trees).Length); this.Blobs = (imm.Blobs).ToList((imm.Blobs).Length); }
private async Task<Errorable<TreeIDPathMapping>> getTreeIDByPath(TreeNode root, TreeTreePath path) { ReadOnlyCollection<string> parts = path.Path.Parts; if (parts.Count == 0) return new TreeIDPathMapping(path, path.RootTreeID); int j = 0; // Start descending into child nodes: TreeNode node = root, nextNode; while (node != null) { nextNode = null; // Check all child nodes against the next name in the path: for (int i = 0; i < node.Trees.Length; ++i) // TODO: specific string comparison logic! if (parts[j] == node.Trees[i].Name) { TreeID nextID = node.Trees[i].TreeID; // Run out of path components? This is it! if (++j == parts.Count) return new TreeIDPathMapping(path, (TreeID?)nextID); // Load up the next node so we can scan through its child nodes: var enextNode = await getTree(nextID).ConfigureAwait(continueOnCapturedContext: false); if (enextNode.HasErrors) return enextNode.Errors; nextNode = enextNode.Value; break; } // Attempt to continue: node = nextNode; } // If we got here it means that we didn't find what we were looking for: return new TreeIDPathMapping(path, (TreeID?)null); }
private async Task<Errorable<TreeNode>> persistTree(TreeNode tr) { Debug.Assert(tr != null); // Check that all referenced blobs are already persisted: foreach (var trbl in tr.Blobs) { if (!system.getPathByID(trbl.BlobID).Exists) return new BlobIDRecordDoesNotExistError(trbl.BlobID); } // Check that all referenced blobs are already persisted: foreach (var trtr in tr.Trees) { if (!system.getPathByID(trtr.TreeID).Exists) return new TreeIDRecordDoesNotExistError(trtr.TreeID); } // Write the tree contents to the file: FileInfo tmpFile = system.getTemporaryFile(); using (var fs = new FileStream(tmpFile.FullName, FileMode.CreateNew, FileAccess.Write, FileShare.None, bufferSize: 16384, useAsync: true)) { await fs.WriteRawAsync(tr.WriteTo(new StringBuilder()).ToString()); } lock (FileSystem.SystemLock) { FileInfo fi = system.getPathByID(tr.ID); // NOTE: if the record already exists we can either error out or overwrite the existing file with contents known to be good in the case the existing file got corrupt. // Let's stick with the self-repair scenario since erroring out doesn't help anyone. if (fi.Exists) { Debug.WriteLine(String.Format("Self-repair scenario: overwriting old TreeID {0} with new contents", tr.ID)); fi.Delete(); File.Move(tmpFile.FullName, fi.FullName); return tr; } // Create directory if it doesn't exist: if (!fi.Directory.Exists) { Debug.WriteLine(String.Format("New DIR '{0}'", fi.Directory.FullName)); fi.Directory.Create(); } Debug.WriteLine(String.Format("New TREE '{0}'", fi.FullName)); File.Move(tmpFile.FullName, fi.FullName); } return tr; }
private async Task<Errorable<TreeNode[]>> getTreeRecursively(TreeID id) { var eroot = await getTree(id).ConfigureAwait(continueOnCapturedContext: false); if (eroot.HasErrors) return eroot.Errors; var root = eroot.Value; var rootArr = new TreeNode[1] { root }; if (root.Trees.Length == 0) return rootArr; Task<Errorable<TreeNode[]>>[] tasks = new Task<Errorable<TreeNode[]>>[root.Trees.Length]; for (int i = 0; i < root.Trees.Length; ++i) { tasks[i] = getTreeRecursively(root.Trees[i].TreeID); } // Await all the tree retrievals: var allTrees = await Task.WhenAll(tasks).ConfigureAwait(continueOnCapturedContext: false); // Roll up all the errors: ErrorContainer errors = ( from etrs in allTrees where etrs.HasErrors select etrs.Errors ).Aggregate(new ErrorContainer(), (acc, err) => acc + err); if (errors.HasAny) return errors; // Flatten out the tree arrays: var flattened = from etrs in allTrees from tr in etrs.Value select tr; // Return the final array: return rootArr.Concat(flattened).ToArray(allTrees.Sum(ta => ta.Value.Length) + 1); }