public long TryAppend(byte[] buffer, TapeAppendCondition condition) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (buffer.Length == 0) { throw new ArgumentException("Buffer must contain at least one byte."); } using (var file = OpenForWrite()) { // we need to know version first. file.Seek(0, SeekOrigin.End); var version = TapeStreamSerializer.ReadVersionFromTheEnd(file); if (!condition.Satisfy(version)) { return(0); } var versionToWrite = version + 1; TapeStreamSerializer.WriteRecord(file, buffer, versionToWrite); return(versionToWrite); } }
public bool AppendNonAtomic(IEnumerable <byte[]> records, TapeAppendCondition condition = default(TapeAppendCondition)) { if (records == null) { throw new ArgumentNullException("records"); } return(Write(w => { var version = w.IndexWriter.BaseStream.Position / sizeof(long); if (!condition.Satisfy(version)) { return false; } var recordsArray = records.ToArray(); if (version > long.MaxValue - 1) { throw new IndexOutOfRangeException("Version is more than long.MaxValue."); } Append(w, recordsArray, version + 1); return true; })); }
static long TryAppendInternal(Writers writers, byte[] buffer, TapeAppendCondition condition) { var version = writers.IndexWriter.BaseStream.Position / sizeof(long); if (!condition.Satisfy(version)) { return(0); } if (version > long.MaxValue - 1) { throw new IndexOutOfRangeException("Version is more than long.MaxValue."); } Append(writers, new[] { buffer }, version + 1); return(version + 1); }
public long TryAppend(byte[] buffer, TapeAppendCondition appendCondition = new TapeAppendCondition()) { if (buffer == null) throw new ArgumentNullException("buffer"); if (buffer.Length == 0) throw new ArgumentException("Buffer must contain at least one byte."); long version; int lastBlockSize; long offset; long firstVersion; long count; List<string> blockNames; var blob = _container.GetBlockBlobReference(_blobName); if (blob.Exists()) { var blockList = blob.DownloadBlockList().ToArray(); blockNames = blockList.Select(bl => bl.Name).ToList(); var lastBlock = blockList.LastOrDefault(); if (default(ListBlockItem) == lastBlock) { version = 0; lastBlockSize = int.MaxValue; offset = 0; firstVersion = 1; count = 0; } else { var nameInfo = Naming.GetInfo(DecodeName(lastBlock.Name)); firstVersion = nameInfo.FirstVersion; version = nameInfo.FirstVersion - 1 + nameInfo.Count; count = nameInfo.Count; if (lastBlock.Size > int.MaxValue) throw new InvalidOperationException("last block size must be in 'int' range"); lastBlockSize = (int) lastBlock.Size; offset = blockList.Reverse().Skip(1).Sum(l => l.Size); } } else { version = 0; lastBlockSize = int.MaxValue; offset = 0; firstVersion = 1; count = 0; blockNames = new List<string>(); } if (!appendCondition.Satisfy(version)) return 0; if (version > long.MaxValue - 1) throw new IndexOutOfRangeException("Version is more than long.MaxValue."); if (buffer.Length > FourMb) throw new ArgumentException("buffer size must be less than or equal to 4 Mb", "buffer"); using (var outStream = new MemoryStream()) { if (buffer.Length < MaxBlockSize && lastBlockSize <= MaxBlockSize - buffer.Length) { // read old block using (var s = blob.OpenRead()) { s.Seek(offset, SeekOrigin.Begin); s.CopyTo(outStream); TapeStreamSerializer.WriteRecord(outStream, buffer, version + 1); count++; blockNames.RemoveAt(blockNames.Count - 1); } } else { TapeStreamSerializer.WriteRecord(outStream, buffer, version + 1); firstVersion = version + 1; count = 1; } var blockId = EncodeName(Naming.GetName(firstVersion, count)); string md5Hash; outStream.Seek(0, SeekOrigin.Begin); using (var md5 = MD5.Create()) { md5Hash = Convert.ToBase64String(md5.ComputeHash(outStream)); } outStream.Seek(0, SeekOrigin.Begin); blob.PutBlock(blockId, outStream, md5Hash); blockNames.Add(blockId); blob.PutBlockList(blockNames); return version+1; } }
public bool TryAppend(byte[] buffer, TapeAppendCondition condition) { if (buffer == null) throw new ArgumentNullException("buffer"); if (buffer.Length == 0) throw new ArgumentException("Buffer must contain at least one byte."); using (var file = OpenForWrite()) { // we need to know version first. file.Seek(0, SeekOrigin.End); var version = TapeStreamSerializer.ReadVersionFromTheEnd(file); if (!condition.Satisfy(version)) return false; var versionToWrite = version + 1; TapeStreamSerializer.WriteRecord(file, buffer, versionToWrite); return true; } }
public long TryAppend(byte[] buffer, TapeAppendCondition appendCondition = new TapeAppendCondition()) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (buffer.Length == 0) { throw new ArgumentException("Buffer must contain at least one byte."); } long version; int lastBlockSize; long offset; long firstVersion; long count; List <string> blockNames; var blob = _container.GetBlockBlobReference(_blobName); if (blob.Exists()) { var blockList = blob.DownloadBlockList().ToArray(); blockNames = blockList.Select(bl => bl.Name).ToList(); var lastBlock = blockList.LastOrDefault(); if (default(ListBlockItem) == lastBlock) { version = 0; lastBlockSize = int.MaxValue; offset = 0; firstVersion = 1; count = 0; } else { var nameInfo = Naming.GetInfo(DecodeName(lastBlock.Name)); firstVersion = nameInfo.FirstVersion; version = nameInfo.FirstVersion - 1 + nameInfo.Count; count = nameInfo.Count; if (lastBlock.Size > int.MaxValue) { throw new InvalidOperationException("last block size must be in 'int' range"); } lastBlockSize = (int)lastBlock.Size; offset = blockList.Reverse().Skip(1).Sum(l => l.Size); } } else { version = 0; lastBlockSize = int.MaxValue; offset = 0; firstVersion = 1; count = 0; blockNames = new List <string>(); } if (!appendCondition.Satisfy(version)) { return(0); } if (version > long.MaxValue - 1) { throw new IndexOutOfRangeException("Version is more than long.MaxValue."); } if (buffer.Length > FourMb) { throw new ArgumentException("buffer size must be less than or equal to 4 Mb", "buffer"); } using (var outStream = new MemoryStream()) { if (buffer.Length < MaxBlockSize && lastBlockSize <= MaxBlockSize - buffer.Length) { // read old block using (var s = blob.OpenRead()) { s.Seek(offset, SeekOrigin.Begin); s.CopyTo(outStream); TapeStreamSerializer.WriteRecord(outStream, buffer, version + 1); count++; blockNames.RemoveAt(blockNames.Count - 1); } } else { TapeStreamSerializer.WriteRecord(outStream, buffer, version + 1); firstVersion = version + 1; count = 1; } var blockId = EncodeName(Naming.GetName(firstVersion, count)); string md5Hash; outStream.Seek(0, SeekOrigin.Begin); using (var md5 = MD5.Create()) { md5Hash = Convert.ToBase64String(md5.ComputeHash(outStream)); } outStream.Seek(0, SeekOrigin.Begin); blob.PutBlock(blockId, outStream, md5Hash); blockNames.Add(blockId); blob.PutBlockList(blockNames); return(version + 1); } }