Пример #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SnapshotElementComparer" /> class.
 /// </summary>
 /// <param name="region">The parent region that contains this element.</param>
 /// <param name="pointerIncrementMode">The method by which to increment element pointers.</param>
 /// <param name="constraints">The constraints to use for the element comparisons.</param>
 public unsafe SnapshotElementComparer(
     SnapshotRegion region,
     PointerIncrementMode pointerIncrementMode,
     ConstraintNode constraints) : this(region, pointerIncrementMode)
 {
     this.ElementCompare = this.BuildCompareActions(constraints);
 }
Пример #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="SnapshotElementComparer" /> class.
        /// </summary>
        /// <param name="region">The parent region that contains this element.</param>
        /// <param name="pointerIncrementMode">The method by which to increment element pointers.</param>
        /// <param name="constraints">The constraints to use for the element comparisons.</param>
        public unsafe SnapshotElementComparer(SnapshotRegion region, PointerIncrementMode pointerIncrementMode, DataTypeBase dataType)
        {
            this.Region          = region;
            this.CurrentTypeCode = Type.GetTypeCode(dataType);

            // The garbage collector can relocate variables at runtime. Since we use unsafe pointers, we need to keep these pinned
            this.CurrentValuesHandle  = GCHandle.Alloc(this.Region.ReadGroup.CurrentValues, GCHandleType.Pinned);
            this.PreviousValuesHandle = GCHandle.Alloc(this.Region.ReadGroup.PreviousValues, GCHandleType.Pinned);

            this.InitializePointers();
            this.SetConstraintFunctions();
            this.SetPointerFunction(pointerIncrementMode);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SnapshotElementIterator" /> class.
        /// </summary>
        /// <param name="parent">The parent region that contains this element.</param>
        /// <param name="elementIndex">The index of the element to begin pointing to.</param>
        /// <param name="compareActionConstraint">The constraint to use for the element quick action.</param>
        /// <param name="compareActionValue">The value to use for the element quick action.</param>
        /// <param name="pointerIncrementMode">The method by which to increment element pointers.</param>
        public unsafe SnapshotElementIterator(
            SnapshotRegion parent,
            Int32 elementIndex = 0,
            PointerIncrementMode pointerIncrementMode = PointerIncrementMode.AllPointers,
            ConstraintsEnum compareActionConstraint   = ConstraintsEnum.Changed,
            Object compareActionValue = null)
        {
            this.Parent = parent;

            // The garbage collector can relocate variables at runtime. Since we use unsafe pointers, we need to keep these pinned
            this.CurrentValuesHandle  = GCHandle.Alloc(this.Parent.CurrentValues, GCHandleType.Pinned);
            this.PreviousValuesHandle = GCHandle.Alloc(this.Parent.PreviousValues, GCHandleType.Pinned);

            this.InitializePointers(elementIndex);
            this.SetConstraintFunctions();
            this.SetPointerFunction(pointerIncrementMode);
            this.SetCompareAction(compareActionConstraint, compareActionValue);
        }
Пример #4
0
        /// <summary>
        /// Gets the enumerator for an element reference within this snapshot region.
        /// </summary>
        /// <param name="pointerIncrementMode">The method for incrementing pointers.</param>
        /// <param name="compareActionConstraint">The constraint to use for the element quick action.</param>
        /// <param name="compareActionValue">The value to use for the element quick action.</param>
        /// <returns>The enumerator for an element reference within this snapshot region.</returns>
        public IEnumerator <SnapshotElementIterator> IterateElements(
            PointerIncrementMode pointerIncrementMode,
            ConstraintsEnum compareActionConstraint = ConstraintsEnum.Changed,
            Object compareActionValue = null)
        {
            UInt64 elementCount = this.ElementCount;
            SnapshotElementIterator snapshotElement = new SnapshotElementIterator(
                parent: this,
                pointerIncrementMode: pointerIncrementMode,
                compareActionConstraint: compareActionConstraint,
                compareActionValue: compareActionValue);

            for (UInt64 index = 0; index < elementCount; index++)
            {
                yield return(snapshotElement);

                snapshotElement.IncrementPointers();
            }
        }
Пример #5
0
        /// <summary>
        /// Initializes the pointer incrementing function based on the provided parameters.
        /// </summary>
        /// <param name="pointerIncrementMode">The method by which to increment pointers.</param>
        private unsafe void SetPointerFunction(PointerIncrementMode pointerIncrementMode)
        {
            Int32 alignment = this.Region.ReadGroup.Alignment;

            if (this.Region.ReadGroup.Alignment == 1)
            {
                switch (pointerIncrementMode)
                {
                case PointerIncrementMode.AllPointers:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentLabelIndex++;
                        this.CurrentValuePointer++;
                        this.PreviousValuePointer++;
                    };
                    break;

                case PointerIncrementMode.CurrentOnly:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentValuePointer++;
                    };
                    break;

                case PointerIncrementMode.LabelsOnly:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentLabelIndex++;
                    };
                    break;

                case PointerIncrementMode.NoPrevious:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentLabelIndex++;
                        this.CurrentValuePointer++;
                    };
                    break;

                case PointerIncrementMode.ValuesOnly:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentValuePointer++;
                        this.PreviousValuePointer++;
                    };
                    break;
                }
            }
            else
            {
                switch (pointerIncrementMode)
                {
                case PointerIncrementMode.AllPointers:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentLabelIndex    += alignment;
                        this.CurrentValuePointer  += alignment;
                        this.PreviousValuePointer += alignment;
                    };
                    break;

                case PointerIncrementMode.CurrentOnly:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentValuePointer += alignment;
                    };
                    break;

                case PointerIncrementMode.LabelsOnly:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentLabelIndex += alignment;
                    };
                    break;

                case PointerIncrementMode.NoPrevious:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentLabelIndex   += alignment;
                        this.CurrentValuePointer += alignment;
                    };
                    break;

                case PointerIncrementMode.ValuesOnly:
                    this.IncrementPointers = () =>
                    {
                        this.CurrentValuePointer  += alignment;
                        this.PreviousValuePointer += alignment;
                    };
                    break;
                }
            }
        }
Пример #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SnapshotElementComparer" /> class.
 /// </summary>
 /// <param name="region">The parent region that contains this element.</param>
 /// <param name="pointerIncrementMode">The method by which to increment element pointers.</param>
 /// <param name="constraints">The constraints to use for the element comparisons.</param>
 public unsafe SnapshotElementComparer(SnapshotRegion region, PointerIncrementMode pointerIncrementMode, Constraint constraints, DataTypeBase dataType) : this(region, pointerIncrementMode, dataType)
 {
     this.ElementCompare = this.BuildCompareActions(constraints);
 }
Пример #7
0
        /// <summary>
        /// Called when the scan updates.
        /// </summary>
        /// <param name="cancellationToken">The cancellation token for handling canceled tasks.</param>
        protected override void OnUpdate(CancellationToken cancellationToken)
        {
            Int32   processedPages        = 0;
            Boolean hasRelativeConstraint = this.ScanConstraintManager.HasRelativeConstraint();

            // Determine if we need to increment both current and previous value pointers, or just current value pointers
            PointerIncrementMode pointerIncrementMode = hasRelativeConstraint ? PointerIncrementMode.ValuesOnly : PointerIncrementMode.CurrentOnly;

            cancellationToken.ThrowIfCancellationRequested();

            // Enforce each value constraint
            foreach (ScanConstraint scanConstraint in this.ScanConstraintManager)
            {
                this.Snapshot.SetAllValidBits(false);

                Parallel.ForEach(
                    this.Snapshot.Cast <SnapshotRegion>(),
                    SettingsViewModel.GetInstance().ParallelSettingsFullCpu,
                    (region) =>
                {
                    // Check for canceled scan
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    // Ignore region if it requires current & previous values, but we cannot find them
                    if (hasRelativeConstraint && !region.CanCompare())
                    {
                        return;
                    }

                    for (IEnumerator <SnapshotElementIterator> enumerator = region.IterateElements(pointerIncrementMode, scanConstraint.Constraint, scanConstraint.ConstraintValue);
                         enumerator.MoveNext();)
                    {
                        SnapshotElementIterator element = enumerator.Current;

                        // Perform the comparison based on the current scan constraint
                        if (element.Compare())
                        {
                            element.SetValid(true);
                        }
                    }
                    //// End foreach Element

                    lock (this.ProgressLock)
                    {
                        processedPages++;

                        // Limit how often we update the progress
                        if (processedPages % 10 == 0)
                        {
                            this.UpdateProgress(processedPages / this.ScanConstraintManager.Count(), this.Snapshot.RegionCount, canFinalize: false);
                        }
                    }
                });
                //// End foreach Region

                // Exit if canceled
                cancellationToken.ThrowIfCancellationRequested();
            }
            //// End foreach Constraint
        }