#if FAT using System; using System.Threading; namespace LinqInternal.Threading { internal sealed partial class VersionProvider { public struct VersionToken : IComparable, IEquatable { private long _number; private VersionProvider _provider; private Target _target; internal VersionToken(VersionProvider provider) { _number = 0; _target = null; _provider = provider; } internal VersionToken(VersionProvider provider, Target target, long number) { _provider = provider; _target = target; _number = number; } public static bool operator !=(VersionToken left, VersionToken right) { return left.Equals(right); } public static bool operator <(VersionToken left, VersionToken right) { return left.CompareTo(right) < 0; } public static bool operator ==(VersionToken left, VersionToken right) { return left.Equals(right); } public static bool operator >(VersionToken left, VersionToken right) { return left.CompareTo(right) > 0; } /// /// Compares this instance with a specified VersionToken and indicates whether this instances precedes, follows, or represents the same version. /// /// A VersionToken to compare with. /// A 32-bit signed integer indicating whether this instances precedes, follows, or represents the same version. public int CompareTo(VersionToken other) { if (_target == null) { return -1; } if (other._target == null) { return 1; } if (_target == other._target) { return _number.CompareTo(other._number); } var check = _target.CompareToExtracted(other._target); return check == 0 ? _number.CompareTo(other._number) : check; } public bool Equals(VersionToken other) { if (_target == null) { return false; } if (other._target == null) { return false; } if (_target == other._target) { return _number == other._number; } var check = _target.EqualsExtracted(other._target); return check && _number == other._number; } /// /// Marks the current VersionToken as outdated /// public void Reset() { _target = null; _number = 0; } /// /// Set the version of this instance to that of an specefied VersionToken /// /// The VersionToken to copy the version from /// Returns true if the version was changed; otherwise false. public bool SetTo(VersionToken other) { return Interlocked.Exchange(ref _provider, other._provider) != other._provider || Interlocked.Exchange(ref _target, other._target) != other._target || Interlocked.Exchange(ref _number, other._number) != other._number; } /// /// Updates the version of this instance to current up to date version of the VersionProvider from which it was created /// /// Returns true if the version was changed; otherwise false. /// public bool Update() { if (_provider == null) { throw new InvalidOperationException("This VersionToken doesn't have a VersionProvider associated."); } var newTarget = _provider._target; var newNumber = newTarget.Number; return Interlocked.Exchange(ref _target, newTarget) != newTarget || Interlocked.Exchange(ref _number, newNumber) != newNumber; } /// /// Updates the version of this instance to current up to that of an specefied VersionToken if it is newer /// /// The VersionToken to copy the version from /// Returns true if the version was changed; otherwise false. public bool UpdateTo(VersionToken other) { return CompareTo(other) < 0 && ( Interlocked.Exchange(ref _provider, other._provider) != other._provider || Interlocked.Exchange(ref _target, other._target) != other._target || Interlocked.Exchange(ref _number, other._number) != other._number ); } public override bool Equals(object obj) { return obj is VersionProvider && Equals((VersionToken)obj); } public override int GetHashCode() { return base.GetHashCode(); } } } } #endif