/// <summary>
 ///		Method called from <see cref="Write(IDataItem)"/>
 /// </summary>
 /// <param name="folder">
 ///		Repository folder into which new data item has been added
 /// </param>
 /// <param name="file">
 ///		The data file the data item is going to go to.
 /// </param>
 /// <param name="dataItem">
 ///		The new data item
 /// </param>
 protected virtual void OnDataItemAdded(IRepositoryFolder folder, IRepositoryFileName file, IDataItem dataItem)
 {
     if (!_itemAddedEvent.HasNoSubscribers)
     {
         _itemAddedEvent.Raise(this, new bfs.Repository.Events.DataItemAddedEventArgs(folder, file, dataItem));
     }
 }
Exemple #2
0
        /// <summary>
        ///		Find first leaf data [sub]folder and data file in it containing items dated at, earlier or later than the
        ///		<paramref name="seekTime"/>
        /// </summary>
        /// <param name="seekTime">
        ///		Specifies the start of date-time range (inclusive) to find data in
        /// </param>
        /// <param name="backwards">
        ///		To which side from <paramref name="seekTime"/> to look for data
        /// </param>
        /// <returns>
        ///		First (according to <paramref name="seekTime"/>) data file containing the required data;
        ///		<see langword="null"/> if none found
        /// </returns>
        public IRepositoryFile Seek(DateTime seekTime, bool backwards)
        {
            _log.DebugFormat("Seeking data folder for reader, descr: {0}"
                             , this.IsVirtualRoot ? "Virtual Root" : this._folderDescriptor.ToString());

            IRepositoryFileName dataFile = null;
            IRepositoryFile     retval   = null;

            if (IsLeafFolder)
            {
                LoadFiles(false);
                dataFile = _dataFileBrowser.GetFile(seekTime, backwards);
                if (null != dataFile)
                {
                    _log.DebugFormat("Seek found file: {0}", dataFile.FileName);
                    retval = GetContainedRepositoryFile(dataFile);
                }
            }
            else
            {
                LoadSubFolders(false);

                IDirectedEnumerable <IDataFolder> sequence = GetSubfoldersSequence(seekTime, backwards);

                for (
                    IEnumerator <IDataFolder> scanner = sequence.GetEnumerator();
                    scanner.MoveNext() && null == retval;
                    )
                {
                    retval = scanner.Current.Seek(seekTime, backwards);
                }
            }
            return(retval);
        }
        private IDataFileAccessor GetAccessor(IRepositoryFileName targetFile)
        {
            var retval = _targetFolder.Repository.ObjectFactory.GetDataFileAccessor(_currentFolder, targetFile);

            retval.Coder = Coder;
            retval.EqualTimestampItemsComparer = EqualTimestampedItemsComparer;
            return(retval);
        }
        /// <summary>
        ///		Create new instance.
        /// </summary>
        /// <param name="containingFolder">
        ///		Leaf data folder object reference, mandatory.
        /// </param>
        /// <param name="fileName">
        ///		Object representing data file name, optional.
        /// </param>
        public RepositoryFile(IDataFolder containingFolder, IRepositoryFileName fileName)
        {
            Check.DoRequireArgumentNotNull(containingFolder, "containingFolder");
            RepositoryFolder.CheckNotDetached(containingFolder.RepoFolder);

            ContainingFolder = containingFolder;
            Name             = fileName;
        }
Exemple #5
0
        /// <summary>
        ///		Get child data file next to the specified data file.
        /// </summary>
        /// <param name="file">
        ///		The data file which neighbour to find
        /// </param>
        /// <param name="backwards">
        ///		The direction in which to go from <paramref name="file"/>:
        ///		<see langword="true"/>: to the past
        ///		<see langword="false"/>: to the future
        /// </param>
        /// <returns>
        ///		Existing data file which is contained in this data folder or <see langword="null"/> if the sought data file
        ///		does not exist.
        /// </returns>
        /// <exception cref="InvalidOperationException">
        ///		This is not a leaf folder
        /// </exception>
        public IRepositoryFileName GetNextDataFile(IRepositoryFileName file, bool backwards)
        {
            Check.RequireLambda(IsLeafFolder, () => new InvalidOperationException("Operation not supported on non-leaf folders"));

            DateTime seekTime = backwards ? file.FirstItemTimestamp.AddTicks(-1) : file.End;

            return(_dataFileBrowser.GetFile(seekTime, backwards));
        }
Exemple #6
0
        /// <summary>
        ///		Create data file accessor instance.
        /// </summary>
        /// <param name="folder">
        ///		Data folder containig the file.
        /// </param>
        /// <param name="file">
        ///		Data file to be accessed; may not exist on disk.
        /// </param>
        /// <returns>
        ///		New <see cref="IDataFileAccessor"/> instance.
        /// </returns>
        public IDataFileAccessor GetDataFileAccessor(IDataFolder folder, IRepositoryFileName file)
        {
            Check.DoRequireArgumentNotNull(folder, "folder");
            Check.DoRequireArgumentNotNull(file, "file");
            RepositoryFolder.CheckNotDetached(folder.RepoFolder);

            return(new RepositoryFileAccessor(folder, file));
        }
 /// <summary>
 ///		Discarding changes if dirty. Call <see cref="Flush"/> to save changes.
 /// </summary>
 public void Close()
 {
     FirstItemTimestamp = DateTime.MaxValue;
     LastItemTimestamp  = DateTime.MinValue;
     _existinglFilePath = null;
     _dataItems         = null;
     _dataFolder        = null;
     _repoFile          = null;
 }
Exemple #8
0
 /// <summary>
 ///     Create and initialize new instance.
 /// </summary>
 /// <param name="folder">
 ///     Repository folder to which a new data item has been added.
 /// </param>
 /// <param name="file">
 ///     Repository file to which a new data item has been added.
 /// </param>
 /// <param name="dataItem">
 ///     Newly added data item.
 /// </param>
 public DataItemAddedEventArgs(
     IRepositoryFolder folder
     , IRepositoryFileName file
     , IDataItem dataItem)
 {
     this.Folder   = folder;
     this.File     = file;
     this.DataItem = dataItem;
 }
Exemple #9
0
        /// <summary>
        ///		Get data files around the specified item timestamp
        /// </summary>
        /// <param name="itemTimestamp">
        ///		The data item timestamp
        /// </param>
        /// <param name="predecessor">
        ///		The file if any which ends before the specified timestamp
        /// </param>
        /// <param name="owner">
        ///		The file covering the specified item timestamp
        /// </param>
        /// <param name="successor">
        ///		The file which starts after the specified timestamp
        /// </param>
        public void GetDataFiles(DateTime itemTimestamp
                                 , out IRepositoryFileName predecessor
                                 , out IRepositoryFileName owner
                                 , out IRepositoryFileName successor)
        {
            Check.Require(_container.Start <= itemTimestamp && _container.End > itemTimestamp);

            _files.GetItems(itemTimestamp, out predecessor, out owner, out successor);
        }
 /// <summary>
 ///		Create accessor for a file and retrieve compressor from repository's
 ///		object factory by the file extension
 /// </summary>
 /// <param name="folder">
 ///		Containing repo folder
 /// </param>
 /// <param name="repoFile">
 ///		Target data file, optional.
 /// </param>
 /// <param name="dataFolder">
 ///		Leaf data folder containing <paramref name="repoFile"/>
 /// </param>
 /// <param name="equalTimestampedItemsComparer">
 ///		Comparer for data items with equal timestamps, optional.
 /// </param>
 internal RepositoryFileAccessor(
     IFolder folder
     , IRepositoryFileName repoFile
     , IDataFolder dataFolder
     , IComparer <IDataItem> equalTimestampedItemsComparer)
     : this(dataFolder, repoFile
            , folder.Repository.ObjectFactory.GetCompressor(repoFile.CompressorCode)
            , equalTimestampedItemsComparer)
 {
 }
Exemple #11
0
        private IRepositoryFile GetContainedRepositoryFile(IRepositoryFileName fileName)
        {
            IRepositoryFile retval = null;

            if (null != fileName)
            {
                retval = new RepositoryFile(containingFolder: this, fileName: fileName);
            }
            return(retval);
        }
Exemple #12
0
 /// <summary>
 ///		Handle creation, renaming, or deletion of any file belonging to this container
 /// </summary>
 /// <param name="firstItemTimestamp">
 ///		First item timestamp before the change; use <see cref="DateTime.MinValue"/> to handle creation
 /// </param>
 /// <param name="newFileName">
 ///		File name after the change; use <see langword="null"/> to handle deletion
 /// </param>
 /// <remarks>
 ///
 /// </remarks>
 private void HandleFileChanged(DateTime firstItemTimestamp, IRepositoryFileName newFileName)
 {
     if (firstItemTimestamp != DateTime.MinValue)
     {
         bool removed = DeleteFile(firstItemTimestamp);
     }
     if (newFileName != null)
     {
         AddFile(newFileName);
     }
 }
Exemple #13
0
        /// <summary>
        ///		Not thread-safe
        /// </summary>
        private void AddFile(IRepositoryFileName file)
        {
            RequireFileValid(file);

            try
            {
                // overlapping and duplicates handled inside Add
                _files.Add(file);
            }
            catch (OverlappingRangesException e)
            {
                throw new OverlappingFileInContainer(e, _container.RelativePath);
            }
        }
Exemple #14
0
        public void Refresh()
        {
            string dirPath             = this.FullPath;
            IEnumerable <string> files =
                _folder.Repository.ObjectFactory.FileSystemProvider.DirectoryProvider.EnumerateFiles(dirPath, "*");

            _files = new IndexedRangeTreeDictionary <DateTime, IRepositoryFileName>(f => f.FirstItemTimestamp, f => f.End);

            foreach (string filePath in files)
            {
                IRepositoryFileName repoFile =
                    _folder.Repository.ObjectFactory.GetFileDescriptor(System.IO.Path.GetFileName(filePath));
                if (null != repoFile)
                {
                    AddFile(repoFile);
                }
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="dataFolder">
        ///		Leaf data folder in which the data files will be accessed.
        /// </param>
        /// <param name="repoFile">
        ///		Target repo file, optional. New instance will be created using object factory if null is supplied.
        /// </param>
        /// <param name="coder">
        ///		Compressor instance
        /// </param>
        /// <param name="equalTimestampedItemsComparer">
        ///		Comparer to use when sorting data items for items with equal timestamps.
        ///		When timestamps are not equal the comparer has no effect.
        /// </param>
        internal RepositoryFileAccessor(
            IDataFolder dataFolder
            , IRepositoryFileName repoFile
            , ICoder coder
            , IComparer <IDataItem> equalTimestampedItemsComparer)
        {
            Check.DoRequireArgumentNotNull(dataFolder, "dataFolder");
            Check.DoRequireArgumentNotNull(repoFile, "repoFile");
            Check.DoRequireArgumentNotNull(coder, "coder");
            RepositoryFolder.CheckNotDetached(dataFolder.RepoFolder);

            _folder     = dataFolder.RepoFolder;
            _repoFile   = repoFile;
            _dataFolder = dataFolder;

            if (_repoFile == null)
            {
                _repoFile = _folder.Repository.ObjectFactory.CreateNewFile(_folder);
            }
            this.Coder = coder;

            if (repoFile.Encrypted)
            {
                this.Encryptor = _folder.Repository.ObjectFactory.GetEncryptor(repoFile.EncryptorCode);
            }

            if (_folder.Repository.ObjectFactory.FileSystemProvider.FileProvider.Exists(this.FilePath))
            {
                _existinglFilePath = this.FilePath;
            }
            else
            {
                _dataItems = new List <IDataItem>();
            }
            _isSorted = true;
            this.EqualTimestampItemsComparer = equalTimestampedItemsComparer;

            FirstItemTimestamp = DateTime.MaxValue;
            LastItemTimestamp  = DateTime.MinValue;
        }
        /// <summary>
        ///		Get next data file in the same repo folder.
        /// </summary>
        /// <param name="backwards">
        ///		The direction in which to look for data file relative to this file: to the past or to the future
        /// </param>
        /// <returns>
        ///		Next data file or <see langword="null"/> if none exists.
        /// </returns>
        public IRepositoryFile GetNext(bool backwards)
        {
            IRepositoryFile retval = null;

            IRepositoryFileName fileInSameFolder = ContainingFolder.GetNextDataFile(this.Name, backwards);

            if (null != fileInSameFolder)
            {
                retval = new RepositoryFile(containingFolder: ContainingFolder, fileName: fileInSameFolder);
            }
            else
            {
                // scanning sibling leaf folders until first data file is found
                for (
                    IDataFolder nextFolder = ContainingFolder.GetNextSiblingInTree(backwards);
                    nextFolder != null && retval == null;
                    nextFolder = nextFolder.GetNextSiblingInTree(backwards))
                {
                    retval = nextFolder.FindFirstDataFile(backwards);
                }
            }

            return(retval);
        }
Exemple #17
0
 private static int CompareFiles(IRepositoryFileName file1, IRepositoryFileName file2)
 {
     return(DateTime.Compare(file1.FirstItemTimestamp, file2.FirstItemTimestamp));
 }
Exemple #18
0
 private void RequireFileValid(IRepositoryFileName file)
 {
     Util.Check.RequireArgumentNotNull(file, "file");
     Util.Check.RequireLambda(file.FirstItemTimestamp <= file.LastItemTimestamp, () => StorageResources.InvalidFileNamingFirstLast);
 }
Exemple #19
0
 /// <summary>
 ///		Notify container that a file was changed
 /// </summary>
 /// <param name="firstItemTimestamp">
 ///		The timestamp of the file as it has been known to the container
 ///		(the value before the change happened)
 /// </param>
 /// <param name="newFileName">
 ///		New file name
 /// </param>
 /// <exception cref="FileContainerNotificationException">
 ///		The file cannot be found in the container; possible concurrency issue
 /// </exception>
 /// <exception cref="OverlappingFileInContainer">
 ///		The <paramref name="newRepoFile"/> overlaps with an existing file; possible concurrency issue or internal error.
 /// </exception>
 public void FileChanged(DateTime firstItemTimestamp, IRepositoryFileName newFileName)
 {
     FileDeleted(firstItemTimestamp);
     FileAdded(newFileName);
 }
Exemple #20
0
 /// <summary>
 ///		Perform necessary operations after a new file has been added to the container.
 /// </summary>
 /// <param name="newRepoFile">
 ///		New file added to the container
 /// </param>
 /// <exception cref="OverlappingFileInContainer">
 ///		The <paramref name="newRepoFile"/> overlaps with an existing file; possible concurrency issue or internal error.
 /// </exception>
 public void FileAdded(IRepositoryFileName newRepoFile)
 {
     AddFile(newRepoFile);
 }
Exemple #21
0
 public SeekFileResult(DateTime seekTime, IDataFolder foundFolder, IRepositoryFileName foundFile)
 {
     this.SeekDateTime   = seekTime;
     this.RepositoryFile = new RepositoryFile(containingFolder: foundFolder, fileName: foundFile);
 }
 public void DeleteFile(IRepositoryFileName file)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 ///		Create new instance.
 /// </summary>
 /// <param name="folder">
 ///		Data folder where file will be stored.
 /// </param>
 /// <param name="file">
 ///		File name instance, optional.
 /// </param>
 /// <remarks>
 ///		If <paramref name="file"/> is not supplied new instance will be created using the object factory (<see cref="IRepository.ObjectFactory"/>).
 ///		Coder and encryptor will be set from the object factory as well. They may be overridden afterwards.
 /// </remarks>
 public RepositoryFileAccessor(IDataFolder folder, IRepositoryFileName file)
     : this(folder : folder.RepoFolder, repoFile : file, dataFolder : folder, equalTimestampedItemsComparer : null)
 {
 }
Exemple #24
0
 /// <summary>
 ///		Get full path of the contained data file
 /// </summary>
 /// <param name="file">
 /// </param>
 /// <returns>
 /// </returns>
 /// <remarks>
 ///		This must be a leaf folder
 /// </remarks>
 private string GetDataFilePath(IRepositoryFileName file)
 {
     Check.Require(IsLeafFolder);
     return(Path.Combine(FullPath, file.FileName));
 }