Exemplo n.º 1
0
        /// <summary>
        /// Gets or Adds a snapshot component for a visibility lsn.
        /// </summary>
        public SnapshotComponent <TKey, TValue, TKeyComparer, TKeyEqualityComparer> GetOrAdd(
            long key, SnapshotComponent <TKey, TValue, TKeyComparer, TKeyEqualityComparer> value)
        {
            var result = this.container.GetOrAdd(key, value);

            return(result);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Removes the given key.
        /// </summary>
        /// <param name="key"></param>
        public void Remove(long key)
        {
            SnapshotComponent <TKey, TValue, TKeyComparer, TKeyEqualityComparer> value = null;
            var result = this.container.TryRemove(key, out value);

            Diagnostics.Assert(result, this.traceType, "SnapshotComponent should be removed.");

            // Remove the file metadata table from the lsn map.
            ConcurrentDictionary <uint, FileMetadata> fileMetadataTable = null;

            if (this.FileMetadataTableLsnMap.TryRemove(key, out fileMetadataTable))
            {
                // Acquire reader lock before trying to remove checkpoint file
                checkpointFileDeleteLock.EnterReadLock();

                try
                {
                    // Decrement ref on each file metadata.
                    foreach (var item in fileMetadataTable)
                    {
                        var metadata = item.Value;
                        metadata.ReleaseRef();
                    }
                }
                finally
                {
                    checkpointFileDeleteLock.ExitReadLock();
                }
            }
        }
        /// <summary>
        /// Adds a new entry to this store component.
        /// </summary>
        /// <devnote>
        /// Consolidated Manager is only required for the AddList feature.
        /// </devnote>
        public void Add(TKey key, TVersionedItem <TValue> value, IReadableStoreComponent <TKey, TVersionedItem <TValue> > consolidationManager)
        {
            bool isInReadOnlyMode = Volatile.Read(ref this.isReadonly);

            Diagnostics.Assert(isInReadOnlyMode == false, this.traceType, "Write operation cannot come after the differential has become readonly.");

            var concurrentDictionary = this.component as ConcurrentDictionary <TKey, DifferentialStateVersions <TValue> >;

            Diagnostics.Assert(concurrentDictionary != null, this.traceType, "write operation came after becoming readonly.");

            var differentialVersions = concurrentDictionary.GetOrAdd(key, k => new DifferentialStateVersions <TValue>());

            if (differentialVersions.CurrentVersion == null)
            {
                Diagnostics.Assert(differentialVersions.PreviousVersion == null, this.traceType, "previous version should be null");
                differentialVersions.CurrentVersion = value;
                if (value.Kind == RecordKind.InsertedVersion)
                {
                    Diagnostics.Assert(
                        (differentialVersions.flags & DifferentialStateFlags.NewKey) == DifferentialStateFlags.None,
                        this.traceType,
                        "DifferentialStateFlags.NewKey is already set");
                    differentialVersions.flags |= DifferentialStateFlags.NewKey;
                }
            }
            else
            {
                // Assert that version sequence number is lesser or equal compared to the new one.
                // Sequence number can be equal if the same key gets updated multiple times in the same transaction.
                if (differentialVersions.CurrentVersion.VersionSequenceNumber > value.VersionSequenceNumber)
                {
                    var message = string.Format(@"New lsn {0} should be greater than or equal the existing current lsn {1}. 
This error could be caused by an incorrect implementation of key comparer or key serializer. 
Please check your implementation of IEquatable, IComparable, and custom serializer (if applicable).",
                                                value.VersionSequenceNumber, differentialVersions.CurrentVersion.VersionSequenceNumber);

                    FabricEvents.Events.StoreDiagnosticError(this.traceType, message);
                    Diagnostics.Assert(
                        false,
                        this.traceType,
                        message);
                }

                if (differentialVersions.CurrentVersion.VersionSequenceNumber == value.VersionSequenceNumber)
                {
                    // Set the latest value in case there are multiple updates in the same transaction(same lsn).
                    differentialVersions.CurrentVersion = value;
                    this.UpdateAddList(key, value, consolidationManager);
                    return;
                }

                // Check if previous version is null
                if (differentialVersions.PreviousVersion == null)
                {
                    differentialVersions.PreviousVersion = differentialVersions.CurrentVersion;
                    differentialVersions.CurrentVersion  = value;
                }
                else
                {
                    // Move to snapshot container, if needed.
                    var removeVersionResult = this.transactionalReplicator.TryRemoveVersion(
                        this.stateProviderId,
                        differentialVersions.PreviousVersion.VersionSequenceNumber,
                        differentialVersions.CurrentVersion.VersionSequenceNumber);

                    if (!removeVersionResult.CanBeRemoved)
                    {
                        var enumerationSet = removeVersionResult.EnumerationSet;

                        foreach (var snapshotVisibilityLsn in enumerationSet)
                        {
                            var snapshotComponent = this.snapshotContainer.Read(snapshotVisibilityLsn);

                            if (snapshotComponent == null)
                            {
                                snapshotComponent = new SnapshotComponent <TKey, TValue, TKeyComparer, TKeyEqualityComparer>(this.snapshotContainer, this.loadValueCounter, this.isValueAReferenceType, this.traceType);
                                snapshotComponent = this.snapshotContainer.GetOrAdd(snapshotVisibilityLsn, snapshotComponent);
                            }

                            snapshotComponent.Add(key, differentialVersions.PreviousVersion);
                        }

                        // Wait on notifications and remove the entry from the container
                        if (removeVersionResult.EnumerationCompletionNotifications != null)
                        {
                            foreach (var enumerationResult in removeVersionResult.EnumerationCompletionNotifications)
                            {
                                enumerationResult.Notification.ContinueWith(x => { this.snapshotContainer.Remove(enumerationResult.VisibilitySequenceNumber); })
                                .IgnoreExceptionVoid();
                            }
                        }
                    }

                    // Remove from differential state
                    differentialVersions.PreviousVersion = differentialVersions.CurrentVersion;
                    differentialVersions.CurrentVersion  = value;
                }
            }

            this.UpdateAddList(key, value, consolidationManager);
        }