///***************************************************/
        ///**** Public Methods                            ****/
        ///***************************************************/

        public static void SetHashFragment(IEnumerable <IBHoMObject> objs, List <string> exceptions = null, bool useDefaultExceptions = true)
        {
            if (useDefaultExceptions)
            {
                Compute.SetDefaultExceptions(ref exceptions);
            }

            // Calculate and set the object hashes
            foreach (var obj in objs)
            {
                string hash = BH.Engine.Diffing.Compute.DiffingHash(obj, exceptions, useDefaultExceptions);

                HashFragment existingFragm = obj.GetHashFragment();

                if (existingFragm != null)
                {
                    obj.Fragments.RemoveAll(fr => (fr as HashFragment) != null);
                    obj.Fragments.Add(new HashFragment(hash, existingFragm.Hash));
                }
                else
                {
                    obj.Fragments.Add(new HashFragment(hash, null));
                }
            }
        }
Ejemplo n.º 2
0
        public static Delta Diffing(Stream previousStream, Stream currentStream, bool enablePropertyDiff = true, List <string> exceptions = null, bool useDefaultExceptions = true)
        {
            // Take the Stream's objects
            List <IBHoMObject> currentObjs = currentStream.Objects.ToList();
            List <IBHoMObject> readObjs    = previousStream.Objects.ToList();

            // Make dictionary with object hashes to speed up the next lookups
            Dictionary <string, IBHoMObject> readObjs_dict = readObjs.ToDictionary(obj => obj.GetHashFragment().Hash, obj => obj);

            // Set exceptions
            if (useDefaultExceptions)
            {
                Compute.SetDefaultExceptions(ref exceptions);
            }

            // Dispatch the objects: new, modified or old
            List <IBHoMObject> toBeCreated = new List <IBHoMObject>();
            List <IBHoMObject> toBeUpdated = new List <IBHoMObject>();
            List <IBHoMObject> toBeDeleted = new List <IBHoMObject>();
            var objModifiedProps           = new Dictionary <string, Dictionary <string, Tuple <object, object> > >();

            foreach (var obj in currentObjs)
            {
                var hashFragm = obj.GetHashFragment();

                if (hashFragm?.PreviousHash == null)
                {
                    toBeCreated.Add(obj); // It's a new object
                }

                else if (hashFragm.PreviousHash == hashFragm.Hash)
                {
                    // It's NOT been modified
                }

                else if (hashFragm.PreviousHash != hashFragm.Hash)
                {
                    toBeUpdated.Add(obj); // It's been modified

                    if (enablePropertyDiff)
                    {
                        // Determine changed properties
                        IBHoMObject oldObjState = null;
                        readObjs_dict.TryGetValue(hashFragm.PreviousHash, out oldObjState);

                        if (oldObjState == null)
                        {
                            continue;
                        }

                        IsEqualConfig config = new IsEqualConfig();
                        config.PropertiesToIgnore = exceptions;

                        var differentProps = BH.Engine.Testing.Query.DifferentProperties(obj, oldObjState, config);

                        objModifiedProps.Add(hashFragm.Hash, differentProps);
                    }
                }
                else
                {
                    throw new Exception("Could not find hash information to perform Diffing on some objects.");
                }
            }

            // If no modified property was found, set the field to null (otherwise will get empty list)
            objModifiedProps = objModifiedProps.Count == 0 ? null : objModifiedProps;

            // All ReadObjs that cannot be found by hash in the previousHash of the CurrentObjs are toBeDeleted
            Dictionary <string, IBHoMObject> CurrentObjs_withPreviousHash_dict = currentObjs
                                                                                 .Where(obj => obj.GetHashFragment().PreviousHash != null)
                                                                                 .ToDictionary(obj => obj.GetHashFragment().PreviousHash, obj => obj);

            toBeDeleted = readObjs_dict.Keys.Except(CurrentObjs_withPreviousHash_dict.Keys)
                          .Where(k => readObjs_dict.ContainsKey(k)).Select(k => readObjs_dict[k]).ToList();

            return(new Delta(toBeCreated, toBeDeleted, toBeUpdated, objModifiedProps));
        }