Exemplo n.º 1
0
 /// <summary>Ctor.</summary>
 /// <param name="name">variable name</param>
 /// <param name="initialVersion">first version number</param>
 /// <param name="initialValue">first value</param>
 /// <param name="timestamp">timestamp of first version</param>
 /// <param name="millisecondLifetimeOldVersions">
 /// number of milliseconds after which older versions get expired and removed
 /// </param>
 /// <param name="readLock">for coordinating Update to old versions</param>
 /// <param name="highWatermark">
 /// when the number of old versions reached high watermark, the list inspects size on every write
 /// </param>
 /// <param name="errorWhenNotFound">
 /// true if an exception should be throw if the requested version cannot be found,
 /// or false if the engine should log a warning
 /// </param>
 public VersionedValueList(String name, int initialVersion, T initialValue, long timestamp, long millisecondLifetimeOldVersions, ILockable readLock, int highWatermark, bool errorWhenNotFound)
 {
     _name              = name;
     _readLock          = readLock;
     _highWatermark     = highWatermark;
     _olderVersions     = new List <VersionedValue <T> >();
     _errorWhenNotFound = errorWhenNotFound;
     _millisecondLifetimeOldVersions = millisecondLifetimeOldVersions;
     _currentAndPriorValue           = new CurrentValue <T>(new VersionedValue <T>(initialVersion, initialValue, timestamp),
                                                            new VersionedValue <T>(-1, null, timestamp));
 }
Exemplo n.º 2
0
        /// <summary>
        /// Add a value and version to the list, returning the prior value of the variable.
        /// </summary>
        /// <param name="version">for the value to add</param>
        /// <param name="value">to add</param>
        /// <param name="timestamp">the time associated with the version</param>
        /// <returns>prior value</returns>
        public Object AddValue(int version, T value, long timestamp)
        {
            if (ExecutionPathDebugLog.IsEnabled && Log.IsDebugEnabled)
            {
                Log.Debug(".addValue Thread " + Thread.CurrentThread.ManagedThreadId + " for '" + _name + "' adding version " + version + " at value " + value);
            }

            // push to prior if not already used
            if (_currentAndPriorValue.PriorVersion.Version == -1)
            {
                _currentAndPriorValue = new CurrentValue <T>(new VersionedValue <T>(version, value, timestamp),
                                                             _currentAndPriorValue.CurrentVersion);
                return(_currentAndPriorValue.PriorVersion.Value);
            }

            // add to list
            VersionedValue <T> priorVersion = _currentAndPriorValue.PriorVersion;

            _olderVersions.Add(priorVersion);

            // check watermarks
            if (_olderVersions.Count >= _highWatermark)
            {
                long expireBefore = timestamp - _millisecondLifetimeOldVersions;
                while (_olderVersions.Count > 0)
                {
                    VersionedValue <T> oldestVersion = _olderVersions[0];
                    if (oldestVersion.Timestamp <= expireBefore)
                    {
                        _olderVersions.RemoveAt(0);
                    }
                    else
                    {
                        break;
                    }
                }
            }

            _currentAndPriorValue = new CurrentValue <T>(new VersionedValue <T>(version, value, timestamp),
                                                         _currentAndPriorValue.CurrentVersion);
            return(_currentAndPriorValue.PriorVersion.Value);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Retrieve a value for the given version or older then then given version.
        /// <para/>
        /// The implementaton only locks the read lock if an older version the the prior version is requested.
        /// </summary>
        /// <param name="versionAndOlder">the version we are looking for</param>
        /// <returns>
        /// value for the version or the next older version, ignoring newer versions
        /// </returns>
        public T GetVersion(int versionAndOlder)
        {
            if (ExecutionPathDebugLog.IsEnabled && Log.IsDebugEnabled)
            {
                Log.Debug(".GetVersion Thread " + Thread.CurrentThread.ManagedThreadId + " for '" + _name + "' retrieving version " + versionAndOlder + " or older");
            }

            T resultValue            = null;
            CurrentValue <T> current = _currentAndPriorValue;

            if (current.CurrentVersion.Version <= versionAndOlder)
            {
                resultValue = current.CurrentVersion.Value;
            }
            else if ((current.PriorVersion.Version != -1) &&
                     (current.PriorVersion.Version <= versionAndOlder))
            {
                resultValue = current.PriorVersion.Value;
            }
            else
            {
                using (_readLock.Acquire())
                {
                    current = _currentAndPriorValue;

                    if (current.CurrentVersion.Version <= versionAndOlder)
                    {
                        resultValue = current.CurrentVersion.Value;
                    }
                    else if ((current.PriorVersion.Version != -1) &&
                             (current.PriorVersion.Version <= versionAndOlder))
                    {
                        resultValue = current.PriorVersion.Value;
                    }
                    else
                    {
                        bool found = false;
                        for (int i = _olderVersions.Count - 1; i >= 0; i--)
                        {
                            VersionedValue <T> entry = _olderVersions[i];
                            if (entry.Version <= versionAndOlder)
                            {
                                resultValue = entry.Value;
                                found       = true;
                                break;
                            }
                        }

                        if (!found)
                        {
                            int currentVersion = current.CurrentVersion.Version;
                            int priorVersion   = current.PriorVersion.Version;
                            int?oldestVersion  = null;
                            if (_olderVersions.Count > 0)
                            {
                                oldestVersion = _olderVersions[0].Version;
                            }

                            T oldestValue = (_olderVersions.Count > 0) ? _olderVersions[0].Value : null;

                            String text = "Variables value for version '" + versionAndOlder +
                                          "' and older could not be found" +
                                          " (currentVersion=" + currentVersion + " priorVersion=" + priorVersion +
                                          " oldestVersion=" + oldestVersion + " numOldVersions=" + _olderVersions.Count +
                                          " oldestValue=" + oldestValue + ")";
                            if (_errorWhenNotFound)
                            {
                                throw new IllegalStateException(text);
                            }
                            Log.Warn(text);
                            return(current.CurrentVersion.Value);
                        }
                    }
                }
            }

            if (ExecutionPathDebugLog.IsEnabled && Log.IsDebugEnabled)
            {
                Log.Debug(".getVersion Thread " + Thread.CurrentThread.ManagedThreadId + " for '" + _name + " version " + versionAndOlder + " or older result is " + resultValue);
            }

            return(resultValue);
        }