Example #1
0
        internal void Discard()
        {
            try
            {
                _persisting = true;
                _removedGraphs.Clear();

                // Read-Only managers have no persistence
                if (_manager.IsReadOnly)
                {
                    return;
                }

                // No actions mean no persistence necessary
                if (_actions.Count == 0)
                {
                    return;
                }

                // Important - For discard we reverse the list of actions so that we
                // rollback the actions in appropriate order
                _actions.Reverse();

                if (_manager.UpdateSupported)
                {
                    // Persist based on Triple level actions
                    // First group Triple together based on Graph URI
                    while (_actions.Count > 0)
                    {
                        TripleStorePersistenceAction action = _actions[0];

                        if (action.IsTripleAction)
                        {
                            Queue <TriplePersistenceAction> actions = new Queue <TriplePersistenceAction>();
                            Uri currUri = _actions[0].TripleAction.Triple.GraphUri;
                            actions.Enqueue(_actions[0].TripleAction);
                            _actions.RemoveAt(0);

                            // Find all the Triple actions related to this Graph up to the next non-Triple action
                            for (int i = 0; i < _actions.Count && _actions[i].IsTripleAction; i++)
                            {
                                if (EqualityHelper.AreUrisEqual(currUri, _actions[i].TripleAction.Triple.GraphUri))
                                {
                                    actions.Enqueue(_actions[i].TripleAction);
                                    _actions.RemoveAt(i);
                                    i--;
                                }
                            }

                            // Split the Triples for this Graph into batches of adds and deletes to ensure
                            // accurate persistence of the actions
                            bool          toDelete = false;
                            List <Triple> batch    = new List <Triple>();
                            while (actions.Count > 0)
                            {
                                TriplePersistenceAction next = actions.Dequeue();
                                if (next.IsDelete != toDelete)
                                {
                                    if (batch.Count > 0)
                                    {
                                        // Process a batch whenever we find a switch between additions and removals
                                        // This ensures that regardless of the logic in UpdateGraph() we force
                                        // additions and removals to happen in the order we care about

                                        // Important - For discard we flip the actions in order to reverse them
                                        // i.e. additions become removals and vice versa
                                        // Also for discard we only need to alter the in-memory state not actually
                                        // do any persistence since the actions will never have been persisted
                                        if (toDelete)
                                        {
                                            this[currUri].Assert(batch);
                                        }
                                        else
                                        {
                                            this[currUri].Retract(batch);
                                        }
                                        batch.Clear();
                                    }
                                    toDelete = next.IsDelete;
                                }
                                batch.Add(next.Triple);
                            }
                            // Ensure the final batch (if any) gets processed
                            if (batch.Count > 0)
                            {
                                // Important - For discard we flip the actions in order to reverse them
                                // i.e. additions become removals and vice versa
                                // Also for discard we only need to alter the in-memory state not actually
                                // do any persistence since the actions will never have been persisted
                                if (toDelete)
                                {
                                    this[currUri].Assert(batch);
                                }
                                else
                                {
                                    this[currUri].Retract(batch);
                                }
                            }
                        }
                        else
                        {
                            switch (action.GraphAction.Action)
                            {
                            case GraphPersistenceActionType.Added:
                                // Need to remove from being in-memory
                                Remove(action.GraphAction.Graph.BaseUri);
                                break;

                            case GraphPersistenceActionType.Deleted:
                                // Need to add back into memory
                                Add(action.GraphAction.Graph, false);
                                break;
                            }
                            _actions.RemoveAt(0);
                        }
                    }
                }
                else
                {
                    // Persist based on Graph level actions
                    foreach (TripleStorePersistenceAction action in _actions)
                    {
                        // Important - For discard we flip the actions in order to reverse them
                        // i.e. additions become removals and vice versa

                        if (action.IsGraphAction)
                        {
                            if (action.GraphAction.Action == GraphPersistenceActionType.Added)
                            {
                                Remove(action.GraphAction.Graph.BaseUri);
                            }
                            else if (action.GraphAction.Action == GraphPersistenceActionType.Deleted)
                            {
                                Add(action.GraphAction.Graph, false);
                            }
                        }
                    }
                }
            }
            finally
            {
                _persisting = false;
            }
        }
Example #2
0
        internal void Flush()
        {
            try
            {
                _persisting = true;
                _removedGraphs.Clear();

                // Read-Only managers have no persistence
                if (_manager.IsReadOnly)
                {
                    return;
                }

                // No actions means no persistence necessary
                if (_actions.Count == 0)
                {
                    return;
                }

                if (_manager.UpdateSupported)
                {
                    // Persist based on Triple level actions
                    // First group Triple together based on Graph URI
                    while (_actions.Count > 0)
                    {
                        TripleStorePersistenceAction action = _actions[0];

                        if (action.IsTripleAction)
                        {
                            Queue <TriplePersistenceAction> actions = new Queue <TriplePersistenceAction>();
                            Uri currUri = action.TripleAction.Triple.GraphUri;
                            actions.Enqueue(_actions[0].TripleAction);
                            _actions.RemoveAt(0);

                            // Find all the Triple actions related to this Graph up to the next non-Triple action
                            for (int i = 0; i < _actions.Count && _actions[i].IsTripleAction; i++)
                            {
                                if (EqualityHelper.AreUrisEqual(currUri, _actions[i].TripleAction.Triple.GraphUri))
                                {
                                    actions.Enqueue(_actions[i].TripleAction);
                                    _actions.RemoveAt(i);
                                    i--;
                                }
                            }

                            // Split the Triple Actions for this Graph into batches of adds and deletes to ensure
                            // accurate persistence of the actions
                            bool          toDelete = false;
                            List <Triple> batch    = new List <Triple>();
                            while (actions.Count > 0)
                            {
                                TriplePersistenceAction next = actions.Dequeue();
                                if (next.IsDelete != toDelete)
                                {
                                    if (batch.Count > 0)
                                    {
                                        // Process a batch whenever we find a switch between additions and removals
                                        // This ensures that regardless of the logic in UpdateGraph() we force
                                        // additions and removals to happen in the order we care about
                                        if (toDelete)
                                        {
                                            _manager.UpdateGraph(currUri, null, batch);
                                        }
                                        else
                                        {
                                            _manager.UpdateGraph(currUri, batch, null);
                                        }
                                        batch.Clear();
                                    }
                                    toDelete = next.IsDelete;
                                }
                                batch.Add(next.Triple);
                            }
                            // Ensure the final batch (if any) gets processed
                            if (batch.Count > 0)
                            {
                                if (toDelete)
                                {
                                    _manager.UpdateGraph(currUri, null, batch);
                                }
                                else
                                {
                                    _manager.UpdateGraph(currUri, batch, null);
                                }
                            }
                        }
                        else
                        {
                            switch (action.GraphAction.Action)
                            {
                            case GraphPersistenceActionType.Added:
                                // No need to do anything in-memory as will be in the graph collection
                                // Call SaveGraph() with an empty graph to create the relevant graph
                                // If Triples were added these will be persisted separately with
                                // TriplePersistenceActions
                                Graph g = new Graph();
                                g.BaseUri = action.GraphAction.Graph.BaseUri;
                                _manager.SaveGraph(g);
                                break;

                            case GraphPersistenceActionType.Deleted:
                                // No need to do anything in-memory as won't be in the graph collection
                                // If DeleteGraph() is supported call it to delete the relevant graph
                                if (_manager.DeleteSupported)
                                {
                                    _manager.DeleteGraph(action.GraphAction.Graph.BaseUri);
                                }
                                break;
                            }
                            _actions.RemoveAt(0);
                        }
                    }
                }
                else
                {
                    // Persist based on Graph level actions
                    foreach (TripleStorePersistenceAction action in _actions)
                    {
                        if (action.IsGraphAction)
                        {
                            if (action.GraphAction.Action == GraphPersistenceActionType.Added)
                            {
                                _manager.SaveGraph(action.GraphAction.Graph);
                            }
                            else if (action.GraphAction.Action == GraphPersistenceActionType.Deleted && _manager.DeleteSupported)
                            {
                                // Can only delete graphs if deletion is supported
                                _manager.DeleteGraph(action.GraphAction.Graph.BaseUri);
                            }
                        }
                    }
                }
            }
            finally
            {
                _persisting = false;
            }
        }