예제 #1
0
        /// <summary>
        /// Adds a new child.
        /// </summary>
        /// <param name="persistenceInformation">The persistence information that describes the dataset that should be copied.</param>
        /// <returns>
        /// The newly created dataset.
        /// </returns>
        public DatasetFacade AddChild(IPersistenceInformation persistenceInformation)
        {
            {
                Enforce.Argument(() => persistenceInformation);
            }

            // For user created datasets we have some default settings:
            // - We don't ever allow nodes to be adopted, it just creates too much of a hassle with
            //   updating the node links etc.
            // - We always allow user created datasets to become parents, they may need to split
            //   of their calculations
            // - We allow all user created datasets to be copied
            // - User created datasets can always be deleted
            var creationInformation = new DatasetCreationInformation
            {
                CanBeAdopted       = false,
                CanBecomeParent    = true,
                CanBeCopied        = true,
                CanBeDeleted       = true,
                CreatedOnRequestOf = DatasetCreator.User,
                LoadFrom           = persistenceInformation,
            };

            var child = m_Dataset.CreateNewChild(creationInformation);

            return(new DatasetFacade(child));
        }
예제 #2
0
        public void AddChildWithPersistenceInformation()
        {
            DatasetCreationInformation creationInformation = null;

            var storage = new Mock <IPersistenceInformation>();
            var child   = CreateMockDataset();
            var dataset = new Mock <IProxyDataset>();
            {
                dataset.Setup(d => d.StoredAt)
                .Returns(new Mock <IPersistenceInformation>().Object);

                dataset.Setup(d => d.CreateNewChild(It.IsAny <DatasetCreationInformation>()))
                .Callback <DatasetCreationInformation>(d => creationInformation = d)
                .Returns(child);
            }

            var facade      = new DatasetFacade(dataset.Object);
            var childFacade = facade.AddChild(storage.Object);

            Assert.AreEqual(new DatasetFacade(child), childFacade);
            Assert.IsFalse(creationInformation.CanBeAdopted);
            Assert.IsTrue(creationInformation.CanBecomeParent);
            Assert.IsTrue(creationInformation.CanBeCopied);
            Assert.IsTrue(creationInformation.CanBeDeleted);
            Assert.AreEqual(DatasetCreator.User, creationInformation.CreatedOnRequestOf);
            Assert.AreEqual(storage.Object, creationInformation.LoadFrom);
        }
예제 #3
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);
        }
예제 #4
0
        /// <summary>
        /// Creates a new child dataset and returns the ID number of the child.
        /// </summary>
        /// <param name="newChild">The information required to create the new child.</param>
        /// <returns>
        /// The ID number of the child.
        /// </returns>
        /// <exception cref="ArgumentException">
        ///     Thrown when the owning project has been closed.
        /// </exception>
        /// <exception cref="DatasetCannotBecomeParentException">
        ///     Thrown when the current dataset cannot become a parent.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        ///     Thrown when <paramref name="newChild"/> is <see langword="null" />.
        /// </exception>
        public IProxyDataset CreateNewChild(DatasetCreationInformation newChild)
        {
            {
                Lokad.Enforce.With <ArgumentException>(
                    !Owner.IsClosed,
                    Resources.Exceptions_Messages_CannotUseProjectAfterClosingIt);
                Lokad.Enforce.With <DatasetCannotBecomeParentException>(
                    CanBecomeParent,
                    Resources.Exceptions_Messages_DatasetCannotBecomeParent_WithId,
                    Id);
                Lokad.Enforce.Argument(() => newChild);
            }

            return(Owner.CreateDataset(Id, newChild));
        }
예제 #5
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);
        }
예제 #6
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);
                    }
                }
            }
        }