示例#1
0
 public void SetChild(TreeBranch branch)
 {
     if (branches.Contains(branch))
     {
         if (childBranch1 != branch && childBranch2 != branch) // If the branch isn't already a child
         {
             if (childBranch1 == null)
             {
                 childBranch1 = branch;
             }
             else if (childBranch2 == null)
             {
                 childBranch2 = branch;
             }
             else
             {
                 throw new OverflowException("This node already has two children.");
             }
         }
     }
     else
     {
         throw new ArgumentException("Cannot set a branch as a child of this node if it isn't connected to this node.");
     }
 }
示例#2
0
            public void AddBranch(TreeBranch branch)
            {
                // A node can only support three connections
                if (branches.Count == 3)
                {
                    throw new OverflowException("This node already has 3 connections.");
                }
                else
                {
                    // If the branch being added connects this node to a leaf, and one of the other branches also
                    // connects to a leaf, this is a terminal node. Add this node to the list of terminal nodes.
                    if (branch.Follow(this).GetType() == typeof(TreeLeaf))
                    {
                        foreach (TreeBranch otherBranch in branches)
                        {
                            if (otherBranch.Follow(this).GetType() == typeof(TreeLeaf))
                            {
                                tree.terminalNodesList.Add(this);
                            }
                        }
                    }

                    branches.Add(branch);
                }
            }
示例#3
0
        private static void EvaluateDescriptionPosition(TreeBranch branch, string description, double x1, double y1, double x2, double y2, Graphics g, Font font, out double dx, out double dy)
        {
            double angle = Funcs.Atan(x1, y1, x2, y2);

            if (branch is ExpressionBranch)
            {
                ExpressionBranch e = branch as ExpressionBranch;

                double xt = x2 + e.DescriptionX * Math.Cos(angle + Math.PI);
                double yt = y2 - e.DescriptionX * Math.Sin(angle + Math.PI);

                double d = (branch as ExpressionBranch).DescriptionY;

                dx = xt + d * Math.Cos(angle + Math.PI / 2) + (branch as ExpressionBranch).DescriptionOffsetX;
                dy = yt - d * Math.Sin(angle + Math.PI / 2) + (branch as ExpressionBranch).DescriptionOffsetY;
            }
            else
            {
                dy = y1 - g.MeasureString(description, font).Height / 2;

                if (x2 < x1)
                {
                    dx = x1 + 5;
                }
                else
                {
                    dx = x1 - g.MeasureString(description, font).Width - 5;
                }
            }
        }
示例#4
0
    public void OnClickReset()
    {
        ResetOutput();
        TreeNode.ResetNodes();
        TreeBranch.ResetBranches();

        OnResetClicked();
    }
示例#5
0
            public void RemoveBranch(TreeBranch branch)
            {
                // List's Remove method handles low-count and not-in-list conditions,
                // so I won't handle them here.
                // bool removeFlag = branches.Remove(branch); Not sure why I need the return code.
                branches.Remove(branch);

                if (childBranch1 == branch)
                {
                    childBranch1 = null;
                }
                else if (childBranch2 == branch)
                {
                    childBranch2 = null;
                }


                //if (!removeFlag)
                //{
                //    return false;
                //}

                if (parentBranch == branch)
                {
                    RemoveParent();
                }

                // If the branch removal results in no connections, the node can be removed from the tree.
                if (branches.Count == 0)
                {
                    tree.nodesList.Remove(this);
                }
                else if (true)
                {
                    // If the branch was a terminal node and the branch being removed was connected to a leaf,
                    // if only one other branch is connected to a leaf, this is no longer a terminal node.
                    // Remove this node from the list of terminal nodes.
                    if (branch.Follow(this).GetType() == typeof(TreeLeaf))
                    {
                        int leafCount = 0;
                        foreach (TreeBranch otherBranch in branches)
                        {
                            if (otherBranch.Follow(this).GetType() == typeof(TreeLeaf))
                            {
                                leafCount += 1;
                            }
                        }

                        if (leafCount <= 1)
                        {
                            tree.terminalNodesList.Remove(this);
                        }
                    }
                }
                //return true;
            }
示例#6
0
        void AssertPaternity()
        // For each branch out from the given root which is not a parent branch, assign that branch
        // as the child's parent branch.
        // As this could be deeply recursive and could result in a stack overflow, this must be coded as a loop.
        {
            Stack <Tuple <TreeMember, TreeBranch> > arguments = new Stack <Tuple <TreeMember, TreeBranch> >();
            TreeBranch prevBranch = new TreeBranch();
            bool       stepBack   = false;

            foreach (TreeBranch rootBranch in root.Branches)
            {
                arguments.Push(Tuple.Create(rootBranch.Follow(root), rootBranch));

                while (arguments.Count > 0)
                {
                    Tuple <TreeMember, TreeBranch> nextArgument = arguments.Peek();
                    TreeMember member       = nextArgument.Item1;
                    TreeBranch parentBranch = nextArgument.Item2;
                    stepBack = false;

                    member.parentBranch = parentBranch;
                    ((TreeNode)parentBranch.Follow(member)).SetChild(parentBranch);

                    if (member.GetType() == typeof(TreeNode))
                    {
                        TreeNode node = (TreeNode)member;
                        if (node.Branches.Contains(prevBranch))
                        // If the previously-used branch is a member of this node's branches, that means we've already used the
                        // branches of this node, and can discard it.
                        {
                            stepBack = true;
                        }
                        else
                        {
                            foreach (TreeBranch branch in node.Branches)
                            {
                                if (branch != parentBranch)
                                {
                                    arguments.Push(Tuple.Create(branch.Follow(node), branch));
                                }
                            }
                        }
                    }
                    else
                    {
                        stepBack = true;
                    }

                    if (stepBack)
                    {
                        prevBranch = parentBranch;
                        arguments.Pop();
                    }
                }
            }
        }
    private bool TryDamageBranch(INetObject damager, float amount, InteractionContext context)
    {
        int        branchID = context.Parameters["branch"];
        TreeBranch branch   = this.branches[branchID];

        if (context.Parameters.ContainsKey("leaf"))
        {
            int leafID = context.Parameters["leaf"];

            // damage leaf
            LeafBunch leaf = branch.Leaves[leafID];

            if (leaf.Health > 0)
            {
                List <IAtomicAction> actions = new List <IAtomicAction>();
                if (damager is Player)
                {
                    var action = PlayerActions.HarvestLeaves.CreateAtomicAction(((Player)damager).User, this);
                    actions.Add(action);

                    if (!PlayerActions.HarvestLeaves.CreateAtomicAction(((Player)damager).User, this).CanApply().Notify((Player)damager))
                    {
                        // We only want to dispose the action if it is invalid.  Othewise we want to keep it around to possibly apply later.
                        action.Dispose();
                        return(false);
                    }
                }

                leaf.Health = Mathf.Max(0, leaf.Health - amount);

                if (leaf.Health <= 0)
                {
                    if (!new MultiAtomicAction(actions).TryApply().Success)
                    {
                        throw new Exception("Removing this stump was verified to be legal a moment ago, but is not anymore.");
                    }

                    leaf.Health = 0;
                    this.RPC("DestroyLeaves", branchID, leafID);
                }
                else
                {
                    new MultiAtomicAction(actions).Dispose();
                }
            }

            this.Save();
            return(true);
        }
        else
        {
            return(this.TryDamageBranch(branch, branchID, amount));
        }
    }
示例#8
0
        static double GetAverageBranchLength(TreeMember member, TreeBranch baseBranch, bool includeBranch, out int numLeaves)
        // From the given tree member, this will calculate the average branch length of the branches extending
        // from it. The switch "includeBranch" indicates whether the branch should be included in the numbers
        // (used for distance to the other end of the branch). If the TreeMember is a leaf, this function returns 0.
        {
            double averageBranchLength = 0;
            double sumBranchLength     = GetSumBranchLength(member, baseBranch, includeBranch, out numLeaves);

            averageBranchLength = sumBranchLength / numLeaves;

            return(averageBranchLength);
        }
    void DestroyLeaf(int branchID, int leafID)
    {
        TreeBranch branch = this.branches[branchID];
        LeafBunch  leaf   = branch.Leaves[leafID];

        if (leaf.Health > 0)
        {
            // replicate to all clients
            leaf.Health = 0;
            this.RPC("DestroyLeaves", branchID, leafID);
        }
    }
示例#10
0
    /// <summary>
    /// We override the create world object function for a tree. This is done as we need to load in multiple
    /// parts of the tree
    /// </summary>
    /// <param name="transform"></param>
    /// <returns></returns>
    public override WorldObject CreateWorldObject(Transform transform = null)
    {
        //Create random with seed unique to tree position - this ensures tree should be same every time.
        GenerationRandom genRan = new GenerationRandom(WorldPosition.x * World.WorldSize * World.ChunkSize + WorldPosition.z);
        int   canopy            = genRan.RandomInt(3, 7);
        float angleOffset       = genRan.Random(0, Mathf.PI);

        float       range    = Mathf.Sqrt(canopy * 0.5f) * 0.8f;
        WorldObject treeBase = WorldObject.CreateWorldObject(this, transform);
        Vec2i       zero     = new Vec2i(0, 0);

        Vector3[] canopyPositions = new Vector3[canopy];

        for (int i = 0; i < canopy; i++)
        {
            //Define the positions of each canopy as roughly circular about the middle of the tree.
            float   angle  = (Mathf.PI * 2 / (canopy)) * i + angleOffset;
            Vector2 delta  = new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * range + genRan.RandomVector2(-0.1f, 0.1f);
            float   height = 1.8f + genRan.Random(0, 1f);
            //Store the total position for use later, then generate the canopy itself.
            canopyPositions[i] = new Vector3(delta.x, height, delta.y);
            TreeCanopy tr = new TreeCanopy(zero, canopyPositions[i]);
            tr.SetRandom(genRan);
            tr.CreateWorldObject(treeBase.transform);
        }
        //Generate the trunk

        float      trunkHeight = 1.2f;
        float      trunkScale  = 1.2f;
        TreeBranch trunk       = new TreeBranch(zero);

        trunk.SetCharacteristic(Vector3.zero, new Vector3(0, 0, 0), new Vector3(1, trunkScale, 1));
        WorldObject trunkObj = trunk.CreateWorldObject(treeBase.transform);
        //MeshCollider mc  =trunkObj.gameObject.AddComponent<MeshCollider>();
        //mc.sharedMesh = trunkObj.gameObject.GetComponent<MeshFilter>().mesh;
        Vector3 trunkTop = Vector3.up * trunkHeight * trunkScale; //Scale to correct height

        foreach (Vector3 v in canopyPositions)
        {
            TreeBranch canopyBranch = new TreeBranch(zero);
            //Calculate the Euler angles from the branch base to the canopy
            Vector3 delta_pos = v - trunkTop;
            Quaternion.FromToRotation(Vector3.up, delta_pos);
            //Vector3 rot = Quaternion.FromToRotation(trunkTop, v*5f).eulerAngles;
            Vector3 rot   = Quaternion.FromToRotation(Vector3.up, delta_pos).eulerAngles;
            float   scale = Vector3.Distance(v, trunkTop) / trunkHeight;
            canopyBranch.SetCharacteristic(trunkTop, rot, new Vector3(1 / scale, scale, 1 / scale));
            canopyBranch.CreateWorldObject(treeBase.transform);
        }

        return(treeBase);
    }
    void DestroyBranch(int branchID)
    {
        TreeBranch branch = this.branches[branchID];

        if (branch.Health > 0)
        {
            // replicate to all clients
            branch.Health = 0;
            this.RPC("DestroyBranch", branchID);
        }

        this.Save();
    }
示例#12
0
    /// <summary>
    /// reset the tree for generating another one
    /// </summary>
    private void ResetTree()
    {
        for (int i = 0; i < TreeNode.Nodes.Count; i++)
        {
            Destroy(TreeNode.Nodes[i].GO);
        }
        TreeNode.Reset();

        for (int i = 0; i < TreeBranch.Branches.Count; i++)
        {
            Destroy(TreeBranch.Branches[i].GO);
        }
        TreeBranch.Reset();
    }
    private GameObject createResponseButton(TreeBranch branch)
    {
        GameObject responseButton = Instantiate(responseButtonPrefab);

        var responseButtonText = (Text)responseButton.GetComponent <Text>();

        responseButtonText.text = branch.description;

        var button = (Button)responseButton.GetComponent <Button>();

        button.onClick.AddListener(() => ClickResponseButton(branch.linkIndex));

        responseButton.transform.SetParent(responsePanel.transform, false);
        return(responseButton);
    }
示例#14
0
        void CountNodeChildren()
        // Walk the tree up from the terminal nodes and count the children of each node.
        {
            if (!isRooted)
            {
                throw new InvalidOperationException("The tree must be rooted to count children.");
            }

            foreach (TreeNode terminalNode in terminalNodesList)
            {
                terminalNode.childCount = 2;

                TreeNode currentNode = terminalNode;

                while (currentNode != root)
                {
                    TreeBranch parentBranch = currentNode.parentBranch;
                    TreeNode   parentNode   = (TreeNode)parentBranch.Follow(currentNode);
                    TreeBranch otherChildBranch;

                    if (parentNode.childBranch1 == parentBranch)
                    {
                        otherChildBranch = parentNode.childBranch2;
                    }
                    else // should be childBranch2
                    {
                        otherChildBranch = parentNode.childBranch1;
                    }

                    if (otherChildBranch.Follow(parentNode).GetType() == typeof(TreeLeaf))
                    {
                        parentNode.childCount = currentNode.childCount + 1;
                    }
                    else if (parentNode.childCount > 0)
                    {
                        parentNode.childCount += currentNode.childCount;
                    }
                    else
                    {
                        // Need to wait for another terminal node to propogate up.
                        parentNode.childCount += currentNode.childCount;
                        break;
                    }

                    currentNode = parentNode;
                }
            }
        }
示例#15
0
    private bool TryDamageBranch(INetObject damager, float amount, InteractionContext context)
    {
        int        branchID = context.Parameters["branch"];
        TreeBranch branch   = this.branches[branchID];

        if (context.Parameters.ContainsKey("leaf"))
        {
            int leafID = context.Parameters["leaf"];

            // damage leaf
            LeafBunch leaf = branch.Leaves[leafID];

            if (leaf.Health > 0)
            {
                leaf.Health = Mathf.Max(0, leaf.Health - amount);

                if (leaf.Health <= 0)
                {
                    leaf.Health = 0;

                    if (RandomUtil.Value < this.Species.SeedDropChance)
                    {
                        var    numSeeds      = (int)this.Species.SeedRange.Max;
                        int    numBonusSeeds = 0;
                        Item[] newSeeds      = new Item[] { };
                        if (numSeeds > 0 && this.Species.SeedItem != null)
                        {
                            var yield = ItemAttribute.Get <YieldAttribute>(this.Species.SeedItem.Type);
                            numBonusSeeds = yield != null?yield.Yield.GetCurrentValueInt(context.Player.User) : 0;

                            context.Player.User.Inventory.TryAddItems(this.Species.SeedItem.Type, numSeeds + numBonusSeeds);
                        }
                    }
                    this.RPC("DestroyLeaves", branchID, leafID);
                }
            }

            this.Save();
            return(true);
        }
        else
        {
            return(this.TryDamageBranch(branch, branchID, amount));
        }
    }
示例#16
0
        public async Task Tree(CommandContext ctx, Group group)
        {
            //Get teh user group
            if (group == null)
            {
                throw new ArgumentNullException($"The group does not exist.");
            }

            //Get the tree
            var tree = await TreeBranch.CreateTreeAsync(group);

            var sb = new StringBuilder();

            tree.BuildTreeString(sb);
            var export = sb.ToString();

            if (export.Length < 1980)
            {
                await ctx.ReplyAsync("```\n" + export + "\n```");
            }
            else
            {
                string tmppath = "tree_" + ctx.Guild.Id + "_" + group.Name + ".txt";
                try
                {
                    await System.IO.File.WriteAllTextAsync(tmppath, export);

                    await ctx.RespondWithFileAsync(tmppath, "Exported Groups:");

                    await ctx.ReplyReactionAsync(true);
                }
                catch (Exception)
                {
                    await ctx.ReplyReactionAsync(false);
                }
                finally
                {
                    if (System.IO.File.Exists(tmppath))
                    {
                        System.IO.File.Delete(tmppath);
                    }
                }
            }
        }
示例#17
0
        public async void EC02_RoleSubtraction()
        {
            var engine = new Engine();
            await engine.ImportAsync(@"
                ::everyone|0
                -group.contributor
                
                ::contributor
                +group.role.contributor

                ::role.builder
                +group.contributor

                ::user.vex
                +group.everyone
                +group.role.builder

                ::user.lachee
                +group.everyone

                ::user.nobody
                ::role.contributor
            ");

            var vex = await engine.GetGroupAsync("user.vex");

            Assert.NotNull(vex);

            var lachee = await engine.GetGroupAsync("user.lachee");

            Assert.NotNull(lachee);

            var nobody = await engine.GetGroupAsync("user.nobody");

            Assert.NotNull(nobody);

            var tree = await TreeBranch.CreateTreeAsync(vex);

            Assert.Equal(StateType.Allow, await vex.EvaluatePermissionAsync("group.role.contributor"));
            Assert.Equal(StateType.Deny, await lachee.EvaluatePermissionAsync("group.role.contributor"));
            Assert.Equal(StateType.Unset, await nobody.EvaluatePermissionAsync("group.role.contributor"));
        }
示例#18
0
    private static List <TreeBranch> getTreeBranchListFromDataStr(string linkDataStr)
    {
        List <TreeBranch> branchList = new List <TreeBranch>();

        var linkList = ParseHelper.getSplitList(linkDataStr, Environment.NewLine);

        foreach (var link in linkList)
        {
            TreeBranch tb           = new TreeBranch();
            var        linkDataList = ParseHelper.getSplitList(link, ":");
            tb.linkIndex   = Int64.Parse(linkDataList[0]);
            tb.description = ParseHelper.removeBlock(linkDataList[1], "{", "}");

            tb.conditionList = getTreeBranchConditionList(linkDataList[1]);

            branchList.Add(tb);
        }

        return(branchList);
    }
    private bool TryDamageBranch(TreeBranch branch, int branchID, float amount)
    {
        if (branch != null && branch.Health > 0)
        {
            branch.Health = Mathf.Max(0, branch.Health - amount);

            if (branch.Health <= 0)
            {
                branch.Health = 0;
                this.RPC("DestroyBranch", branchID);
                this.Save();
            }

            return(true);
        }
        else
        {
            return(false);
        }
    }
示例#20
0
    /// <summary>
    /// traces the path from the leaf back to the root
    /// </summary>
    /// <param name="leaf"></param>
    private void TracePathToRoot(TreeNode leaf)
    {
        Queue <TreeBranch> path = new Queue <TreeBranch> ();
        SpriteRenderer     sr;

        TreeNode node = leaf;

        //queue up all nodes from the leaf to the root
        while (node != TreeGenerator.root)
        {
            path.Enqueue(node.parentBranch);
            node = node.GetParent();
        }
        //change all subsequent branches according to the leaf's state
        while (path.Count > 0)
        {
            TreeBranch branch = path.Dequeue();
            sr        = branch.GO.GetComponent <SpriteRenderer> ();
            sr.sprite = activeBranch;
        }
    }
示例#21
0
            public static void Build(TreeMember member1, TreeMember member2, double length)
            {
                TreeBranch newBranch = new TreeBranch(member1, member2, length);

                if (member1.GetType() == typeof(TreeNode))
                {
                    ((TreeNode)member1).AddBranch(newBranch);
                }
                else
                {
                    member1.parentBranch = newBranch;
                }

                if (member2.GetType() == typeof(TreeNode))
                {
                    ((TreeNode)member2).AddBranch(newBranch);
                }
                else
                {
                    member2.parentBranch = newBranch;
                }
            }
示例#22
0
    /// <summary>
    /// recursive constructor that ends up creating all tree by itself
    /// </summary>
    /// <param name="branching">the number of links each node has down the tree</param>
    /// <param name="currentDepth">how far down the tree is this node</param>
    /// <param name="type">Max or Min</param>
    public TreeNode(int branching, int currentDepth, NodeType type)
    {
        //node gets new ID, seed, depth and type
        randomSeed = Random.value;
        ID         = Count++;
        Type       = type;
        this.depth = currentDepth;

        SetInitialValues();


        if (currentDepth < TreeGenerator.depth)
        {
            //sets up the branches linking to child nodes
            branches = new TreeBranch[branching];
            for (int i = 0; i < branches.Length; i++)
            {
                NodeType newType = ((currentDepth + 1) % 2 == 0) ? NodeType.Max : NodeType.Min;
                branches[i] = new TreeBranch(this, new TreeNode(branching, currentDepth + 1, newType));
                branches[i].b.parentBranch = branches[i];
            }

            leafID = null;
        }
        else
        {
            //if its the last depth level, it becomes a leaf
            Type     = NodeType.Leaf;
            branches = new TreeBranch[0];
            Score    = Random.Range(0, 20);
            leafID   = ID;
            leaves.Add(this);
        }

        nodes.Add(this);
    }
    private bool TryDamageBranch(INetObject damager, float amount, InteractionContext context)
    {
        int        branchID = context.Parameters["branch"];
        TreeBranch branch   = this.branches[branchID];

        if (context.Parameters.ContainsKey("leaf"))
        {
            int leafID = context.Parameters["leaf"];

            // damage leaf
            LeafBunch leaf = branch.Leaves[leafID];

            if (leaf.Health > 0)
            {
                List <IAtomicAction> actions = new List <IAtomicAction>();
                if (damager is Player)
                {
                    var action = PlayerActions.HarvestLeaves.CreateAtomicAction((Player)damager, this);
                    actions.Add(action);

                    if (!PlayerActions.HarvestLeaves.CreateAtomicAction((Player)damager, this).CanApply().Notify((Player)damager))
                    {
                        // We only want to dispose the action if it is invalid.  Othewise we want to keep it around to possibly apply later.
                        action.Dispose();
                        return(false);
                    }
                }

                leaf.Health = Mathf.Max(0, leaf.Health - amount);

                if (leaf.Health <= 0)
                {
                    if (!new MultiAtomicAction(actions).TryApply().Success)
                    {
                        throw new Exception("Removing this stump was verified to be legal a moment ago, but is not anymore.");
                    }

                    leaf.Health = 0;

                    if (RandomUtil.Value < this.Species.SeedDropChance)
                    {
                        var    numSeeds      = (int)this.Species.SeedRange.Max;
                        int    numBonusSeeds = 0;
                        Item[] newSeeds      = new Item[] { };
                        if (numSeeds > 0 && this.Species.SeedItem.Type != null)
                        {
                            var yield = ItemAttribute.Get <YieldAttribute>(this.Species.SeedItem.Type);
                            numBonusSeeds = yield != null?yield.Yield.GetCurrentValueInt(context.Player.User) : 0;

                            context.Player.User.Inventory.TryAddItems(this.Species.SeedItem.Type, numSeeds + numBonusSeeds);
                        }
                    }
                    this.RPC("DestroyLeaves", branchID, leafID);
                }
                else
                {
                    new MultiAtomicAction(actions).Dispose();
                }
            }

            this.Save();
            return(true);
        }
        else
        {
            return(this.TryDamageBranch(branch, branchID, amount));
        }
    }
示例#24
0
        public void CalculateSimilarities()
        // Construct a similarities matrix
        // Clustal does this by storing the path to root for each leaf (storing the distance), then finds the common ancestor
        // for each pair, storing the distance from the other sequence to it.
        //
        // I think a better implementation would be to loop over the leaves to get their paths to root, then for each pair,
        // walk their paths until they diverge
        {
            similarityMatrix = new double[leavesCount, leavesCount];

            Dictionary <TreeLeaf, List <Tuple <TreeNode, double> > > pathsToRoot = new Dictionary <TreeLeaf, List <Tuple <TreeNode, double> > >();

            foreach (TreeLeaf leaf in leavesList)
            {
                List <Tuple <TreeNode, double> > pathToRoot = new List <Tuple <TreeNode, double> >();

                double     distance     = 0;
                TreeBranch parentBranch = leaf.parentBranch;
                TreeNode   parentNode   = (TreeNode)parentBranch.Follow(leaf);

                while (true)
                {
                    distance += parentBranch.BranchLength;
                    pathToRoot.Add(Tuple.Create(parentNode, distance));
                    parentBranch = parentNode.parentBranch;
                    if (parentBranch != null)
                    {
                        parentNode = (TreeNode)parentBranch.Follow(parentNode);
                    }
                    else
                    {
                        break;
                    }
                }
                pathsToRoot.Add(leaf, pathToRoot);
            }


            for (int i = 0; i < leavesCount - 1; i++)
            {
                TreeLeaf leafI = leavesList[i];
                List <Tuple <TreeNode, double> > pathToRootI = pathsToRoot[leafI];

                for (int j = i + 1; j < leavesCount; j++)
                {
                    TreeLeaf leafJ = leavesList[j];
                    List <Tuple <TreeNode, double> > pathToRootJ = pathsToRoot[leafJ];
                    bool found = false;

                    foreach (Tuple <TreeNode, double> pathMemberI in pathToRootI)
                    {
                        foreach (Tuple <TreeNode, double> pathmemberJ in pathToRootJ)
                        {
                            if (pathMemberI.Item1 == pathmemberJ.Item1)
                            {
                                found = true;
                                similarityMatrix[i, j] = 1 - (pathMemberI.Item2 + pathmemberJ.Item2);
                                break;
                            }
                        }
                        if (found)
                        {
                            break;
                        }
                    }
                }
            }

            // Then Clustal forces any values less than 0.01 to be 0.01 (within the sequence ranges)
            // and sets small values above 1 to 1, but values above 1.1 go into an error handling method.
            // I won't implement this yet. Note that this is done while they are still in distances, not
            // similarities.
        }
示例#25
0
        void DetermineSteps()
        // Determine the groups to be used in each step of the alignment.
        // Step through the tree to find the terminal leaf-only nodes and step back to join them together,
        // with each step stored in a tuple, and the leaf groups 1 and 2 stored in lists in members 1 and 2 of the
        // tuple, respectively.
        // Possible to parallelize, but it looks like the overhead is generally too much for the work being done.
        // may want to test that on larger sets, however.
        {
            if (!isRooted)
            {
                throw new InvalidOperationException("The tree must be rooted to determine alignment steps.");
            }

            Dictionary <TreeNode, List <TreeLeaf> > waitingList = new Dictionary <TreeNode, List <TreeLeaf> >(); // Store the members of one child of the node until the other child has been evaluated.

            steps = new List <Tuple <ReadOnlyCollection <T>, ReadOnlyCollection <T>, double> >();

            foreach (TreeNode terminalNode in terminalNodesList)
            {
                List <TreeLeaf> group1 = new List <TreeLeaf>();
                TreeLeaf        leaf1  = (TreeLeaf)terminalNode.childBranch1.Follow(terminalNode);
                group1.Add(leaf1);
                List <TreeLeaf> group2 = new List <TreeLeaf>();
                TreeLeaf        leaf2  = (TreeLeaf)terminalNode.childBranch2.Follow(terminalNode);
                group2.Add(leaf2);


                steps.Add(CreateStep(group1, group2));

                TreeNode currentNode = terminalNode;

                List <TreeLeaf> childLeaves = new List <TreeLeaf>();
                childLeaves.Add(leaf1);
                childLeaves.Add(leaf2);

                while (currentNode != root)
                {
                    TreeBranch parentBranch = currentNode.parentBranch;
                    TreeNode   parentNode   = (TreeNode)parentBranch.Follow(currentNode);
                    TreeBranch otherChildBranch;

                    group1 = new List <TreeLeaf>();
                    group2 = new List <TreeLeaf>();

                    if (parentNode.childBranch1 == parentBranch)
                    {
                        otherChildBranch = parentNode.childBranch2;
                    }
                    else // should be childBranch2
                    {
                        otherChildBranch = parentNode.childBranch1;
                    }

                    if (otherChildBranch.Follow(parentNode).GetType() == typeof(TreeLeaf))
                    // The other child is a leaf, so we're okay.
                    {
                        group1 = childLeaves;
                        TreeLeaf otherChildLeaf = (TreeLeaf)otherChildBranch.Follow(parentNode);
                        group2.Add(otherChildLeaf);
                    }
                    else if (waitingList.ContainsKey(parentNode))
                    // The other child is a node which was waiting for the other children to be evaluated.
                    {
                        group1 = childLeaves.ToList <TreeLeaf>();
                        group2 = waitingList[parentNode];
                    }
                    else
                    // The other child is a node. We'll need to save the current child and store the values
                    // for later. This also means we need to start over with another terminal node.
                    {
                        waitingList.Add(parentNode, childLeaves);
                        break;
                    }

                    steps.Add(CreateStep(group1, group2));

                    foreach (TreeLeaf leaf in group2)
                    {
                        childLeaves.Add(leaf);
                    }

                    currentNode = parentNode;
                }
            }
        }
示例#26
0
        void ReRoot()
        // Root an unrooted tree or adjust the root location after a rooted tree has beem modified
        {
            // Alternative algorithm:
            //   0. If the tree is already rooted, remove the root node.
            //   1. Find the average branch lengths extending from every node.
            //   2. Compute the differences using the largest branch
            //         Treat the branches as vectors leaving the node separated evenly by 120 degrees, and treat
            //         the largest branch length as the top vertical vector. Subtract the vertical components of the
            //         other two vectors from the largest to find the difference score.
            //         Since cos(60 deg) = 0.5, just multiply the other vectors' magnitudes by 0.5.
            //   3. Select the node with the smallest difference.
            //   4. Select the branch from that node with the largest average branch length.
            //      a. If two or three branches are tied, select the branch among the ties with the longest
            //         length to the next node.
            //      b. If they are still tied, arbitrarily pick the first.
            //   5. Insert the root between the identified nodes, and set the branch lengths
            //      satisfying x = (internode branch length - |difference|) / 2, where the side with the smaller average
            //      branch length is increased by the difference.
            //   6. Walk the tree from the new root to assert parent relationships as needed.

            if (isRooted)
            {
                double     branchLength;
                TreeMember connection1, connection2;
                // The root should only connect to two members
                connection1  = root.Branches[0].Follow(root);
                connection2  = root.Branches[1].Follow(root);
                branchLength = root.Branches[0].BranchLength + root.Branches[1].BranchLength;

                root.Branches[0].Destroy();
                root.Branches[1].Destroy();

                TreeBranch.Build(connection1, connection2, branchLength);
            }

            TreeMember rootConnection1, rootConnection2;

            TreeNode   minNode              = new TreeNode();
            double     minDifference        = Double.MaxValue;
            TreeBranch minNodeMaxBranch     = new TreeBranch();
            TreeBranch minNodeTiedMaxBranch = new TreeBranch();

            // Find the node with the smallest vector difference
            foreach (TreeNode node in nodesList) // parallelize?
            {
                Dictionary <TreeBranch, double> averageBranchLengths = new Dictionary <TreeBranch, double>();
                TreeBranch maxBranch              = null;
                TreeBranch tiedMaxBranch          = null;
                double     maxAverageBranchLength = 0;
                foreach (TreeBranch branch in node.Branches)
                {
                    int    numLeaves;
                    double averageBranchLength = GetAverageBranchLength(node, branch, true, out numLeaves);
                    averageBranchLengths.Add(branch, averageBranchLength);
                    if (averageBranchLength > maxAverageBranchLength)
                    {
                        maxAverageBranchLength = averageBranchLength;
                        maxBranch     = branch;
                        tiedMaxBranch = null;
                    }
                    else if (averageBranchLength == maxAverageBranchLength)
                    {
                        tiedMaxBranch = branch;
                    }
                }

                double vectorDifference = maxAverageBranchLength;
                foreach (TreeBranch branch in node.Branches)
                {
                    if (branch != maxBranch)
                    {
                        vectorDifference -= 0.5 * averageBranchLengths[branch];
                    }
                }

                if (vectorDifference < minDifference)
                {
                    minDifference        = vectorDifference;
                    minNode              = node;
                    minNodeMaxBranch     = maxBranch;
                    minNodeTiedMaxBranch = tiedMaxBranch;
                }
            }
            rootConnection1 = minNode;

            // Found the minimum node. Now we must decide which branch the root should replace.
            // In the case of ties (minDifference = 0 or minNodeTiedMaxBranch is not null), the root
            // will be placed along the longest adjacent branch. If tie isn't broken, it will be the
            // first branch used.
            TreeBranch rootBranch;

            if (minDifference == 0)
            {
                double     maxBranchLength = 0;
                TreeBranch maxBranch       = new TreeBranch();
                foreach (TreeBranch branch in minNode.Branches)
                {
                    double branchLength = branch.BranchLength;

                    if (branchLength > maxBranchLength)
                    {
                        maxBranchLength = branchLength;
                        maxBranch       = branch;
                    }
                }
                rootBranch = maxBranch;
            }
            else if (minNodeTiedMaxBranch != null)
            {
                if (minNodeMaxBranch.BranchLength >= minNodeTiedMaxBranch.BranchLength)
                {
                    rootBranch = minNodeMaxBranch;
                }
                else
                {
                    rootBranch = minNodeTiedMaxBranch;
                }
            }
            else
            {
                rootBranch = minNodeMaxBranch;
            }
            rootConnection2 = rootBranch.Follow(rootConnection1);

            // Determine the lengths of the branches that will connect to the root.
            // This is determined by the equation:
            //     Li = (Aj - Ai + (Nj * L)) / (Nj + Ni)
            // Where "i" and "j" each represent one of the root connections, L indicates length,
            // A indicates average branch length, and N indicates number of leaves.
            int    numLeaves1, numLeaves2;
            double averageBranchLength1 = GetAverageBranchLength(rootConnection1, rootBranch, false, out numLeaves1);
            double averageBranchLength2 = GetAverageBranchLength(rootConnection2, rootBranch, false, out numLeaves2);
            double branchDifference = averageBranchLength1 - averageBranchLength2;
            double rootBranchLength1, rootBranchLength2;

            if (branchDifference != 0)
            {
                rootBranchLength1 = (averageBranchLength2 - averageBranchLength1 + (numLeaves2 * rootBranch.BranchLength)) / (numLeaves1 + numLeaves2);
            }
            else
            {
                rootBranchLength1 = (numLeaves2 * rootBranch.BranchLength) / (numLeaves1 + numLeaves2);
            }
            rootBranchLength2 = rootBranch.BranchLength - rootBranchLength1;

            rootBranch.Destroy(); // Remove the branch that will be replaced by the root node.

            isRooted = true;
            root     = new TreeNode(this);
            TreeBranch.Build(root, rootConnection1, rootBranchLength1);
            TreeBranch.Build(root, rootConnection2, rootBranchLength2);

            // Now we need to walk the tree from the root to ensure that all the downstream
            // nodes have the parent assigned correctly.
            AssertPaternity();
        }
示例#27
0
    private GameObject createResponseButton(TreeBranch branch)
    {
        GameObject responseButton = Instantiate(responseButtonPrefab);

        var responseButtonText = (Text)responseButton.GetComponent<Text>();
        responseButtonText.text = branch.description;

        var button = (Button)responseButton.GetComponent<Button>();
        button.onClick.AddListener(() => ClickResponseButton(branch.linkIndex));

        responseButton.transform.SetParent(responsePanel.transform,false);
        return responseButton;
    }
示例#28
0
    private static List<TreeBranch> getTreeBranchListFromDataStr(string linkDataStr)
    {
        List<TreeBranch> branchList = new List<TreeBranch>();

            var linkList = ParseHelper.getSplitList(linkDataStr, Environment.NewLine);
            foreach(var link in linkList)
            {
                TreeBranch tb = new TreeBranch();
                var linkDataList = ParseHelper.getSplitList(link, ":");
                tb.linkIndex = Int64.Parse(linkDataList[0]);
                tb.description = ParseHelper.removeBlock(linkDataList[1],"{","}");

                tb.conditionList = getTreeBranchConditionList(linkDataList[1]);

                branchList.Add(tb);
            }

            return branchList;
    }
示例#29
0
        public IList<ITreeNode> FetchNodes(long[] nids)
        {
            // The number of nodes,
            int node_count = nids.Length;
            // The array of read nodes,
            ITreeNode[] result_nodes = new ITreeNode[node_count];

            // Resolve special nodes first,
            {
                int i = 0;
                foreach (long nodeId in nids) {
                    if ((nodeId & 0x01000000000000000L) != 0)
                        result_nodes[i] = SparseLeafNode.Create(nodeId);

                    ++i;
                }
            }

            // Group all the nodes to the same block,
            List<long> uniqueBlocks = new List<long>();
            List<List<long>> uniqueBlockList = new List<List<long>>();
            {
                int i = 0;
                foreach (long node_ref in nids) {
                    // If it's not a special node,
                    if ((node_ref & 0x01000000000000000L) == 0) {
                        // Get the block id and add it to the list of unique blocks,
                        DataAddress address = new DataAddress(node_ref);
                        // Check if the node is in the local cache,
                        ITreeNode node = networkCache.GetNode(address);
                        if (node != null) {
                            result_nodes[i] = node;
                        } else {
                            // Not in the local cache so we need to bundle this up in a node
                            // request on the block servers,
                            // Group this node request by the block identifier
                            long blockId = address.BlockId;
                            int ind = uniqueBlocks.IndexOf(blockId);
                            if (ind == -1) {
                                ind = uniqueBlocks.Count;
                                uniqueBlocks.Add(blockId);
                                uniqueBlockList.Add(new List<long>());
                            }
                            List<long> blist = uniqueBlockList[ind];
                            blist.Add(node_ref);
                        }
                    }
                    ++i;
                }
            }

            // Exit early if no blocks,
            if (uniqueBlocks.Count == 0)
                return result_nodes;

            // Resolve server records for the given block identifiers,
            IDictionary<long, IList<BlockServerElement>> servers_map = GetServersForBlock(uniqueBlocks);

            // The result nodes list,
            List<ITreeNode> nodes = new List<ITreeNode>();

            // For each unique block list,
            foreach (List<long> blist in uniqueBlockList) {
                // Make a block server request for each node in the block,
                MessageStream block_server_msg = new MessageStream(MessageType.Request);
                long block_id = -1;
                foreach (long node_ref in blist) {
                    DataAddress address = new DataAddress(node_ref);
                    RequestMessage request = new RequestMessage("readFromBlock");
                    request.Arguments.Add(address);
                    block_server_msg.AddMessage(request);
                    block_id = address.BlockId;
                }

                if (block_id == -1)
                    throw new ApplicationException("block_id == -1");

                // Get the shuffled list of servers the block is stored on,
                IList<BlockServerElement> servers = servers_map[block_id];

                // Go through the servers one at a time to fetch the block,
                bool success = false;
                for (int z = 0; z < servers.Count && !success; ++z) {
                    BlockServerElement server = servers[z];

                    // If the server is up,
                    if (server.IsStatusUp) {
                        // Open a connection with the block server,
                        IMessageProcessor block_server_proc = connector.Connect(server.Address, ServiceType.Block);
                        MessageStream message_in = (MessageStream) block_server_proc.Process(block_server_msg);
                        // DEBUG: ++networkCommCount;
                        // DEBUG: ++networkFetchCommCount;

                        bool is_error = false;
                        bool severe_error = false;
                        // Turn each none-error message into a node
                        foreach (ResponseMessage m in message_in) {
                            if (m.HasError) {
                                // See if this error is a block read error. If it is, we don't
                                // tell the manager server to lock this server out completely.
                                bool is_block_read_error = m.Error.Source.Equals("Deveel.Data.Net.BlockReadException");
                                if (!is_block_read_error) {
                                    // If it's something other than a block read error, we mark
                                    // this error as severe,
                                    severe_error = true;
                                }
                                is_error = true;
                            } else if (!is_error) {
                                // The reply contains the block of data read.
                                NodeSet node_set = (NodeSet)m.Arguments[0].Value;

                                // Decode the node items into node objects,
                                IEnumerator<Node> item_iterator = node_set.GetEnumerator();

                                while (item_iterator.MoveNext()) {
                                    // Get the node item,
                                    Node node_item = item_iterator.Current;

                                    long node_ref = node_item.Id;

                                    DataAddress address = new DataAddress(node_ref);
                                    // Wrap around a buffered DataInputStream for reading values
                                    // from the store.
                                    BinaryReader input = new BinaryReader(node_item.Input, Encoding.Unicode);
                                    short node_type = input.ReadInt16();

                                    ITreeNode read_node;

                                    // Is the node type a leaf node?
                                    if (node_type == LeafType) {
                                        // Read the key
                                        int leaf_size = input.ReadInt32();

                                        byte[] buf = ReadNodeAsBuffer(node_item);
                                        if (buf == null) {
                                            buf = new byte[leaf_size + 6];
                                            input.Read(buf, 6, leaf_size);
                                            // Technically, we could comment these next two lines out.
                                            ByteBuffer.WriteInt2(node_type, buf, 0);
                                            ByteBuffer.WriteInt4(leaf_size, buf, 2);
                                        }

                                        // Create a leaf that's mapped to this data
                                        read_node = new ByteArrayTreeLeaf(node_ref, buf); ;

                                    }
                                        // Is the node type a branch node?
                                    else if (node_type == BranchType) {
                                        // Note that the entire branch is loaded into memory,
                                        int child_data_size = input.ReadInt32();
                                        long[] data_arr = new long[child_data_size];
                                        for (int n = 0; n < child_data_size; ++n) {
                                            data_arr[n] = input.ReadInt64();
                                        }
                                        // Create the branch node,
                                        read_node = new TreeBranch(node_ref, data_arr, child_data_size);
                                    } else {
                                        throw new InvalidDataState("Unknown node type: " + node_type, address);
                                    }

                                    // Is the node already in the list? If so we don't add it.
                                    if (!IsInNodeList(node_ref, nodes)) {
                                        // Put the read node in the cache and add it to the 'nodes'
                                        // list.
                                        networkCache.SetNode(address, read_node);
                                        nodes.Add(read_node);
                                    }
                                }
                            }
                        }

                        // If there was no error while reading the result, we assume the node
                        // requests were successfully read.
                        if (is_error == false) {
                            success = true;
                        } else {
                            if (severe_error) {
                                // If this is an error, we need to report the failure to the
                                // manager server,
                                ReportBlockServerFailure(server.Address);
                                // Remove the block id from the server list cache,
                                networkCache.RemoveServers(block_id);
                            } else {
                                // Otherwise, not a severe error (probably a corrupt block on a
                                // server), so shuffle the server list for this block_id so next
                                // time there's less chance of hitting this bad block.
                                IList<BlockServerElement> srvs = networkCache.GetServers(block_id);
                                List<BlockServerElement> server_list = new List<BlockServerElement>();
                                server_list.AddRange(srvs);
                                CollectionsUtil.Shuffle(server_list);
                                networkCache.SetServers(block_id, server_list, 15 * 60 * 1000);
                            }
                        }

                    }
                }

                // If the nodes were not successfully read, we generate an exception,
                if (!success) {
                    // Remove from the cache,
                    networkCache.RemoveServers(block_id);
                    throw new ApplicationException("Unable to fetch node from block server");
                }
            }

            int sz = nodes.Count;
            if (sz == 0)
                throw new ApplicationException("Empty nodes list");

            for (int i = 0; i < sz; ++i) {
                ITreeNode node = nodes[i];
                long node_ref = node.Id;
                for (int n = 0; n < nids.Length; ++n) {
                    if (nids[n] == node_ref)
                        result_nodes[n] = node;
                }
            }

            // Check the result_nodes list is completely populated,
            for (int n = 0; n < result_nodes.Length; ++n) {
                if (result_nodes[n] == null)
                    throw new ApplicationException("Assertion failed: result_nodes not completely populated.");
            }

            return result_nodes;
        }
 public void DecomposeTree(AbstractTree parentNode, AbstractTree node, TreeBranch branch, TreePath path)
 {
     if (!path.IsAdded)
     {
         Possibilities.Add(path);
         path.IsAdded = true;
     }
     // Recursive browse
     if (node is TreeConnector) {
             TreeConnector treeConnector = (TreeConnector)node;
             if (treeConnector.Connection == "&")
             {
                 DecomposeTree(treeConnector, treeConnector.LeftTree, TreeBranch.Left, path);
                 DecomposeTree(treeConnector, treeConnector.RightTree, TreeBranch.Right, path);
             }
             else if (treeConnector.Connection == "|")
             {
                 // In this case, parentNode is a TreeOperator
                 if (parentNode != null)
                 {
                     // Left distribution
                     TreePath clonedPathLeftDistribution = (TreePath)path.Clone();
                     TreeConnector parentTreeConnectorLeftDistribution = (TreeConnector)parentNode.Clone();
                     // Right distribution
                     TreePath clonedPathRightDistribution = (TreePath)path.Clone();
                     TreeConnector parentTreeConnectorRightDistribution = (TreeConnector)parentNode.Clone();
                     if (branch == TreeBranch.Left)
                     {
                         parentTreeConnectorLeftDistribution.LeftTree = treeConnector.LeftTree;
                         parentTreeConnectorRightDistribution.LeftTree = treeConnector.RightTree;
                     }
                     else if (branch == TreeBranch.Right)
                     {
                         parentTreeConnectorLeftDistribution.RightTree = treeConnector.LeftTree;
                         parentTreeConnectorRightDistribution.RightTree = treeConnector.RightTree;
                     }
                     // Remove obsolete path
                     Possibilities.Remove(path);
                     // Browse recursively distributed tree ; the path must be different (by ref) if the parent operator is 'OR'
                     DecomposeTree(
                         parentTreeConnectorLeftDistribution,
                         parentTreeConnectorLeftDistribution.LeftTree,
                         TreeBranch.Left,
                         parentTreeConnectorLeftDistribution.Connection == "|"
                             ? (TreePath)clonedPathLeftDistribution.Clone()
                             : clonedPathLeftDistribution
                     );
                     DecomposeTree(
                         parentTreeConnectorLeftDistribution,
                         parentTreeConnectorLeftDistribution.RightTree,
                         TreeBranch.Right,
                         clonedPathLeftDistribution
                     );
                     DecomposeTree(
                         parentTreeConnectorRightDistribution,
                         parentTreeConnectorRightDistribution.LeftTree,
                         TreeBranch.Left,
                         parentTreeConnectorLeftDistribution.Connection == "|"
                             ? (TreePath)clonedPathRightDistribution.Clone()
                             : clonedPathRightDistribution
                     );
                     DecomposeTree(
                         parentTreeConnectorRightDistribution,
                         parentTreeConnectorRightDistribution.RightTree,
                         TreeBranch.Right,
                         clonedPathRightDistribution
                     );
                 }
                 // The operator is the root of the tree; we simply divide the path
                 else
                 {
                     TreePath clonedLeftPath = (TreePath)path.Clone();
                     TreePath clonedRightPath = (TreePath)path.Clone();
                     // Remove obsolete path
                     Possibilities.Remove(path);
                     DecomposeTree(treeConnector, treeConnector.LeftTree, TreeBranch.Left, clonedLeftPath);
                     DecomposeTree(treeConnector, treeConnector.RightTree, TreeBranch.Right, clonedRightPath);
                 }
             }
             break;
     }
     // Leaf
     else if (node is TreeValue) {
         TreeValue treeValue = (TreeValue)node;
         path.Add(treeValue);
     }
 }
示例#31
0
        private NodeId[] InternalPersist(TreeWrite sequence, int tryCount)
        {
            // NOTE: nodes are written in order of branches and then leaf nodes. All
            //   branch nodes and leafs are grouped together.

            // The list of nodes to be allocated,
            IList<ITreeNode> allBranches = sequence.BranchNodes;
            IList<ITreeNode> allLeafs = sequence.LeafNodes;
            List<ITreeNode> nodes = new List<ITreeNode>(allBranches.Count + allLeafs.Count);
            nodes.AddRange(allBranches);
            nodes.AddRange(allLeafs);
            int sz = nodes.Count;
            // The list of allocated referenced for the nodes,
            DataAddress[] refs = new DataAddress[sz];
            NodeId[] outNodeIds = new NodeId[sz];

            MessageStream allocateMessageStream = new MessageStream();

            // Allocate the space first,
            for (int i = 0; i < sz; ++i) {
                ITreeNode node = nodes[i];
                // Is it a branch node?
                if (node is TreeBranch) {
                    // Branch nodes are 1K in size,
                    allocateMessageStream.AddMessage(new Message("allocateNode", 1024));
                }
                    // Otherwise, it must be a leaf node,
                else {
                    // Leaf nodes are 4k in size,
                    allocateMessageStream.AddMessage(new Message("allocateNode", 4096));
                }
            }

            // Process a command on the manager,
            IEnumerable<Message> resultStream = ProcessManager(allocateMessageStream);

            // The unique list of blocks,
            List<BlockId> uniqueBlocks = new List<BlockId>();

            // Parse the result stream one message at a time, the order will be the
            // order of the allocation messages,
            int n = 0;
            foreach (Message m in resultStream) {
                if (m.HasError)
                    throw new ApplicationException(m.ErrorMessage);

                DataAddress addr = (DataAddress) m.Arguments[0].Value;
                refs[n] = addr;
                // Make a list of unique block identifiers,
                if (!uniqueBlocks.Contains(addr.BlockId)) {
                    uniqueBlocks.Add(addr.BlockId);
                }
                ++n;
            }

            // Get the block to server map for each of the blocks,

            IDictionary<BlockId, IList<BlockServerElement>> blockToServerMap =
                GetServerListForBlocks(uniqueBlocks);

            // Make message streams for each unique block
            int ubidCount = uniqueBlocks.Count;
            MessageStream[] ubidStream = new MessageStream[ubidCount];
            for (int i = 0; i < ubidStream.Length; ++i) {
                ubidStream[i] = new MessageStream();
            }

            // Scan all the blocks and create the message streams,
            for (int i = 0; i < sz; ++i) {

                byte[] nodeBuf;

                ITreeNode node = nodes[i];
                // Is it a branch node?
                if (node is TreeBranch) {
                    TreeBranch branch = (TreeBranch) node;
                    // Make a copy of the branch (NOTE; we clone() the array here).
                    long[] curNodeData = (long[]) branch.NodeData.Clone();
                    int curNdsz = branch.NodeDataSize;
                    branch = new TreeBranch(refs[i].Value, curNodeData, curNdsz);

                    // The number of children
                    int chsz = branch.ChildCount;
                    // For each child, if it's a heap node, look up the child id and
                    // reference map in the sequence and set the reference accordingly,
                    for (int o = 0; o < chsz; ++o) {
                        NodeId childId = branch.GetChild(o);
                        if (childId.IsInMemory) {
                            // The ref is currently on the heap, so adjust accordingly
                            int refId = sequence.LookupRef(i, o);
                            branch.SetChildOverride(refs[refId].Value, o);
                        }
                    }

                    // Turn the branch into a 'node_buf' byte[] array object for
                    // serialization.
                    long[] nodeData = branch.NodeData;
                    int ndsz = branch.NodeDataSize;
                    MemoryStream bout = new MemoryStream(1024);
                    BinaryWriter dout = new BinaryWriter(bout);
                    dout.Write(StoreBranchType);
                    dout.Write((short) 0); // Reserved for future
                    dout.Write(0); // The crc32 checksum will be written here,
                    dout.Write(ndsz);
                    for (int o = 0; o < ndsz; ++o) {
                        dout.Write(nodeData[o]);
                    }
                    dout.Flush();

                    // Turn it into a byte array,
                    nodeBuf = bout.ToArray();

                    // Write the crc32 of the data,
                    Crc32 checksum = new Crc32();
                    checksum.ComputeHash(nodeBuf, 8, nodeBuf.Length - 8);
                    ByteBuffer.WriteInt4((int) checksum.CrcValue, nodeBuf, 4);

                    // Put this branch into the local cache,
                    networkCache.SetNode(refs[i], branch);

                }
                    // If it's a leaf node,
                else {
                    TreeLeaf leaf = (TreeLeaf) node;
                    int lfsz = leaf.Length;

                    nodeBuf = new byte[lfsz + 12];

                    // Format the data,
                    ByteBuffer.WriteInt2(StoreLeafType, nodeBuf, 0);
                    ByteBuffer.WriteInt2(0, nodeBuf, 2); // Reserved for future
                    ByteBuffer.WriteInt4(lfsz, nodeBuf, 8);
                    leaf.Read(0, nodeBuf, 12, lfsz);

                    // Calculate and set the checksum,
                    Crc32 checksum = new Crc32();
                    checksum.ComputeHash(nodeBuf, 8, nodeBuf.Length - 8);
                    ByteBuffer.WriteInt4((int) checksum.CrcValue, nodeBuf, 4);

                    // Put this leaf into the local cache,
                    leaf = new MemoryTreeLeaf(refs[i].Value, nodeBuf);
                    networkCache.SetNode(refs[i], leaf);

                }

                // The DataAddress this node is being written to,
                DataAddress address = refs[i];
                // Get the block id,
                BlockId blockId = address.BlockId;
                int bid = uniqueBlocks.IndexOf(blockId);
                ubidStream[bid].AddMessage(new Message("writeToBlock", address, nodeBuf, 0, nodeBuf.Length));

                // Update 'out_refs' array,
                outNodeIds[i] = refs[i].Value;
            }

            // A log of successfully processed operations,
            List<object> successProcess = new List<object>(64);

            // Now process the streams on the servers,
            for (int i = 0; i < ubidStream.Length; ++i) {
                // The output message,
                MessageStream outputStream = ubidStream[i];
                // Get the servers this message needs to be sent to,
                BlockId blockId = uniqueBlocks[i];
                IList<BlockServerElement> blockServers = blockToServerMap[blockId];
                // Format a message for writing this node out,
                int bssz = blockServers.Count;
                IMessageProcessor[] blockServerProcs = new IMessageProcessor[bssz];
                // Make the block server connections,
                for (int o = 0; o < bssz; ++o) {
                    IServiceAddress address = blockServers[o].Address;
                    blockServerProcs[o] = connector.Connect(address, ServiceType.Block);
                    IEnumerable<Message> inputStream = blockServerProcs[o].Process(outputStream);
                    ++NetworkCommCount;

                    foreach (Message m in inputStream) {
                        if (m.HasError) {
                            // If this is an error, we need to report the failure to the
                            // manager server,
                            ReportBlockServerFailure(address);
                            // Remove the block id from the server list cache,
                            networkCache.RemoveServersWithBlock(blockId);

                            // Rollback any server writes already successfully made,
                            for (int p = 0; p < successProcess.Count; p += 2) {
                                IServiceAddress blocksAddr = (IServiceAddress) successProcess[p];
                                MessageStream toRollback = (MessageStream) successProcess[p + 1];

                                List<DataAddress> rollbackNodes = new List<DataAddress>(128);
                                foreach (Message rm in toRollback) {
                                    DataAddress raddr = (DataAddress) rm.Arguments[0].Value;
                                    rollbackNodes.Add(raddr);
                                }
                                // Create the rollback message,
                                MessageStream rollbackMsg = new MessageStream();
                                rollbackMsg.AddMessage(new Message("rollbackNodes", new object[] {rollbackNodes.ToArray()}));

                                // Send it to the block server,
                                IEnumerable<Message> responseStream = connector.Connect(blocksAddr, ServiceType.Block).Process(rollbackMsg);
                                ++NetworkCommCount;
                                foreach (Message rbm in responseStream) {
                                    // If rollback generated an error we throw the error now
                                    // because this likely is a serious network error.
                                    if (rbm.HasError) {
                                        throw new NetworkWriteException("Write failed (rollback failed): " + rbm.ErrorMessage);
                                    }
                                }

                            }

                            // Retry,
                            if (tryCount > 0)
                                return InternalPersist(sequence, tryCount - 1);

                            // Otherwise we fail the write
                            throw new NetworkWriteException(m.ErrorMessage);
                        }
                    }

                    // If we succeeded without an error, add to the log
                    successProcess.Add(address);
                    successProcess.Add(outputStream);

                }
            }

            // Return the references,
            return outNodeIds;
        }
示例#32
0
        public IList<ITreeNode> FetchNodes(NodeId[] nids)
        {
            // The number of nodes,
            int nodeCount = nids.Length;
            // The array of read nodes,
            ITreeNode[] resultNodes = new ITreeNode[nodeCount];

            // Resolve special nodes first,
            {
                int i = 0;
                foreach (NodeId nodeId in nids) {
                    if (nodeId.IsSpecial) {
                        resultNodes[i] = nodeId.CreateSpecialTreeNode();
                    }
                    ++i;
                }
            }

            // Group all the nodes to the same block,
            List<BlockId> uniqueBlocks = new List<BlockId>();
            List<List<NodeId>> uniqueBlockList = new List<List<NodeId>>();
            {
                int i = 0;
                foreach (NodeId nodeId in nids) {
                    // If it's not a special node,
                    if (!nodeId.IsSpecial) {
                        // Get the block id and add it to the list of unique blocks,
                        DataAddress address = new DataAddress(nodeId);
                        // Check if the node is in the local cache,
                        ITreeNode node = networkCache.GetNode(address);
                        if (node != null) {
                            resultNodes[i] = node;
                        } else {
                            // Not in the local cache so we need to bundle this up in a node
                            // request on the block servers,
                            // Group this node request by the block identifier
                            BlockId blockId = address.BlockId;
                            int ind = uniqueBlocks.IndexOf(blockId);
                            if (ind == -1) {
                                ind = uniqueBlocks.Count;
                                uniqueBlocks.Add(blockId);
                                uniqueBlockList.Add(new List<NodeId>());
                            }
                            List<NodeId> blist = uniqueBlockList[ind];
                            blist.Add(nodeId);
                        }
                    }
                    ++i;
                }
            }

            // Exit early if no blocks,
            if (uniqueBlocks.Count == 0) {
                return resultNodes;
            }

            // Resolve server records for the given block identifiers,
            IDictionary<BlockId, IList<BlockServerElement>> serversMap = GetServerListForBlocks(uniqueBlocks);

            // The result nodes list,
            List<ITreeNode> nodes = new List<ITreeNode>();

            // Checksumming objects
            byte[] checksumBuf = null;
            Crc32 crc32 = null;

            // For each unique block list,
            foreach (List<NodeId> blist in uniqueBlockList) {
                // Make a block server request for each node in the block,
                MessageStream blockServerMsg = new MessageStream();
                BlockId blockId = null;
                foreach (NodeId nodeId in blist) {
                    DataAddress address = new DataAddress(nodeId);
                    blockServerMsg.AddMessage(new Message("readFromBlock", address));
                    blockId = address.BlockId;
                }

                if (blockId == null) {
                    throw new ApplicationException("block_id == null");
                }

                // Get the shuffled list of servers the block is stored on,
                IList<BlockServerElement> servers = serversMap[blockId];

                // Go through the servers one at a time to fetch the block,
                bool success = false;
                for (int z = 0; z < servers.Count && !success; ++z) {
                    BlockServerElement server = servers[z];
                    // If the server is up,
                    if (server.IsStatusUp) {
                        // Open a connection with the block server,
                        IMessageProcessor blockServerProc = connector.Connect(server.Address, ServiceType.Block);
                        IEnumerable<Message> messageIn = blockServerProc.Process(blockServerMsg);
                        ++NetworkCommCount;
                        ++NetworkFetchCommCount;

                        bool isError = false;
                        bool severeError = false;
                        bool crcError = false;
                        bool connectionError = false;

                        // Turn each none-error message into a node
                        foreach (Message m in messageIn) {
                            if (m.HasError) {
                                // See if this error is a block read error. If it is, we don't
                                // tell the manager server to lock this server out completely.
                                bool isBlockReadError = m.Error.Source.Equals("Deveel.Data.Net.BlockReadException");
                                // If it's a connection fault,
                                if (IsConnectionFailMessage(m)) {
                                    connectionError = true;
                                } else if (!isBlockReadError) {
                                    // If it's something other than a block read error or
                                    // connection failure, we set the severe flag,
                                    severeError = true;
                                }
                                isError = true;
                            } else if (isError == false) {
                                // The reply contains the block of data read.
                                NodeSet nodeSet = (NodeSet) m.Arguments[0].Value;

                                DataAddress address = null;

                                // Catch any IOExceptions (corrupt zips, etc)
                                try {
                                    // Decode the node items into Java node objects,
                                    foreach (Node nodeItem in nodeSet) {
                                        NodeId nodeId = nodeItem.Id;

                                        address = new DataAddress(nodeId);
                                        // Wrap around a buffered DataInputStream for reading values
                                        // from the store.
                                        BinaryReader input = new BinaryReader(nodeItem.Input);
                                        short nodeType = input.ReadInt16();

                                        ITreeNode readNode = null;

                                        if (crc32 == null)
                                            crc32 = new Crc32();
                                        crc32.Initialize();

                                        // Is the node type a leaf node?
                                        if (nodeType == StoreLeafType) {
                                            // Read the checksum,
                                            input.ReadInt16(); // For future use...
                                            int checksum = input.ReadInt32();
                                            // Read the size
                                            int leafSize = input.ReadInt32();

                                            byte[] buf = StreamUtil.AsBuffer(nodeItem.Input);
                                            if (buf == null) {
                                                buf = new byte[leafSize + 12];
                                                ByteBuffer.WriteInt4(leafSize, buf, 8);
                                                input.Read(buf, 12, leafSize);
                                            }

                                            // Check the checksum...
                                            crc32.ComputeHash(buf, 8, leafSize + 4);
                                            int calcChecksum = (int) crc32.CrcValue;
                                            if (checksum != calcChecksum) {
                                                // If there's a CRC failure, we reject his node,
                                                log.Warning(String.Format("CRC failure on node {0} @ {1}", nodeId, server.Address));
                                                isError = true;
                                                crcError = true;
                                                // This causes the read to retry on a different server
                                                // with this block id
                                            } else {
                                                // Create a leaf that's mapped to this data
                                                ITreeNode leaf = new MemoryTreeLeaf(nodeId, buf);
                                                readNode = leaf;
                                            }

                                        }
                                            // Is the node type a branch node?
                                        else if (nodeType == StoreBranchType) {
                                            // Read the checksum,
                                            input.ReadInt16(); // For future use...
                                            int checksum = input.ReadInt32();

                                            // Check the checksum objects,
                                            if (checksumBuf == null)
                                                checksumBuf = new byte[8];

                                            // Note that the entire branch is loaded into memory,
                                            int childDataSize = input.ReadInt32();
                                            ByteBuffer.WriteInt4(childDataSize, checksumBuf, 0);
                                            crc32.ComputeHash(checksumBuf, 0, 4);
                                            long[] dataArr = new long[childDataSize];
                                            for (int n = 0; n < childDataSize; ++n) {
                                                long item = input.ReadInt64();
                                                ByteBuffer.WriteInt8(item, checksumBuf, 0);
                                                crc32.ComputeHash(checksumBuf, 0, 8);
                                                dataArr[n] = item;
                                            }

                                            // The calculated checksum value,
                                            int calcChecksum = (int) crc32.CrcValue;
                                            if (checksum != calcChecksum) {
                                                // If there's a CRC failure, we reject his node,
                                                log.Warning(String.Format("CRC failure on node {0} @ {1}", nodeId, server.Address));
                                                isError = true;
                                                crcError = true;
                                                // This causes the read to retry on a different server
                                                // with this block id
                                            } else {
                                                // Create the branch node,
                                                TreeBranch branch =
                                                    new TreeBranch(nodeId, dataArr, childDataSize);
                                                readNode = branch;
                                            }

                                        } else {
                                            log.Error(String.Format("Unknown node {0} type: {1}", address, nodeType));
                                            isError = true;
                                        }

                                        // Is the node already in the list? If so we don't add it.
                                        if (readNode != null && !IsInNodeList(nodeId, nodes)) {
                                            // Put the read node in the cache and add it to the 'nodes'
                                            // list.
                                            networkCache.SetNode(address, readNode);
                                            nodes.Add(readNode);
                                        }

                                    } // while (item_iterator.hasNext())

                                } catch (IOException e) {
                                    // This catches compression errors, as well as any other misc
                                    // IO errors.
                                    if (address != null) {
                                        log.Error(String.Format("IO Error reading node {0}", address));
                                    }
                                    log.Error(e.Message, e);
                                    isError = true;
                                }

                            }

                        } // for (Message m : message_in)

                        // If there was no error while reading the result, we assume the node
                        // requests were successfully read.
                        if (isError == false) {
                            success = true;
                        } else {
                            // If this is a connection failure, we report the block failure.
                            if (connectionError) {
                                // If this is an error, we need to report the failure to the
                                // manager server,
                                ReportBlockServerFailure(server.Address);
                                // Remove the block id from the server list cache,
                                networkCache.RemoveServersWithBlock(blockId);
                            } else {
                                String failType = "General";
                                if (crcError) {
                                    failType = "CRC Failure";
                                } else if (severeError) {
                                    failType = "Exception during process";
                                }

                                // Report to the first manager the block failure, so it may
                                // investigate and hopefully correct.
                                ReportBlockIdCorruption(server.Address, blockId, failType);

                                // Otherwise, not a severe error (probably a corrupt block on a
                                // server), so shuffle the server list for this block_id so next
                                // time there's less chance of hitting this bad block.
                                IEnumerable<BlockServerElement> srvs = networkCache.GetServersWithBlock(blockId);
                                if (srvs != null) {
                                    List<BlockServerElement> serverList = new List<BlockServerElement>();
                                    serverList.AddRange(srvs);
                                    CollectionsUtil.Shuffle(serverList);
                                    networkCache.SetServersForBlock(blockId, serverList, 15*60*1000);
                                }
                            }
                            // We will now go retry the query on the next block server,
                        }

                    }
                }

                // If the nodes were not successfully read, we generate an exception,
                if (!success) {
                    // Remove from the cache,
                    networkCache.RemoveServersWithBlock(blockId);
                    throw new ApplicationException(
                        "Unable to fetch node from a block server" +
                        " (block = " + blockId + ")");
                }
            }

            int sz = nodes.Count;
            if (sz == 0) {
                throw new ApplicationException("Empty nodes list");
            }

            for (int i = 0; i < sz; ++i) {
                ITreeNode node = nodes[i];
                NodeId nodeId = node.Id;
                for (int n = 0; n < nids.Length; ++n) {
                    if (nids[n].Equals(nodeId)) {
                        resultNodes[n] = node;
                    }
                }
            }

            // Check the result_nodes list is completely populated,
            for (int n = 0; n < resultNodes.Length; ++n) {
                if (resultNodes[n] == null) {
                    throw new ApplicationException("Assertion failed: result_nodes not completely populated.");
                }
            }

            return resultNodes;
        }
示例#33
0
        public DataAddress CreateDatabase()
        {
            // The child reference is a sparse node element
            NodeId childId = NodeId.CreateSpecialSparseNode((byte) 1, 4);

            // Create a branch,
            TreeBranch rootBranch = new TreeBranch(NodeId.CreateInMemoryNode(0L), MaxBranchSize);
            rootBranch.Set(childId, 4, Key.Tail, childId, 4);

            TreeWrite seq = new TreeWrite();
            seq.NodeWrite(rootBranch);
            IList<NodeId> refs = Persist(seq);

            // The written root node reference,
            NodeId rootId = refs[0];

            // Return the root,
            return new DataAddress(rootId);
        }
示例#34
0
        private static RenderBranch Create(double x, double y, int angle, TreeBranch branch, VariableContext variables, Graphics g, Font font)
        {
            double x2 = x - branch.Position * Math.Cos(angle * Math.PI / 180);
            double y2 = y + branch.Position * Math.Sin(angle * Math.PI / 180);

            double x1 = x2 + branch.Length * Math.Cos((angle + branch.Angle) * Math.PI / 180);
            double y1 = y2 - branch.Length * Math.Sin((angle + branch.Angle) * Math.PI / 180);

            double a = Funcs.Atan(x1, y1, x2, y2);

            x2 = x1 + (branch.Length - 2) * Math.Cos(a);
            y2 = y1 - (branch.Length - 2) * Math.Sin(a);

            RenderBranch[] branches = branch.Branches.Select(i => Create(x2, y2, angle + branch.Angle - 180, i, variables, g, font)).ToArray();


            string description;

            double imageX          = 0;
            double imageY          = 0;
            Bitmap expressionImage = null;

            if (branch is ExpressionBranch)
            {
                string[] preVariables = variables.GetAllVariables();

                Expression[] expressions = new MathyLanguageService().Compile((branch as ExpressionBranch).Expression, variables);
                foreach (Expression expression in expressions)
                {
                    new MathyLanguageService().CreateEvaluator().Evaluate(expression, variables);
                }


                StringBuilder b = new StringBuilder();

                foreach (string variableName in variables.GetAllVariables().Where(i => !preVariables.Contains(i)))
                {
                    b.AppendFormat("{0}={1}", variableName, variables.GetValue(variableName));
                }


                description = branch.Description + "\r\n" + b.ToString();


                double xt = x2 + (branch as ExpressionBranch).ImageX * Math.Cos(a + Math.PI);
                double yt = y2 - (branch as ExpressionBranch).ImageX * Math.Sin(a + Math.PI);

                double d = (branch as ExpressionBranch).ImageY;

                imageX = xt + d * Math.Cos(a + Math.PI / 2);
                imageY = yt - d * Math.Sin(a + Math.PI / 2);

                expressionImage = new NodeVisualizer(expressions.Select(i => new NodeConverter().Convert(i)).ToArray()).VisulizeAsBitmap();
            }
            else
            {
                string variableName = (branch as VariableBranch).VariableName;
                object value        = variables.GetValue(variableName);
                description = string.Format("{0}\r\n{1}={2}", branch.Description, variableName, value);
            }


            double dx;
            double dy;

            EvaluateDescriptionPosition(branch, description, x1, y1, x2, y2, g, font, out dx, out dy);


            return(new RenderBranch()
            {
                X1 = x1,
                Y1 = y1,
                X2 = x2,
                Y2 = y2,
                IsVariable = branch is VariableBranch,
                ImageX = imageX,
                ImageY = imageY,
                Image = expressionImage,
                Branches = branches,
                DescriptionX = dx,
                DescriptionY = dy,
                Description = description
            });
        }
示例#35
0
 public void RemoveParent()
 {
     parentBranch = null;
 }
示例#36
0
        private List<long> DoPersist(TreeWrite sequence, int tryCount)
        {
            // NOTE: nodes are written in order of branches and then leaf nodes. All
            //   branch nodes and leafs are grouped together.

            // The list of nodes to be allocated,
            IList<ITreeNode> allBranches = sequence.BranchNodes;
            IList<ITreeNode> allLeafs = sequence.LeafNodes;
            List<ITreeNode> nodes = new List<ITreeNode>(allBranches.Count + allLeafs.Count);
            nodes.AddRange(allBranches);
            nodes.AddRange(allLeafs);
            int sz = nodes.Count;
            // The list of allocated referenced for the nodes,
            DataAddress[] refs = new DataAddress[sz];
            long[] outRefs = new long[sz];

            MessageStream allocateMessage = new MessageStream(MessageType.Request);

            // Make a connection with the manager server,
            IMessageProcessor manager = connector.Connect(managerAddress, ServiceType.Manager);

            // Allocate the space first,
            for (int i = 0; i < sz; ++i) {
                ITreeNode node = nodes[i];
                RequestMessage request = new RequestMessage("allocateNode");
                // Is it a branch node?
                if (node is TreeBranch) {
                    // Branch nodes are 1K in size,
                    request.Arguments.Add(1024);
                } else {
                    // Leaf nodes are 4k in size,
                    request.Arguments.Add(4096);
                }

                allocateMessage.AddMessage(request);
            }

            // The result of the set of allocations,
            MessageStream resultStream = (MessageStream) manager.Process(allocateMessage);
            //DEBUG: ++network_comm_count;

            // The unique list of blocks,
            List<long> uniqueBlocks = new List<long>();

            // Parse the result stream one message at a time, the order will be the
            // order of the allocation messages,
            int n = 0;
            foreach (ResponseMessage m in resultStream) {
                if (m.HasError)
                    throw m.Error.AsException();

                DataAddress addr = (DataAddress) m.Arguments[0].Value;
                refs[n] = addr;
                // Make a list of unique block identifiers,
                if (!uniqueBlocks.Contains(addr.BlockId)) {
                    uniqueBlocks.Add(addr.BlockId);
                }
                ++n;
            }

            // Get the block to server map for each of the blocks,

            IDictionary<long, IList<BlockServerElement>> blockToServerMap = GetServersForBlock(uniqueBlocks);

            // Make message streams for each unique block
            int ubid_count = uniqueBlocks.Count;
            MessageStream[] ubidStream = new MessageStream[ubid_count];
            for (int i = 0; i < ubidStream.Length; ++i) {
                ubidStream[i] = new MessageStream(MessageType.Request);
            }

            // Scan all the blocks and create the message streams,
            for (int i = 0; i < sz; ++i) {
                byte[] nodeBuf;

                ITreeNode node = nodes[i];
                // Is it a branch node?
                if (node is TreeBranch) {
                    TreeBranch branch = (TreeBranch)node;
                    // Make a copy of the branch (NOTE; we Clone() the array here).
                    long[] curNodeData = (long[])branch.ChildPointers.Clone();
                    int curNdsz = branch.DataSize;
                    branch = new TreeBranch(refs[i].Value, curNodeData, curNdsz);

                    // The number of children
                    int chsz = branch.ChildCount;
                    // For each child, if it's a heap node, look up the child id and
                    // reference map in the sequence and set the reference accordingly,
                    for (int o = 0; o < chsz; ++o) {
                        long childRef = branch.GetChild(o);
                        if (childRef < 0) {
                            // The ref is currently on the heap, so adjust accordingly
                            int ref_id = sequence.LookupRef(i, o);
                            branch.SetChildOverride(o, refs[ref_id].Value);
                        }
                    }

                    // Turn the branch into a 'node_buf' byte[] array object for
                    // serialization.
                    long[] nodeData = branch.ChildPointers;
                    int ndsz = branch.DataSize;
                    MemoryStream bout = new MemoryStream(1024);
                    BinaryWriter dout = new BinaryWriter(bout, Encoding.Unicode);
                    dout.Write(BranchType);
                    dout.Write(ndsz);
                    for (int o = 0; o < ndsz; ++o) {
                        dout.Write(nodeData[o]);
                    }
                    dout.Flush();

                    // Turn it into a byte array,
                    nodeBuf = bout.ToArray();

                    // Put this branch into the local cache,
                    networkCache.SetNode(refs[i], branch);

                } else {
                    // If it's a leaf node,

                    TreeLeaf leaf = (TreeLeaf)node;
                    int lfsz = leaf.Length;

                    nodeBuf = new byte[lfsz + 6];
                    // Technically, we could comment these next two lines out.
                    ByteBuffer.WriteInt2(LeafType, nodeBuf, 0);
                    ByteBuffer.WriteInt4(lfsz, nodeBuf, 2);
                    leaf.Read(0, nodeBuf, 6, lfsz);

                    // Put this leaf into the local cache,
                    leaf = new ByteArrayTreeLeaf(refs[i].Value, nodeBuf);
                    networkCache.SetNode(refs[i], leaf);

                }

                // The DataAddress this node is being written to,
                DataAddress address = refs[i];
                // Get the block id,
                long blockId = address.BlockId;
                int bid = uniqueBlocks.IndexOf(blockId);
                RequestMessage request = new RequestMessage("writeToBlock");
                request.Arguments.Add(address);
                request.Arguments.Add(nodeBuf);
                request.Arguments.Add(0);
                request.Arguments.Add(nodeBuf.Length);
                ubidStream[bid].AddMessage(request);

                // Update 'outRefs' array,
                outRefs[i] = refs[i].Value;
            }

            // A log of successfully processed operations,
            List<object> successProcess = new List<object>(64);

            // Now process the streams on the servers,
            for (int i = 0; i < ubidStream.Length; ++i) {
                // The output message,
                MessageStream requestMessageStream = ubidStream[i];

                // Get the servers this message needs to be sent to,
                long block_id = uniqueBlocks[i];
                IList<BlockServerElement> blockServers = blockToServerMap[block_id];

                // Format a message for writing this node out,
                int bssz = blockServers.Count;
                IMessageProcessor[] blockServerProcs = new IMessageProcessor[bssz];

                // Make the block server connections,
                for (int o = 0; o < bssz; ++o) {
                    IServiceAddress address = blockServers[o].Address;
                    blockServerProcs[o] = connector.Connect(address, ServiceType.Block);
                    MessageStream responseMessageStream = (MessageStream) blockServerProcs[o].Process(requestMessageStream);
                    //DEBUG: ++network_comm_count;

                    if (responseMessageStream.HasError) {
                        // If this is an error, we need to report the failure to the
                        // manager server,
                        ReportBlockServerFailure(address);
                        // Remove the block id from the server list cache,
                        networkCache.RemoveServers(block_id);

                        // Rollback any server writes already successfully made,
                        for (int p = 0; p < successProcess.Count; p += 2) {
                            IServiceAddress blockAddress = (IServiceAddress) successProcess[p];
                            MessageStream toRollback = (MessageStream) successProcess[p + 1];

                            List<DataAddress> rollbackNodes = new List<DataAddress>(128);
                            foreach(Message rm in toRollback) {
                                DataAddress raddr = (DataAddress) rm.Arguments[0].Value;
                                rollbackNodes.Add(raddr);
                            }

                            // Create the rollback message,
                            RequestMessage rollbackRequest = new RequestMessage("rollbackNodes");
                            rollbackRequest.Arguments.Add(rollbackNodes.ToArray());

                            // Send it to the block server,
                            Message responseMessage = connector.Connect(blockAddress, ServiceType.Block).Process(rollbackRequest);
                            //DEBUG: ++network_comm_count;

                            // If rollback generated an error we throw the error now
                            // because this likely is a serious network error.
                            if (responseMessage.HasError)
                                throw new NetworkException("Rollback wrote failed: " + responseMessage.ErrorMessage);
                        }

                        // Retry,
                        if (tryCount > 0)
                            return DoPersist(sequence, tryCount - 1);

                        // Otherwise we fail the write
                        throw new NetworkException(responseMessageStream.ErrorMessage);
                    }

                    // If we succeeded without an error, add to the log
                    successProcess.Add(address);
                    successProcess.Add(requestMessageStream);

                }
            }

            // Return the references,
            return new List<long>(outRefs);
        }
示例#37
0
        static double GetSumBranchLength(TreeMember member, TreeBranch baseBranch, bool includeBranch, out int numLeaves)
        // This is a recursive function
        //
        {
            // Algorithm:
            //   1. Store the branch length to the current member in "distance" (except the first if includeBranch is true).
            //   2. If the current member is a node, add the other branches to the stack and continue the loop.
            //      If the current member is a leaf, add 1 to the number of leaves, add the stemLength to the sumBranchLength, and subtract the length to this branch from the distance.
            //   3.

            double sumBranchLength = 0;

            numLeaves = 0;
            Stack <Tuple <TreeMember, TreeBranch> > arguments = new Stack <Tuple <TreeMember, TreeBranch> >();
            double distance = 0;

            arguments.Push(Tuple.Create(baseBranch.Follow(member), baseBranch));
            TreeBranch prevBranch = new TreeBranch();
            bool       stepBack   = false;

            while (arguments.Count > 0)
            {
                Tuple <TreeMember, TreeBranch> nextArgument = arguments.Peek();
                TreeMember nextMember     = nextArgument.Item1;
                TreeBranch nextBaseBranch = nextArgument.Item2;

                if (nextMember.GetType() == typeof(TreeNode))
                {
                    TreeNode node = (TreeNode)nextMember;
                    if (node.Branches.Contains(prevBranch))
                    // If the previously-used branch is a member of this node's branches, that means we've already used the
                    // branches of this node, and can discard it.
                    {
                        stepBack = true;
                    }
                    else
                    {
                        distance += nextBaseBranch.BranchLength;
                        foreach (TreeBranch branch in node.Branches)
                        {
                            if (branch != nextBaseBranch)
                            {
                                arguments.Push(Tuple.Create(branch.Follow(node), branch));
                            }
                        }
                    }
                }
                else
                // This is a leaf, so add the distance to the sum, increment the leaf count, and step backward
                {
                    distance        += nextBaseBranch.BranchLength;
                    sumBranchLength += distance;
                    numLeaves++;
                    stepBack = true;
                }

                if (stepBack)
                {
                    prevBranch = nextBaseBranch;
                    distance  -= nextBaseBranch.BranchLength;
                    arguments.Pop();
                    stepBack = false;
                }
            }

            if (!includeBranch)
            {   // If we didn't want to include the base branch length, correct for that here.
                sumBranchLength -= numLeaves * baseBranch.BranchLength;
            }

            return(sumBranchLength);
        }
示例#38
0
        public bool MoveNext()
        {
            // если текущий индекс не находиться в конце списка
            if (index < iterations.Count)
            {
                // текущее изображения берется из списка уже
                // пройденных на итерациях изображений
                Current = iterations[index++];
                return true;
            }
            // иначе определение следующего изображения
            else
            {
                // определение действий на текущей итерациии
                switch (next)
                {
                    // остановка метода ветвей и границ
                    case IterationState.Stop:
                        {
                            return false;
                        }
                    // начало метода ветвей и границ
                    case IterationState.Start:
                        {
                            // иницилизация данных
                            dsu = new Dsu(Graph.CountVertex());
                            min = new Branch(float.PositiveInfinity, null);
                            matrix = new ReductionMatrix(Graph.Adjacency);
                            parent = new Branch(matrix.Reduce(), null);
                            tree = new TreeBranch(Graph, parent);

                            // создание и добавление нового изображения ветвления
                            Current = Painter.Drawing(tree);
                            iterations.Add(Current);
                            // перемещение текущего индекса на конец списка
                            index = iterations.Count;

                            // переход в следующее состояние - левое ветвление метода
                            next = IterationState.LeftBranching;
                            return true;
                        }
                    // левое ветвление метода ветвей и границ
                    case IterationState.LeftBranching:
                        {
                            // определение ребер с нулевой стоимостью
                            var zeroEdges = new List<Digraph.Edge>();
                            for (int i = 0; i < matrix.Size; i++)
                                for (int j = 0; j < matrix.Size; j++)
                                    if (matrix[i, j] == 0)
                                        zeroEdges.Add(new Digraph.Edge(i, j, matrix.MinInRow(i, j) + matrix.MinInColumn(j, i)));

                            // если нет ребер ветвления - нет маршрута коммивояжера
                            if (zeroEdges.Count == 0)
                            {
                                TsPath = new Digraph.Path(Graph);

                                // остановка метода ветвей и границ
                                next = IterationState.Stop;
                                return false;
                            }

                            // определение ребра ветвления - ребра с максимальным штрафом
                            edge = zeroEdges.OrderByDescending(e => e.Cost).ToList().First();

                            // создание левого потомка для данного родителя
                            left = new Branch(parent.LowerBound + edge.Cost,
                                new Digraph.Edge(-edge.Begin, -edge.End, float.PositiveInfinity));
                            // добавление в дерево ветвлений
                            tree.Add(parent, Branch.Direction.Left, left);

                            // создание и добавление нового изображения ветвления
                            Current = Painter.Drawing(tree);
                            iterations.Add(Current);
                            // перемещение текущего индекса на конец списка
                            index = iterations.Count;

                            // переход в следующее состояние - правое ветвление метода
                            next = IterationState.RightBranching;
                            return true;
                        }
                    // правое ветвление метода
                    case IterationState.RightBranching:
                        {
                            // исключение подмаршрутов для данного ребра
                            ExcludeSubRoute(matrix, dsu, edge);

                            // создание правого потомка для данного родителя
                            right = new Branch(parent.LowerBound + matrix.Reduce(),
                                new Digraph.Edge(edge.Begin, edge.End, Graph[edge.Begin, edge.End]));
                            // добавление в дерево ветвлений
                            tree.Add(parent, Branch.Direction.Right, right);

                            // создание и добавление нового изображения ветвления
                            Current = Painter.Drawing(tree);
                            iterations.Add(Current);
                            // перемещение текущего индекса на конец списка
                            index = iterations.Count;

                            // если размер матрицы достаточно мал
                            if (matrix.RealSize == 2)
                            {
                                // переход в состояние - малый размер матрицы
                                next = IterationState.LittleMatrix;
                                return true;
                            }

                            // выбор новой родительской вершины из еще не подвергшихся ветвлению
                            parent = tree.GetNotGoBranches().OrderBy(b => b.LowerBound).ToList().First();

                            // проверка на нахождения минимального ветвления и остановки
                            if (min.LowerBound <= parent.LowerBound)
                            {
                                // формирование маршрута коммивояжера
                                TsPath = tree.CreatePathFromBranch(min);
                                // остановка метода
                                next = IterationState.Stop;
                                return false;
                            }

                            // корректировка матрицы для данного ветвления и редуцирование
                            if (parent != right)
                            {
                                // новые непересекающиеся множества вершин
                                dsu = new Dsu(Graph.CountVertex());
                                // исходная редуцированная матрица
                                matrix = new ReductionMatrix(Graph.Adjacency);
                                // получение текущих вершин для данного ветвления
                                var currentPath = tree.GetEdgesBranching(parent);

                                // исключение всех подмаршрутов
                                foreach (var e in currentPath)
                                    ExcludeSubRoute(matrix, dsu, e);

                                // редуцирование матрицы
                                matrix.Reduce();
                            }

                            // следующая итерация методав ветвей и границ - левое ветвление
                            next = IterationState.LeftBranching;
                            return true;
                        }
                    // малый рамзер матрицы, включение ребер в маршрут
                    case IterationState.LittleMatrix:
                        {
                            // новый родитель
                            parent = right;
                            for (int i = 0; i < matrix.Size && countAdeddEdgeFromMatrix != 1; i++)
                                for (int j = 0; j < matrix.Size && countAdeddEdgeFromMatrix != 1; j++)
                                {
                                    if (matrix[i, j] == 0)
                                    {
                                        // исключение данного ребра из матрицы
                                        matrix[i, j] = float.PositiveInfinity;
                                        // создание и добавление правого ветвления к родителю
                                        right = new Branch(parent.LowerBound, new Digraph.Edge(i, j, Graph[i, j]));
                                        tree.Add(parent, Branch.Direction.Right, right);
                                        // новый родитель
                                        parent = right;
                                        // продолжать включать ребра в маршрут на следующей итерации
                                        countAdeddEdgeFromMatrix++;
                                    }
                                }

                            // если следующая итерация та же
                            if (countAdeddEdgeFromMatrix == 1)
                            {
                                // создание и добавление нового изображения ветвления
                                Current = Painter.Drawing(tree);
                                iterations.Add(Current);
                                // перемещение текущего индекса на конец списка
                                index = iterations.Count;
                                // на следующей итерации будет включено второе ребро
                                countAdeddEdgeFromMatrix++;
                                return true;
                            }
                            else
                                // все ребра включены для данной матрицы
                                countAdeddEdgeFromMatrix = 0;

                            // иначе проверка на новое минимальное ветвление
                            if (parent.LowerBound < min.LowerBound)
                                min = parent;

                            // создание и добавление нового изображения ветвления
                            Current = Painter.Drawing(tree);
                            iterations.Add(Current);
                            // перемещение текущего индекса на конец списка
                            index = iterations.Count;

                            // выбор новой родительской вершины из еще не подвергшихся ветвлению
                            parent = tree.GetNotGoBranches().OrderBy(b => b.LowerBound).ToList().First();

                            // проверка на нахождения минимального ветвления и остановки
                            if (min.LowerBound <= parent.LowerBound)
                            {
                                // формирование маршрута коммивояжера
                                TsPath = tree.CreatePathFromBranch(min);
                                // остановка метода
                                next = IterationState.Stop;
                                return false;
                            }

                            // корректировка матрицы для данного ветвления и редуцирование
                            if (parent != right)
                            {
                                // новые непересекающиеся множества вершин
                                dsu = new Dsu(Graph.CountVertex());
                                // исходная редуцированная матрица
                                matrix = new ReductionMatrix(Graph.Adjacency);
                                // получение текущих вершин для данного ветвления
                                var currentPath = tree.GetEdgesBranching(parent);

                                // исключение всех подмаршрутов
                                foreach (var e in currentPath)
                                    ExcludeSubRoute(matrix, dsu, e);

                                // редуцирование матрицы
                                matrix.Reduce();
                            }

                            // следующая итерация методав ветвей и границ - левое ветвление
                            next = IterationState.LeftBranching;
                            return true;
                        }
                    default:
                        return false;
                }
            }
        }
示例#39
0
        /// <summary>
        /// Нахождение маршрута коммивояжера
        /// </summary>
        /// <param name="graph">ограф. граф</param>
        /// <returns>маршрут коммивояжера</returns>
        public static Digraph.Path Tsp(Digraph graph)
        {
            // маршрут коммивояжера
            var TsPath = new Digraph.Path(graph);

            // если граф пуст
            if (graph.CountVertex() == 0)
            {
                // пустой маршрут
                return TsPath;
            }
            // если граф имеет одну вершину
            else if (graph.CountVertex() == 1)
            {
                TsPath.Append(new Digraph.Edge(0, 0, 0));
                // маршрут для одной вершины
                return TsPath;
            }
            // если граф имеет две вершины
            else if (graph.CountVertex() == 2)
            {
                TsPath.Append(new Digraph.Edge(0, 1, graph[0, 1]));
                TsPath.Append(new Digraph.Edge(1, 0, graph[1, 0]));
                // маршрут для двух вершин
                return TsPath;
            }

            /// Создания неперекающихся множеств вершин в графе,
            /// для определения и исключения подмаршрутов графа
            var dsu = new Dsu(graph.CountVertex());

            // минимальное ветвление
            var minBranch = new Branch(float.PositiveInfinity, null);

            /// Получение исходной матрицы смежности данного графа
            var matrix = new ReductionMatrix(graph.Adjacency);

            /// Создание корня и дерева ветвления
            var parentBranch = new Branch(matrix.Reduce(), null);
            var tree = new TreeBranch(graph, parentBranch);

            for (; ; )
            {
                // ребра с нулевой стоимостью
                var zeroEdges = new List<Digraph.Edge>();
                // Получение всех ребер и соответсвующих штрафов
                for (int i = 0; i < matrix.Size; i++)
                    for (int j = 0; j < matrix.Size; j++)
                        if (matrix[i, j] == 0)
                            zeroEdges.Add(new Digraph.Edge(i, j, matrix.MinInRow(i, j) + matrix.MinInColumn(j, i)));

                // если нет ребер ветвления - нет маршрута коммивояжера
                if (zeroEdges.Count == 0)
                    return new Digraph.Path(graph);

                /// Определение ребра ветвления - ребра с максимальным штрафом
                var branchingEdge = zeroEdges.OrderByDescending(e => e.Cost).ToList().First();

                /// Процесс ветления - не включая данное ребро
                var leftBranch = new Branch(parentBranch.LowerBound + branchingEdge.Cost,
                    new Digraph.Edge(-branchingEdge.Begin, -branchingEdge.End, float.PositiveInfinity));
                // добавление ветвления в дерево
                tree.Add(parentBranch, Branch.Direction.Left, leftBranch);

                /// Процесс ветления - включая данное ребро
                ExcludeSubRoute(matrix, dsu, branchingEdge);

                var rightBranch = new Branch(parentBranch.LowerBound + matrix.Reduce(),
                    new Digraph.Edge(branchingEdge.Begin, branchingEdge.End, graph[branchingEdge.Begin, branchingEdge.End]));
                // добавление ветвления в дерево
                tree.Add(parentBranch, Branch.Direction.Right, rightBranch);

                /// Проверка на достаточность размера матрцицы
                if (matrix.RealSize == 2)
                {
                    // новый родитель
                    parentBranch = rightBranch;
                    /// Добавление оставщихся ребер в дерево ветвлений
                    for (int i = 0; i < matrix.Size; i++)
                        for (int j = 0; j < matrix.Size; j++)
                            if (matrix[i, j] == 0)
                            {
                                // новый потомок
                                rightBranch = new Branch(parentBranch.LowerBound, new Digraph.Edge(i, j, graph[i, j]));
                                tree.Add(parentBranch, Branch.Direction.Right, rightBranch);
                                // потомок теперь родитель
                                parentBranch = rightBranch;
                            }

                    /// Определение нового минимального ветвления
                    if (parentBranch.LowerBound < minBranch.LowerBound)
                        minBranch = parentBranch;
                }

                /// Выбор новой родительской вершины из еще не подвергшихся ветвлению
                parentBranch = tree.GetNotGoBranches().OrderBy(b => b.LowerBound).ToList().First();

                /// Проверка на нахождения минимального ветвления и остановки
                if (minBranch.LowerBound <= parentBranch.LowerBound)
                    break;

                /// Корректировка матрицы для данного ветвления и редуцирование
                if (parentBranch != rightBranch)
                {
                    // новые непересекающиеся множества вершин
                    dsu = new Dsu(graph.CountVertex());
                    // исходная редуцированная матрица
                    matrix = new ReductionMatrix(graph.Adjacency);
                    // получение текущих вершин для данного ветвления
                    var currentPath = tree.GetEdgesBranching(parentBranch);

                    // исключение всех подмаршрутов
                    foreach (var e in currentPath)
                        ExcludeSubRoute(matrix, dsu, e);

                    // редуцирование матрицы
                    matrix.Reduce();
                }
            }

            // формирование маршрута коммивояжера
            TsPath = tree.CreatePathFromBranch(minBranch);

            return TsPath;
        }