public void Change(ServerStream stream) { lock (this) { StreamHeader header = GetStreamHeader(stream.StreamID); // if this stream is a reference stream StreamID sourceStreamID; if (_referencingHeaders.TryGetValue(stream.StreamID, out sourceStreamID)) { StreamHeader sourceHeader = GetStreamHeader(sourceStreamID); // dereference the source stream _referencingHeaders.Remove(stream.StreamID); sourceHeader.References.Remove(stream.StreamID); // copy the data from the source stream into this stream _defaultProvider.Create(stream.StreamID); InternalCopy(sourceHeader, header); header.Stream.SourceStream = _defaultProvider.Open(stream.StreamID); // move all references to this stream to the source stream MoveReferences(header, sourceHeader); } } }
public override void Deallocate(StreamID streamID) { lock (this) { StreamHeader header = GetStreamHeader(streamID); if (StreamTracingEnabled) { StreamEvents.Deallocate(streamID); } _headers.Remove(streamID); StreamID sourceStreamID;; if (!_referencingHeaders.TryGetValue(streamID, out sourceStreamID)) { // if this stream is a referenced stream if (header.References.Count > 0) { // select a referencing stream to be the new source stream StreamID newStreamID = header.References[0]; StreamHeader newHeader = GetStreamHeader(newStreamID); // reassign the stream id for the stream in the provider (from this stream to the new source stream id) header.Provider.Reassign(header.StreamID, newStreamID); // change the provider in the header for the new source stream id newHeader.Provider = header.Provider; if (newHeader.Stream != null) { newHeader.Stream.SourceStream = newHeader.Provider.Open(newStreamID); // TODO: Shouldn't this close the old stream? } // dereference the new header _referencingHeaders.Remove(newStreamID); header.References.RemoveAt(0); // move all references to this stream to the new source stream MoveReferences(header, newHeader); } else { // destroy this stream header.Provider.Destroy(streamID); } } else { // if this stream is a reference stream StreamHeader sourceHeader = GetStreamHeader(sourceStreamID); // move all references to this stream to the source stream MoveReferences(header, sourceHeader); // dereference the source stream sourceHeader.References.Remove(streamID); _referencingHeaders.Remove(streamID); } } }
public override void Close(int ownerID, StreamID streamID) { lock (this) { #if DEBUG _closeCount++; #endif if (_streamTracingEnabled) { StreamEvents.Close(streamID); StreamOpens.Add(String.Format("Close {0}", streamID.Value.ToString())); } StreamHeader header = GetStreamHeader(streamID); InternalClose(header); } }
public override Stream Open(int ownerID, StreamID streamID, LockMode mode) { lock (this) { #if DEBUG _openCount++; #endif if (_streamTracingEnabled) { StreamEvents.Open(streamID); StreamOpens.Add(String.Format("Open {0}", streamID.Value.ToString())); } StreamHeader header = GetStreamHeader(streamID); return(new ManagedStream(this, ownerID, streamID, InternalOpen(header, false))); } }
public override StreamID Reference(StreamID streamID) { lock (this) { StreamID localStreamID = InternalGetNextStreamID(); StreamHeader header = GetStreamHeader(streamID); if (StreamTracingEnabled) { StreamEvents.Add(new ReferenceStreamEvent(localStreamID, header.StreamID)); } header.References.Add(localStreamID); _referencingHeaders.Add(localStreamID, streamID); InternalRegister(localStreamID, _defaultProvider); return(localStreamID); } }
protected void InternalClose(StreamHeader header) { header.StreamCount--; if (header.StreamCount == 0) { StreamID sourceStreamID; if (_referencingHeaders.TryGetValue(header.StreamID, out sourceStreamID)) { Stream sourceStream = header.Stream.SourceStream; header.Stream.SourceStream = null; sourceStream.Close(); InternalClose(GetStreamHeader(sourceStreamID)); } else { header.Provider.Close(header.StreamID); } header.Stream.Close(); header.Stream = null; } }
protected Stream InternalOpen(StreamHeader header, bool cover) { if (header.Stream == null) { StreamID sourceStreamID; if (_referencingHeaders.TryGetValue(header.StreamID, out sourceStreamID)) { header.Stream = new ServerStream(this, header.StreamID, InternalOpen(GetStreamHeader(sourceStreamID), true)); } else { header.Stream = new ServerStream(this, header.StreamID, header.Provider.Open(header.StreamID)); } } header.StreamCount++; if (cover) { return(new CoverStream(header.Stream)); } return(header.Stream); }
protected void MoveReferences(StreamHeader fromHeader, StreamHeader toHeader) { for (int index = fromHeader.References.Count - 1; index >= 0; index--) { StreamID streamID = fromHeader.References[index]; // Remove the reference to the from header fromHeader.References.RemoveAt(index); _referencingHeaders.Remove(streamID); // Add the reference to the to header toHeader.References.Add(streamID); _referencingHeaders.Add(streamID, toHeader.StreamID); // Make sure the referencing header has the right stream StreamHeader referenceHeader = GetStreamHeader(streamID); if (referenceHeader.Stream != null) { referenceHeader.Stream.SourceStream = toHeader.Provider.Open(toHeader.StreamID); // TODO: Shouldn't this close the old stream? } } }
protected void InternalCopy(StreamHeader sourceStreamHeader, StreamHeader targetStreamHeader) { Stream sourceStream = InternalOpen(sourceStreamHeader, true); try { Stream targetStream = targetStreamHeader.Provider.Open(targetStreamHeader.StreamID); try { targetStream.Position = 0; StreamUtility.CopyStream(sourceStream, targetStream); } finally { targetStreamHeader.Provider.Close(targetStreamHeader.StreamID); } } finally { sourceStream.Close(); InternalClose(sourceStreamHeader); } }
private void InternalUnregister(StreamID streamID) { StreamHeader header = GetStreamHeader(streamID); _headers.Remove(streamID); }