/// <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); }
/// <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); }
/// <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(); } }
/// <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; } } }
/// <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); }
/// <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 }