/// <summary> /// Flush the content of the stream. /// </summary> public override void Flush() { if (_lock.TryTake) { // have any of the sections been written to? if (_updated) { _updated = false; // yes, iterate the sections for (int i = _sections.Count - 1; i >= 0; --i) { _section = _sections[i]; if (_section != null && _section.Updated) { SaveSection(_section, i); } } _blobs.BlobMeta.Set(Id, _length, _sectionCount, _sectionSize); } _lock.Release(); } }
/// <summary> /// Move to the next section. /// </summary> protected void NextSection() { // increment the section index ++_sectionIndex; // increment the current position _position = _sectionIndex * _sectionSize; _section = null; }
/// <summary> /// Seek the stream. /// </summary> public override long Seek(long offset, SeekOrigin origin) { if (_initialize) { Initialize(true); } switch (origin) { case SeekOrigin.Begin: if (_position + _sectionPosition == offset) { return(offset); } _position = offset; break; case SeekOrigin.Current: _position += offset; break; case SeekOrigin.End: if (_position + _sectionPosition == _length - offset) { return(_position + _sectionPosition); } _position = _length - offset; break; } // determine the section index var sectionIndex = (int)(_position / _sectionSize); if (sectionIndex != _sectionIndex) { _sectionIndex = sectionIndex; if (_sectionIndex >= _sectionCount) { while (_sectionIndex >= _sections.Count) { _sections.Add(new BlobSection()); } _sectionCount = _sectionIndex + 1; } _section = _sections[_sectionIndex]; } // update the position within the current section _sectionPosition = (int)(_position % _sectionSize); // update the overrall section position _position -= _sectionPosition; return(_position + _sectionPosition); }
/// <summary> /// Save the section. /// </summary> protected void SaveSection(BlobSection section, int sectionIndex) { section.Updated = false; if (section.Length != _sectionSize) { byte[] bytes = new byte[section.Length]; Micron.CopyMemory(section.Bytes, bytes, section.Length); _blobs.BlobData.Set(Id, sectionIndex, bytes); } else { _blobs.BlobData.Set(Id, sectionIndex, section.Bytes); } }
//-------------------------------------------// /// <summary> /// Initialize the blob stream, optionally as a reader. /// </summary> protected void Initialize(bool reader) { _initialize = false; if (reader) { if (_sectionCount == 0) { // get the blob metadata var metadata = _blobs.BlobMeta.Get(Id); // was the metadata retrieved? if (metadata == null) { // no, initialize as a new blob _sectionCount = 1; _sections = new ArrayRig <BlobSection>(_sectionCount); _sections.Add(_section = new BlobSection { Bytes = new byte[_sectionSize], Updated = true }); } else { // yes, persist blob metadata _length = metadata.Length; _sectionCount = metadata.SectionCount; _sectionSize = metadata.SectionLength; _sections = new ArrayRig <BlobSection>(_sectionCount); } } else { // initialize the sections collection with the correct count _sections = new ArrayRig <BlobSection>(_sectionCount); } } else { _sectionCount = 1; _sections = new ArrayRig <BlobSection>(_sectionCount); _sections.Add(_section = new BlobSection { Bytes = new byte[_sectionSize], Updated = true }); } }
/// <summary> /// Flush the content of the stream without taking the internal lock. /// </summary> public void FlushInternal() { // have any of the sections been written to? if (_updated) { _updated = false; // yes, iterate the sections for (int i = _sections.Count - 1; i >= 0; --i) { _section = _sections[i]; if (_section != null && _section.Updated) { SaveSection(_section, i); } } _blobs.BlobMeta.Set(Id, _length, _sectionCount, _sectionSize); } }
/// <summary> /// Load or create the section specified by index. /// </summary> protected void SetSection(int index) { _sectionPosition = 0; if (index == _sectionIndex) { if (_sectionIndex == _sectionCount) { // create a new section _sections.Add(_section = new BlobSection()); _section.Bytes = new byte[_sectionSize]; _section.Updated = true; ++_sectionCount; } else if (_section == null) { if (_sections[index] == null) { _sections[index] = _section = new BlobSection(); } else { _section = _sections[index]; } // get the byte collection from the data table _section.Bytes = _blobs.BlobData.Get(Id, index); _section.Length = _section.Bytes.Length; // add the section byte count AddByteCount(_section.Length); } return; } if (index >= _sectionCount) { while (index >= _sectionCount) { // create a new section _sections.Add(_section = new BlobSection()); _section.Bytes = new byte[_sectionSize]; _section.Updated = true; ++_sectionCount; } } else { // create the section if (_sections[index] == null) { _sections[index] = _section = new BlobSection(); // get the byte collection from the data table _section.Bytes = _blobs.BlobData.Get(Id, index); _section.Length = _section.Bytes.Length; // add the section byte count AddByteCount(_section.Length); } else { _section = _sections[index]; } } }