public static void Join(Event e1, Event e2)
        {
            if (!e1.IsLeaf
                && !e2.IsLeaf
                && e1.Value > e2.Value)
            {
                Join(e2, e1);
                e1.Copy(e2);
                e1.Normalize();
                return;
            }

            if (!e1.IsLeaf
                && !e2.IsLeaf
                && e1.Value <= e2.Value)
            {
                var d = e2.Value - e1.Value;
                e2.Left.Lift(d);
                e2.Right.Lift(d);
                Join(e1.Left, e2.Left);
                Join(e1.Right, e2.Right);
                e1.Normalize();
                return;
            }

            if (e1.IsLeaf
                && !e2.IsLeaf)
            {
                e1.SetAsNode();
                Join(e1, e2);
                e1.Normalize();
                return;
            }

            if (!e1.IsLeaf
                && e2.IsLeaf)
            {
                e2.SetAsNode();
                Join(e1, e2);
                e1.Normalize();
                return;
            }

            if (e1.IsLeaf
                && e2.IsLeaf)
            {
                e1.Value = GetMaxValue(e1, e2);
                e1.Normalize();
                return;
            }

            throw new EventOperationException("Event Join failed", e1, e2);
        }
 public static Event Clone(Event orig)
 {
     return (Event)(orig == null ? null : orig.Clone());
 }
        private void DecodeCheck2(BitArray bt)
        {
            var valCheck2 = bt.ReadBits(2);

            if (valCheck2 == 0)
            {
                Value = 0;
                Left = new Event(0);
                Right = new Event();
                Right.Decode(bt);
                return;
            }

            if (valCheck2 == 1)
            {
                SetAsNode(0, null, 0, bt);
                return;
            }

            if (valCheck2 == 2)
            {
                SetAsNode(0, null, null, bt);
                return;
            }

            if (valCheck2 == 3)
            {
                DecodeCheck3(bt);
                return;
            }

            throw new EventOperationException("Decode Failed (Check2)", this, null);
        }
 protected bool Equals(Event inEvent)
 {
     return Equals(Left, inEvent.Left) && Equals(Right, inEvent.Right) && Value == inEvent.Value;
 }
 protected static int GetMaxValue(Event e1, Event e2)
 {
     return Math.Max(e1.Value, e2.Value);
 }
 public static Event Lift(int val, Event e)
 {
     var res = (Event)e.Clone();
     res.Lift(val);
     return res;
 }
 protected Stamp(Stamp s)
 {
     Event = s.Event;
     Id = s.Id;
 }
 protected Stamp(Id i, Event e)
 {
     Id = i;
     Event = e;
 }
        public void SetAsNode(int value, int? leftValue, int? rightValue, BitArray bt)
        {
            Value = value;

            if (leftValue.HasValue)
            {
                Left = new Event(leftValue.Value);
            }
            else
            {
                Left = new Event();
                Left.Decode(bt);
            }

            if (rightValue.HasValue)
            {
                Right = new Event(rightValue.Value);
            }
            else
            {
                Right = new Event();
                Right.Decode(bt);
            }
        }
 public void SetAsNode()
 {
     Left = new Event(0);
     Right = new Event(0);
 }
        public bool Leq(Event e)
        {
            if (!IsLeaf
                && !e.IsLeaf)
            {
                if (Value > e.Value)
                {
                    return false;
                }

                if (!Lift(Value, Left).Leq(Lift(e.Value, e.Left)))
                {
                    return false;
                }

                if (!Lift(Value, Right).Leq(Lift(e.Value, e.Right)))
                {
                    return false;
                }

                return true;
            }

            if (!IsLeaf
                && e.IsLeaf)
            {
                if (Value > e.Value)
                {
                    return false;
                }

                if (!Lift(Value, Left).Leq(e))
                {
                    return false;
                }

                if (!Lift(Value, Right).Leq(e))
                {
                    return false;
                }

                return true;
            }

            if (IsLeaf && e.IsLeaf)
            {
                return Value <= e.Value;
            }

            if (IsLeaf && !e.IsLeaf)
            {
                if (Value < e.Value)
                {
                    return true;
                }

                var ev = (Event)Clone();
                ev.SetAsNode();
                return ev.Leq(e);
            }

            throw new EventOperationException("Leq operation failed", this, e);
        }
 public Event(Event e)
 {
     Value = e.Value;
     Left = Clone(e.Left);
     Right = Clone(e.Right);
 }
 public void Copy(Event e)
 {
     Value = e.Value;
     Left = e.Left;
     Right = e.Right;
 }
 public object Clone()
 {
     var res = new Event(this);
     return res;
 }
 public void SetLeft(Event left)
 {
     Left = left;
 }
 public Stamp()
 {
     Event = new Event();
     Id = new Id();
 }
 public void SetMaxValue(Event e1, Event e2)
 {
     Value = GetMaxValue(e1, e2);
 }
        protected static void StampFill(Id i, Event e)
        {
            if (i.IsLeaf
                && i.Value == 0)
            {
                return;
            }

            if (i.IsLeaf
                && i.Value == 1)
            {
                e.Height();
                return;
            }

            if (e.IsLeaf)
            {
                return;
            }

            if (i.IsLeaf == false
                && i.Left.IsLeaf
                && i.Left.Value == 1)
            {
                StampFill(i.Right, e.Right);
                e.Left.Height();
                e.Left.SetMaxValue(e.Left, e.Right);
                e.Normalize();
                return;
            }

            if (i.IsLeaf == false
                && i.Right.IsLeaf
                && i.Right.Value == 1)
            {
                StampFill(i.Left, e.Left);
                e.Right.Height();
                e.Right.SetMaxValue(e.Right, e.Left);
                e.Normalize();
                return;
            }

            if (i.IsLeaf == false)
            {
                StampFill(i.Left, e.Left);
                StampFill(i.Right, e.Right);
                e.Normalize();
                return;
            }

            throw new StampOperationException(string.Format("Fill failed: id: {0}, event: {1}", i, e));
        }
 public void SetRight(Event right)
 {
     Right = right;
 }
        protected static int StampGrow(Id i, Event e)
        {
            int cost;

            if (i.IsLeaf
                && i.Value == 1
                && e.IsLeaf)
            {
                e.SetValue(e.Value + 1);
                return 0;
            }

            if (e.IsLeaf)
            {
                e.SetAsNode();
                cost = StampGrow(i, e);
                return cost + 1000;
            }

            if (i.IsLeaf == false
                && i.Left.IsLeaf
                && i.Left.Value == 0)
            {
                cost = StampGrow(i.Right, e.Right);
                return cost + 1;
            }

            if (i.IsLeaf == false
                && i.Right.IsLeaf
                && i.Right.Value == 0)
            {
                cost = StampGrow(i.Left, e.Left);
                return cost + 1;
            }

            if (i.IsLeaf == false)
            {
                var el = Event.Clone(e.Left);
                var er = Event.Clone(e.Right);
                var costr = StampGrow(i.Right, e.Right);
                var costl = StampGrow(i.Left, e.Left);
                if (costl < costr)
                {
                    e.SetRight(er);
                    return costl + 1;
                }

                e.SetLeft(el);
                return costr + 1;
            }

            throw new StampOperationException(string.Format("Grow failed: id: {0}, event: {1}", i, e));
        }
 public EventOperationException(string message, Event e1, Event e2)
     : base(string.Format("{0} - Event1: {1} - Event2: {2}", message, e1, e2))
 {
     Event1 = e1;
     Event2 = e2;
 }