/// <summary> /// <see cref="IRepositoryReader.RemoveFolder"/> /// </summary> /// <exception cref="ObjectDisposedException"> /// The reader has been disposed. /// </exception> public void RemoveFolder(IRepositoryFolder folder) { CheckNotDisposed(); Util.Check.DoRequireArgumentNotNull(folder, "folder"); Exceptions.DifferentRepositoriesExceptionHelper.Check(folder.Repository, Repository); RepositoryFolderReader reader = GetExistingReader(folder.FolderKey); Util.Check.DoRequire(reader != null, "The folder is not being read by the reader"); _position.Remove(reader.Position); reader.Unload(); bool topReaderRemoved = this.HasData && TopReader == reader; bool success = !(!_exhaustedReaders.Remove(reader) && !_offlineQueue.Remove(reader) && !_onlineQueue.Remove(reader)); Util.Check.Ensure(success, "Internal error: reader not found."); success = _readers.Remove(folder.FolderKey); Util.Check.Ensure(success); if (topReaderRemoved) { SyncOfflineQueueForReading(); } Invariant(); }
/// <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> /// Add the specified reader to the offline queue /// </summary> /// <param name="reader"> /// The reader to add. Its <see cref="RepositoryFolderReader.NextFileFound"/> /// must equal <see langword="true"/>. /// </param> private void AddReaderToOfflineQueue(RepositoryFolderReader reader) { Util.Check.Require(reader.NextFileFound, "Internal error: reader unsuitable for offline queue"); // free memory reader.Unload(); LinkedListNode <RepositoryFolderReader> predecessor = null; if (_offlineQueue.Count > 0) { predecessor = FindPredecessorInQueue(_offlineQueue.First, reader, _offlineReaderComparer); } if (null == predecessor) { _offlineQueue.AddFirst(reader); } else { _offlineQueue.AddAfter(predecessor, reader); } }
private void AddToExhaustedImpl(RepositoryFolderReader reader) { reader.Unload(); _exhaustedReaders.AddLast(reader); }