コード例 #1
0
        /// <summary>
        /// This operation moves workspace to given snapshot ID.
        /// All uncommited changes which are made in the workspace are going to be preserved.
        /// In case that conflicting changes were made, ConcurrentModificationException will be thrown and workspace will remain not updated.
        /// </summary>
        /// <param name="newSnapshotId">Snapshot Id to be loaded, must be in sequence after the current snapshot ID</param>
        public void Update(Guid newSnapshotId)
        {
            CheckThread();

            var mapping = workspaceFacade.ChangesBetween(snapshotId, newSnapshotId);

            if (isolatedProvider != null)
            {
                foreach (Guid changedNodeId in isolatedProvider.EnumerateChanges())
                {
                    if (mapping.ContainsKey(changedNodeId))
                    {
                        Guid typeId = Guid.Empty;

                        try
                        {
                            typeId = typesService.GetInstanceTypeId(changedNodeId);
                        }
                        catch
                        {
                            throw new ConcurrentModificationException();
                        }

                        throw new ConcurrentModificationException(typesService.GetTypeFromId(typeId).Name);
                    }
                }
            }

            mutableProxyMap.UpgradeProxies(mapping);

            snapshotId = newSnapshotId;

            workspaceFacade.UpdateWorkspace(workspaceId, snapshotId);
        }
コード例 #2
0
        private void Initialize()
        {
            foreach (var typeId in typesService.GetRegisteredTypes())
            {
                if (!typesService.IsScalarType(typeId))
                {
                    var type = typesService.GetTypeFromId(typeId);

                    var rule = new TypeMergeRule();

                    Type collectionType = null;
                    Type dictionaryType = null;

                    if (!Utils.IsCollectionType(type, ref collectionType) &&
                        !Utils.IsDictionaryType(type, ref dictionaryType))
                    {
                        var attributes = type.GetCustomAttributes(typeof(ConcurrentAttribute), true);

                        if (attributes.Length == 1)
                        {
                            rule.IsConcurrent        = true;
                            rule.IsStaticConcurrency = ((ConcurrentAttribute)attributes[0]).Behavior == ConcurrentBehavior.Static;
                            if (!rule.IsStaticConcurrency)
                            {
                                rule.DynamicResolverType = ((ConcurrentAttribute)attributes[0]).Resolver;
                            }
                            else
                            {
                                foreach (var edge in typesService.GetTypeEdges(typeId))
                                {
                                    if (edge.Data.Semantic == Graph.EdgeType.Property)
                                    {
                                        var memberId = edge.ToNodeId;
                                        //var memberTypeId = typesService.GetMemberTypeId(memberId);
                                        var memberName = typesService.GetMemberName(typeId, memberId);

                                        PropertyInfo propertyInfo = FindPropertyInfo(type, memberName);

                                        bool isOverride = propertyInfo.GetCustomAttributes(typeof(OverrideAttribute), false).Length == 1;

                                        rule.IsMemberOverride.Add(memberId, isOverride);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        rule.IsConcurrent        = true;
                        rule.IsStaticConcurrency = true;
                    }

                    // Add rule for the type in cache
                    typeMergeRules.Add(typeId, rule);
                }
            }
        }
コード例 #3
0
        public void MergeObjects(Guid nodeId, Node <Guid, object, EdgeData> originalNode, Node <Guid, object, EdgeData> changedNode, Node <Guid, object, EdgeData> node, MergeRecursiveDelegate mergeRecursive, InsertRecursiveDelegate insertRecursive, RecursiveResolutionParameters parameters)
        {
            Guid typeId = typesService.GetInstanceTypeId(originalNode);

            if (!objectAttributeProvider.IsConcurrent(typeId))
            {
                var instanceType = typesService.GetTypeFromId(typesService.GetInstanceTypeId(nodeId));
                throw new ConcurrentModificationException("Concurrent modification not allowed for entity type:" + instanceType.ToString());
            }

            if (objectAttributeProvider.IsStaticConcurrency(typeId))
            {
                MergeObjectsStatic(nodeId, typeId, originalNode, changedNode, node, mergeRecursive, insertRecursive, parameters);
            }
            else
            {
                throw new NotImplementedException("Dynamic concurrency not implemented");
            }
        }
コード例 #4
0
        private static void LogCollection(Guid nodeId, Node <Guid, object, EdgeData> node, INodeProvider <Guid, object, EdgeData> nodes, INodeProvider <Guid, object, EdgeData> changes, int tabLevel, Hashtable visited, TypesService typesService)
        {
            Edge <Guid, EdgeData> typeEdge = null;

            BPlusTreeOperations.TryFindEdge(nodes, nodeId, new EdgeData(EdgeType.OfType, null), out typeEdge);

            var typeId   = typeEdge.ToNodeId;
            var typeName = typesService.GetTypeFromId(typeId).Name;

            Debug.WriteLine(LogTabs(tabLevel) + nodeId + "(" + typeName + ")");
            Debug.WriteLine(LogTabs(tabLevel) + "Previous=" + node.Previous);


            using (var enumeration = BPlusTreeOperations.GetEnumerator(nodes, nodeId, EdgeType.ListItem))
            {
                while (enumeration.MoveNext())
                {
                    Debug.WriteLine(LogTabs(tabLevel) + enumeration.Current.Data + "=");
                    LogNodesRecursive(enumeration.Current.ToNodeId, nodes, changes, tabLevel + 1, visited, typesService);
                }
            }
        }
コード例 #5
0
        private static void LogObject(Guid nodeId, Node <Guid, object, EdgeData> node, INodeProvider <Guid, object, EdgeData> nodes, INodeProvider <Guid, object, EdgeData> changes, int tabLevel, Hashtable visited, TypesService typesService)
        {
            var typeId   = typesService.GetInstanceTypeId(node);
            var typeName = typesService.GetTypeFromId(typeId).Name;

            Debug.WriteLine(LogTabs(tabLevel) + nodeId + "(" + typeName + ")");
            Debug.WriteLine(LogTabs(tabLevel) + "Previous=" + node.Previous);

            foreach (var value in node.Values)
            {
                Debug.WriteLine(LogTabs(tabLevel) + typesService.GetMemberName(typeId, value.Key) + "=" + value.Value);
            }

            foreach (var edge in node.Edges)
            {
                if (edge.Value.Data.Semantic == EdgeType.Property)
                {
                    Debug.WriteLine(LogTabs(tabLevel) + typesService.GetMemberName(typeId, (Guid)edge.Value.Data.Data) + "=");
                    LogNodesRecursive(edge.Value.ToNodeId, nodes, changes, tabLevel + 1, visited, typesService);
                }
            }
        }
コード例 #6
0
        /// <summary>
        /// Creates subscription to object changes for specific property
        /// </summary>
        /// <param name="workspaceId">Workspace identifier which is making a subscription</param>
        /// <param name="instanceId">Instance Id which changes are going to be notified</param>
        /// <param name="propertyName">Property name which changes are going to be notified</param>
        /// <param name="notifyChangesFromSameWorkspace">Defines if changes from same workspace should be notified</param>
        /// <param name="del">Delegate to be called</param>
        /// <returns>Subscription object</returns>
        public Subscription Create(Guid workspaceId, Guid instanceId, string propertyName, bool notifyChangesFromSameWorkspace, EventHandler <ObjectChangedEventArgs> del)
        {
            lock (subscriptions)
            {
                var id       = Guid.NewGuid();
                var typeId   = typesService.GetInstanceTypeId(instanceId);
                var memberId = typesService.GetTypeMemberId(typeId, propertyName);

                if (memberId.Equals(Guid.Empty))
                {
                    throw new ArgumentException("Property " + propertyName + " not found in type " + typesService.GetTypeFromId(typeId));
                }

                var res = new SubscriptionElement(id, workspaceId, instanceId, memberId, notifyChangesFromSameWorkspace, del);
                subscriptions.Add(id, res);
                return(new Subscription(id, workspaceId));
            }
        }