예제 #1
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///  Ajout d'une valeur.
        /// </summary>
        /// <exception cref="DuplicateElementException">
        ///  Thrown when a Duplicate Element error condition occurs.
        /// </exception>
        /// <param name="node">
        ///  .
        /// </param>
        /// <param name="ownerKey">
        ///  (Optional)
        /// </param>
        ///-------------------------------------------------------------------------------------------------
        public void AddNode(GraphNode node, Identity ownerKey = null)
        {
            DebugContract.Requires(node, "node");

            using (var ctx = CreateCommandContext())
            {
                var currentSlot = new Slot <GraphNode>(node);

                _valuesLock.EnterUpgradeableReadLock();
                try
                {
                    SlotList slots = null;
                    if (!_values.TryGetValue(node.Id, out slots))
                    {
                        // N'existe pas encore. On rajoute
                        slots = new SlotList(node.Id, node.NodeType, ownerKey);
                        _valuesLock.EnterWriteLock();
                        try
                        {
                            _values.Add(node.Id, slots);
                        }
                        finally
                        {
                            _valuesLock.ExitWriteLock();
                        }

                        AddSlot(ctx, slots, currentSlot);
                        // No vaccum notification here since the element is new
                    }
                    else
                    {
                        if (SelectSlot(node.Id, ctx) != null)
                        {
                            throw new DuplicateElementException(node.Id.ToString());
                        }

                        if (_values.TryGetValue(node.Id, out slots))
                        {
                            var initialSlot = slots.GetActiveSlot();
                            AddSlot(ctx, slots, currentSlot);
                            if (initialSlot != null)
                            {
                                initialSlot.CMin = ctx.CommandId;
                                initialSlot.XMax = ctx.Transaction.Id;
                            }
                            NotifyVacuum(slots);
                        }
                    }

                    _trace.WriteTrace(TraceCategory.MemoryStore, "Add {0} - {1}", node.Id, node);
                    ctx.Complete();
                }
                finally
                {
                    _statAddValue.Incr();
                    _valuesLock.ExitUpgradeableReadLock();
                }
            }
        }
예제 #2
0
        private void NotifyVacuum(SlotList slots)
        {
#if !DEBUG
            if (_jobScheduler != null)
            {
                _involvedSlots.Enqueue(slots);
                _jobScheduler.RequestJob();
            }
#endif
        }
예제 #3
0
        private void AddSlot(CommandContext ctx, SlotList slots, Slot <GraphNode> v)
        {
            DebugContract.Requires(ctx, "ctx");
            DebugContract.Requires(slots, "slots");
            DebugContract.Requires(v, "v");

            v.XMin = ctx.Transaction.Id;
            v.XMax = null;
            v.CMin = ctx.CommandId;
            slots.Add(v);
        }
예제 #4
0
        internal SlotList(SlotList clone)
        {
            DebugContract.Requires(clone, "clone");

            _ownerKey    = clone._ownerKey;
            _elementType = clone._elementType;
            Id           = clone.Id;
            _ownerKey    = clone._ownerKey;
            _slots       = new List <ISlot>(Length + 2);
            _slots.AddRange(clone._slots.Where(s => s.Id > 0));
            Length = _slots.Count;
        }
예제 #5
0
        ///-------------------------------------------------------------------------------------------------
        /// <summary>
        ///  Mise à jour d'une valeur.
        /// </summary>
        /// <exception cref="Exception">
        ///  Thrown when an exception error condition occurs.
        /// </exception>
        /// <param name="node">
        ///  .
        /// </param>
        ///-------------------------------------------------------------------------------------------------
        public void UpdateNode(GraphNode node)
        {
            DebugContract.Requires(node);

            using (var ctx = CreateCommandContext())
            {
                try
                {
                    // Test existence tuple ?
                    SlotList slots = null;
                    _valuesLock.EnterReadLock();
                    try
                    {
                        _values.TryGetValue(node.Id, out slots);
                    }
                    finally
                    {
                        _valuesLock.ExitReadLock();
                    }

                    if (slots != null)
                    {
                        var currentSlot = slots.GetActiveSlot();
                        var newSlot     = new Slot <GraphNode>(node);
                        AddSlot(ctx, slots, newSlot);
                        if (currentSlot != null)
                        {
                            currentSlot.CMin = ctx.CommandId;
                            currentSlot.XMax = ctx.Transaction.Id;
                        }

                        NotifyVacuum(slots);
                        Debug.Assert(slots.Count(e => e.XMax == null) == 1);
                        _trace.WriteTrace(TraceCategory.MemoryStore, "Update {0} - {1}", node.Id, node);
                    }
                    else
                    {
                        throw new HypergraphException(ExceptionMessages.NotFound + node.Id);
                    }
                }
                finally
                {
                    // On valide la transaction dans tous les cas pour qu'elle soit purgée par le vacuum
                    ctx.Complete();
                    _statUpdateValue.Incr();
                }
            }
        }