コード例 #1
0
        public async Task SaveAsync(TKey key, TEntity entity)
        {
            var name = this.GetName(key);

            try
            {
                // This is fast and allows to have git-style subfolders in atomic strategy
                // to avoid NTFS performance degradation (when there are more than
                // 10000 files per folder). Kudos to Gabriel Schenker for pointing this out
                var subfolder = Path.GetDirectoryName(name);
                if (subfolder != null && !Directory.Exists(subfolder))
                {
                    Directory.CreateDirectory(subfolder);
                }

                // we are locking this file.
                using (var file = File.Open(name, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
                    // some serializers have nasty habbit of closing the
                    // underling stream
                    using (var mem = new MemoryStream())
                    {
                        this._strategy.Serialize(entity, mem);
                        var data = mem.ToArray();

                        StorageProfiler.CountWriteRequest(name);
                        // upload only if we changed
                        await file.WriteAsync(data, 0, data.Length);

                        // truncate this file
                        file.SetLength(data.Length);
                    }
            }
            catch (DirectoryNotFoundException)
            {
                var s = string.Format(
                    "Container '{0}' does not exist.",
                    this._folder);
                throw new InvalidOperationException(s);
            }
        }
コード例 #2
0
        public async Task <TEntity> AddOrUpdateAsync(TKey key, Func <TEntity> addFactory, Func <TEntity, TEntity> update, AddOrUpdateHint hint = AddOrUpdateHint.ProbablyExists)
        {
            var name = this.GetName(key);

            try
            {
                // This is fast and allows to have git-style subfolders in atomic strategy
                // to avoid NTFS performance degradation (when there are more than
                // 10000 files per folder). Kudos to Gabriel Schenker for pointing this out
                var subfolder = Path.GetDirectoryName(name);
                if (subfolder != null && !Directory.Exists(subfolder))
                {
                    Directory.CreateDirectory(subfolder);
                }

                // we are locking this file.
                using (var file = File.Open(name, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                {
                    var     initial = new byte[0];
                    TEntity result;
                    if (file.Length == 0)
                    {
                        result = addFactory();
                    }
                    else
                    {
                        using (var mem = new MemoryStream())
                        {
                            StorageProfiler.CountReadRequest(name);
                            await file.CopyToAsync(mem);

                            mem.Seek(0, SeekOrigin.Begin);
                            var entity = this._strategy.Deserialize <TEntity>(mem);
                            initial = mem.ToArray();
                            result  = update(entity);
                        }
                    }

                    // some serializers have nasty habbit of closing the
                    // underling stream
                    using (var mem = new MemoryStream())
                    {
                        this._strategy.Serialize(result, mem);
                        var data = mem.ToArray();

                        if (!data.SequenceEqual(initial))
                        {
                            StorageProfiler.CountWriteRequest(name);

                            // upload only if we changed
                            file.Seek(0, SeekOrigin.Begin);
                            await file.WriteAsync(data, 0, data.Length);

                            // truncate this file
                            file.SetLength(data.Length);
                        }
                    }

                    return(result);
                }
            }
            catch (DirectoryNotFoundException)
            {
                var s = string.Format(
                    "Container '{0}' does not exist.",
                    this._folder);
                throw new InvalidOperationException(s);
            }
        }