Exemplo n.º 1
0
        /// <summary>
        /// Creates a new dataset as child of the given parent dataset.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="newChild">The information required to create the new child.</param>
        /// <returns>The new child.</returns>
        public IProxyDataset CreateDataset(DatasetId parent, DatasetCreationInformation newChild)
        {
            {
                Debug.Assert(!IsClosed, "The project should not be closed if we want to create a new dataset.");
                Debug.Assert(
                    (parent == null) || ((parent != null) && m_Datasets.Datasets.ContainsKey(parent)),
                    "The provided parent node does not exist.");
                Debug.Assert(
                    (parent == null) || ((parent != null) && m_Datasets.Datasets[parent].CanBecomeParent),
                    "The given parent is not allowed to have children.");
            }

            m_Diagnostics.Log(
                LevelToLog.Trace,
                HostConstants.LogPrefix,
                string.Format(
                    CultureInfo.InvariantCulture,
                    Resources.Project_LogMessage_CreatingDataset_WithInformation,
                    parent));

            var dataset = CreateNewDatasetProxy(newChild);

            // When adding a new dataset there is no way we can create cycles because
            // we can only add new children to parents, there is no way to link an
            // existing node to the parent.
            lock (m_Lock)
            {
                m_Datasets.Datasets.Add(dataset.Id, dataset);
                m_Datasets.Graph.AddVertex(dataset.Id);
            }

            if (parent != null)
            {
                // Find the actual ID object that we have stored, the caller may have a copy
                // of ID. Using a copy of the real ID might cause issues when connecting the
                // graph so we only use the ID numbers that we have stored.
                var realParent = m_Datasets.Datasets[parent].Id;
                lock (m_Lock)
                {
                    m_Datasets.Graph.AddEdge(new Edge<DatasetId>(realParent, dataset.Id));
                }
            }

            RaiseOnDatasetCreated();
            return dataset;
        }
Exemplo n.º 2
0
        private DatasetProxy CreateNewDatasetProxy(DatasetCreationInformation newChild)
        {
            var id = new DatasetId();
            Action<DatasetId> cleanupAction = localId => DeleteDatasetAndChildren(localId, d => { });
            var parameters = new DatasetConstructionParameters
                {
                    Id = id,
                    Owner = this,
                    DistributionPlanGenerator = m_DatasetDistributor,
                    CreatedOnRequestOf = newChild.CreatedOnRequestOf,
                    CanBecomeParent = newChild.CanBecomeParent,
                    CanBeAdopted = newChild.CanBeAdopted,
                    CanBeCopied = newChild.CanBeCopied,
                    CanBeDeleted = newChild.CanBeDeleted,
                    IsRoot = newChild.IsRoot,
                    LoadFrom = newChild.LoadFrom,
                    OnRemoval = cleanupAction,
                };

            var newDataset = m_Timeline.AddToTimeline(
                DatasetProxy.CreateInstance,
                parameters,
                m_DataStorageProxyBuilder,
                m_Notifications,
                m_Diagnostics);

            return newDataset;
        }
Exemplo n.º 3
0
        public void RollForwardWithDeletesOnly()
        {
            ITimeline timeline = null;
            timeline = new Timeline(t => BuildStorage(timeline, t));
            var systemDiagnostics = new SystemDiagnostics((p, s) => { }, null);
            var offline = new Mock<IDatasetOfflineInformation>();

            var plan = new DistributionPlan(
                (p, t, r) => Task<DatasetOnlineInformation>.Factory.StartNew(
                    () => new DatasetOnlineInformation(
                        new DatasetId(),
                        new EndpointId("id"),
                        new NetworkIdentifier("machine"),
                        new Mock<ISendCommandsToRemoteEndpoints>().Object,
                        new Mock<INotifyOfRemoteEndpointEvents>().Object,
                        systemDiagnostics),
                    t,
                    TaskCreationOptions.None,
                    new CurrentThreadTaskScheduler()),
                offline.Object,
                new NetworkIdentifier("mymachine"),
                new DatasetActivationProposal());
            Func<DatasetActivationRequest, CancellationToken, IEnumerable<DistributionPlan>> distributor =
                (r, c) => new List<DistributionPlan> { plan };
            var proxyLayer = new Mock<IProxyCompositionLayer>();
            var project = new Project(
                timeline,
                distributor,
                d => new DatasetStorageProxy(
                    d,
                    new GroupSelector(
                        new Mock<IConnectGroups>().Object,
                        proxyLayer.Object),
                    proxyLayer.Object),
                new Mock<ICollectNotifications>().Object,
                systemDiagnostics);

            // Create a 'binary' tree of datasets. This should create the following tree:
            //                            X
            //                          /   \
            //                         /     \
            //                        /       \
            //                       /         \
            //                      /           \
            //                     X             X
            //                   /   \         /   \
            //                  /     \       /     \
            //                 /       \     /       \
            //                X         X   X         X
            //              /   \     /   \
            //             X     X   X     X
            var children = new List<DatasetId>();
            var datasets = new Queue<IProxyDataset>();
            var root = project.BaseDataset();
            datasets.Enqueue(root);

            int count = 0;
            while (count < 10)
            {
                var creationInformation = new DatasetCreationInformation()
                {
                    CreatedOnRequestOf = DatasetCreator.User,
                    CanBecomeParent = true,
                    CanBeAdopted = false,
                    CanBeCopied = false,
                    CanBeDeleted = true,
                    LoadFrom = new Mock<IPersistenceInformation>().Object,
                };

                var parent = datasets.Dequeue();
                var newChildren = parent.CreateNewChildren(new DatasetCreationInformation[] { creationInformation, creationInformation });
                foreach (var child in newChildren)
                {
                    datasets.Enqueue(child);
                    children.Add(child.Id);
                    count++;
                }
            }

            var marks = new List<TimeMarker>();
            marks.Add(project.History.Mark());
            for (int i = children.Count - 1; i > -1; i--)
            {
                var child = project.Dataset(children[i]);
                child.Delete();
                marks.Add(project.History.Mark());
            }

            project.History.RollBackTo(marks[0]);

            for (int i = 1; i < marks.Count; i++)
            {
                project.History.RollForwardTo(marks[i]);
                Assert.AreEqual(children.Count - i + 1, project.NumberOfDatasets);
                for (int j = 0; j < children.Count; j++)
                {
                    var child = project.Dataset(children[j]);
                    if (j < children.Count - i)
                    {
                        Assert.IsTrue(child.IsValid);
                    }
                    else
                    {
                        Assert.IsNull(child);
                    }
                }
            }
        }