/// <summary> /// Gets the user value in the versioned item. /// </summary> /// <param name="metadataTable">The metadata table</param> /// <param name="valueSerializer">The value serializer.</param> /// <param name="isValueAReferenceType">Is reference type</param> /// <param name="readMode">The read mode.</param> /// <param name="valueCounter">Loaded value counter.</param> /// <param name="cancellationToken">Token used to signal cancellation.</param> /// <param name="traceType">trace Id</param> /// <param name="duringRecovery">Called during recovery.</param> /// <returns>The value.</returns> /// <remarks> /// Reference Type Life Cycle /// At Recovery: [InUse = false, CanBeSweepedToDisk = true, Value = null] /// Read: [InUse = readMode == CacheResult] [Value = CacheResult?] [CanBeSweepedToDisk = value != null] /// /// Value Type Life Cycle /// At Recovery: [InUse = false, CanBeSweepedToDisk = true, Value = default(TValue)] /// First Read: [Value = CacheResult?] [InUse = true] [CanBeSweepedToDisk = false] /// </remarks> public virtual async Task <TValue> GetValueAsync( MetadataTable metadataTable, IStateSerializer <TValue> valueSerializer, bool isValueAReferenceType, ReadMode readMode, LoadValueCounter valueCounter, CancellationToken cancellationToken, string traceType, bool duringRecovery = false) { TValue value = this.Value; if (this.ShouldValueBeLoadedFromDisk(isValueAReferenceType, value, traceType) == false || readMode == ReadMode.Off) { return(value); } Diagnostics.Assert(duringRecovery == true || readMode != ReadMode.CacheResult || isValueAReferenceType == false || this.InUse == true, traceType, "If CacheResult, InUse must have been set."); value = await MetadataManager.ReadValueAsync <TValue>(metadataTable.Table, this, valueSerializer, cancellationToken, traceType).ConfigureAwait(false); // Value must be set before updating the flags. // Example problem: After recovery two reads on the same key, // T1 sees InUse (IsLoaded) == false, reads the value, updates InUse, *Context Switch* // T2 sees InUse (IsLoaded) == true, reads this.Value which has not been set by T1. if (this.ShouldCacheValue(readMode, isValueAReferenceType)) { this.Value = value; valueCounter.IncrementCounter(); } // Flags must always be updated. For value type, inUse (IsLoadedFromDiskAfterRecovery) must be set. this.UpdateFlagsFollowingLoadValue(isValueAReferenceType, value, readMode, traceType); return(value); }
/// <summary> /// Creates a snapshot component to snapshot reads for a given visibility lsn. /// </summary> public SnapshotComponent(SnapshotContainer <TKey, TValue, TKeyComparer, TKeyEqualityComparer> container, LoadValueCounter valueCounter, bool isValueAReferenceType, string traceType) { this.container = container; this.isValueAReferenceType = isValueAReferenceType; this.valueCounter = valueCounter; this.traceType = traceType; }
/// <summary> /// Constructor. /// </summary> public TDifferentialStoreComponent( ITransactionalReplicator transactionalReplicator, long stateProviderId, SnapshotContainer <TKey, TValue, TKeyComparer, TKeyEqualityComparer> snapshotContainer, LoadValueCounter loadValueCounter, bool isValueAReferenceType, string traceType) { this.traceType = traceType; this.transactionalReplicator = transactionalReplicator; this.stateProviderId = stateProviderId; this.snapshotContainer = snapshotContainer; this.component = new ConcurrentDictionary <TKey, DifferentialStateVersions <TValue> >(KeyEqualityComparer); this.addList = new AddList <TKey>(KeyComparer); this.isReadonly = false; this.isValueAReferenceType = isValueAReferenceType; this.loadValueCounter = loadValueCounter; }
public AsyncEnumerable( bool isValueAReferenceType, ReadMode readMode, IEnumerable <TKey> keyEnumerables, IReadableStoreComponent <TKey, TVersionedItem <TValue> > differentState, IReadableStoreComponent <TKey, TVersionedItem <TValue> > consolidatedState, MetadataTable currentMetadataTable, LoadValueCounter loadValueCounter, IStateSerializer <TValue> valueSerializer, string traceType) { this.traceType = traceType; this.isValueAReferenceType = isValueAReferenceType; this.readMode = readMode; this.keyEnumerable = keyEnumerables; this.differentState = differentState; this.consolidatedState = consolidatedState; this.currentMetadataTable = currentMetadataTable; this.loadValueCounter = loadValueCounter; this.valueSerializer = valueSerializer; this.isInvalidated = false; }
public override Task <TValue> GetValueAsync(FileMetadata fileMetadata, IStateSerializer <TValue> valueSerializer, bool isValueARefernceType, ReadMode readMode, LoadValueCounter valueCounter, CancellationToken cancellationToken, string traceType) { throw new InvalidOperationException(SR.Error_TDeletedItem_NoValue); }