/// <summary> /// Seek with position not loading data immediately. /// </summary> /// <param name="position"> /// The position to restore /// </param> /// <returns> /// Success boolean flag; whether a data file to be read was found. It may not be exact match for the position, however. /// </returns> /// <remarks> /// The position is saved and completely restored when <see cref="LoadNextFile"/> is called; issues are reported /// via <see cref="IRepositoryReader.SeekStatusCallback"/>, success is not reported, only warnings /// , <see cref="FolderSeekStatus.PositionStatus"/>. /// Note that you cannot change reading direction after the call to this method until you load the file and restore /// the reading position. /// </remarks> public bool SeekDataFile(IFolderReadingPosition position) { // save position copy _position.FromSeek(position); bool retval = null != _fileIterator.Seek(position.Time, Backwards); if (position.IsExact && (!retval || !_fileIterator.Current.Name.IsCovering(position.Time))) { _log.WarnFormat("Seek on folder {0} have not found data file containing item referenced in the position: {1}" , position.FolderKey , position.Time); MasterReader.SeekStatusCallback(new FolderSeekStatus(TargetFolder.FolderKey, FolderSeekStatus.PositionStatus.FileNotFound)); } if (retval) { DateTime firstTimeInFile = _getFirstItemToReadFromFileName(NextDataFile.Name); if (_timeComparison.Compare(position.Time, firstTimeInFile) > 0) { // file starts before the seek time, so will need to skip some items in it firstTimeInFile = _position.Time; } NextFileFirstTimestampToRead = firstTimeInFile; } WasPositioned = true; LastSeekTime = position.Time; SoughtFileLoaded = false; return(retval); }
/// <summary> /// Update this position with another reading position (<see cref="IRepositoryReader.Seek(IFolderReadingPosition)"/>) /// </summary> /// <param name="position"> /// Position used in <see cref="IRepositoryReader.Seek(IFolderReadingPosition)"/> /// </param> public void FromSeek(IFolderReadingPosition position) { this.FolderKey = position.FolderKey; this.NumberOfItemsWithTheTimestampRead = position.NumberOfItemsWithTheTimestampRead; this.Time = position.Time; this.VerificationLastReadItemHash = position.VerificationLastReadItemHash; }
/// <summary> /// Add folder to read and optionally prepare it for reading /// </summary> /// <param name="folder"> /// Folder to add /// </param> /// <param name="position"> /// <see langword="null"/> means do not prepare it for reading /// </param> /// <returns> /// <see langword="false"/> - the folder is already being read /// <see langword="true"/> otherwise /// </returns> /// <remarks> /// If reader has data (<see cref="HasData"/>) <paramref name="position"/> must have value /// </remarks> private bool AddFolderImpl(IRepositoryFolder folder, IFolderReadingPosition position) { Check.RequireArgumentNotNull(folder, "folder"); IFolder folderTyped = RepositoryFolder.CastFolder(folder); Check.Require(object.ReferenceEquals(folder.Repository, Repository)); Check.Require(!HasData || position != null, "If we have data we cannot leave a reader unpositioned"); if (IsAccessing(folder, false)) { return(false); } Check.Require(!_position.FolderPositions.ContainsKey(folder.FolderKey) , "Folder position found in repository reader position for a folder not being read"); RepositoryFolderReader reader = new RepositoryFolderReader(folderTyped, this); reader.Direction = this.Direction; _readers.Add(folder.FolderKey, reader); if (position != null) { SeekFolderReader(reader, position); } return(true); }
/// <summary> /// Add folder and restore its reading position. Folder is identified by its <see cref="IRepositoryFolder.FolderKey"/> /// , which is specified by <see cref="IFolderReadingPosition.FolderKey"/> /// </summary> /// <param name="folderPosition"> /// Folder reading position /// </param> /// <returns> /// <see langword="true"/> - success /// <see langword="false"/> - folder is already being read /// </returns> /// <exception cref="ObjectDisposedException"> /// The reader has been disposed. /// </exception> public bool AddFolder(IFolderReadingPosition folderPosition) { CheckNotDisposed(); Check.DoRequireArgumentNotNull(folderPosition, "folderPosition"); IRepositoryFolder folder = Repository.RootFolder.GetDescendant(folderPosition.FolderKey, false); Check.DoAssertLambda(folder != null , () => new ArgumentException(string.Format(StorageResources.FolderNotFound, folderPosition.FolderKey))); return(AddFolderImpl(folder, folderPosition)); }
/// <summary> /// Initiate reading from the <paramref name="reader"/>. /// It must not be in any of the 2 queues (online, offline) or exhausted list. /// If the file contains data since <paramref name="seekTime"/> the reader will /// be placed into offline queue. Otherwise it will go into exhausted readers list. /// </summary> /// <param name="reader"> /// Reader to initiate. It must not be in any of the 2 queues (online, offline) or exhausted list. /// </param> /// <param name="position"> /// Position to start reading from. /// </param> /// <remarks> /// The method ensures that currently loaded reader's data is unloaded first. /// Seeking is done lazily - all go to offline queue and loaded immediately /// before reading. /// </remarks> private void SeekFolderReader(RepositoryFolderReader reader, IFolderReadingPosition position) { Check.RequireArgumentNotNull(position, "position"); Check.RequireArgumentNotNull(reader, "reader"); Check.Require(!_offlineQueue.Contains(reader) && !_exhaustedReaders.Contains(reader) && !_onlineQueue.Contains(reader)); reader.Unload(); reader.SeekDataFile(position); AddPositionedOfflineReaderToAQueue(reader); // as reader.Position is singleton, changes to the reader's position do not require modifying _position _position.SetFolderPosition(reader.Position); }
/// <summary> /// Create new instance and populate it with existing position data. /// </summary> /// <param name="position"> /// Position to copy /// </param> public FolderReadingPositionMock(IFolderReadingPosition position) { FromSeek(position); }
public bool AddFolder(IFolderReadingPosition folderPosition) { throw new NotImplementedException(); }
/// <summary> /// Remove the specific folder reading position from this position. /// </summary> /// <param name="position"> /// Specific folder reading position. /// </param> /// <returns> /// true - the specific folder position was removed from this position /// false - this position does not contain specific position with folder key equal to <code>position.FolderKey</code> /// </returns> public bool Remove(IFolderReadingPosition position) { Check.DoRequireArgumentNotNull(position, "position"); return(_positionsDictionary.Remove(position.FolderKey)); }
/// <summary> /// Set contained folder position. /// </summary> /// <param name="position"> /// IFolderReadingPosition instance /// </param> public void SetFolderPosition(IFolderReadingPosition position) { Check.DoRequireArgumentNotNull(position, "position"); _positionsDictionary[position.FolderKey] = position; }
/// <summary> /// Add folder reading position /// </summary> /// <param name="position"> /// Folder reading position to add /// </param> /// <exception cref="Util.PreconditionException"> /// Position for the folder referenced by <paramref name="position"/> already exists. /// </exception> public void Add(IFolderReadingPosition position) { Check.DoRequire(!ContainsPosition(position.FolderKey), StorageResources.PositionForFolderAlreadyExists); _positionsDictionary.Add(position.FolderKey, position); }