Author: alanmc
Date: 2008-02-09 16:47:50 -0500 (Sat, 09 Feb 2008)
New Revision: 95344
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/PieceManager.cs
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/TorrentManager.cs
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/DiskWriter.cs
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs
Log:
Implemented memory buffer for disk writes - disabled by default. It's sweet as
a nut.
Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs
===================================================================
--- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -41,6 +41,7 @@
using MonoTorrent.Common;
using MonoTorrent.Client.Managers;
using MonoTorrent.Client.Tracker;
+using MonoTorrent.Client.PieceWriter;
namespace MonoTorrent.Client
{
@@ -187,11 +188,15 @@
if (listener == null && !createListener)
throw new ArgumentNullException("listener");
+ // Wrap a memory buffer around the disk writer
+ IPieceWriter writer = new DiskWriter(engineSettings.MaxOpenFiles);
+ //writer = new MemoryWriter(writer);
+
this.settings = engineSettings;
this.asyncCompletionLock = new object();
this.connectionManager = new ConnectionManager(this);
- this.diskManager = new DiskManager(this);
+ this.diskManager = new DiskManager(this, writer);
this.listenManager = new ListenManager(this);
this.peerId = GeneratePeerId();
this.timer = new System.Timers.Timer(TickLength);
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs
===================================================================
--- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -6,6 +6,7 @@
using System.IO;
using MonoTorrent.Common;
using MonoTorrent.Client.Messages.Standard;
+using MonoTorrent.Client.PieceWriter;
namespace MonoTorrent.Client.Managers
{
@@ -19,9 +20,8 @@
private ConnectionMonitor monitor;
internal RateLimiter rateLimiter;
- private FileStreamBuffer streamsBuffer;
+ private IPieceWriter writer;
-
#endregion Member Variables
@@ -43,11 +43,6 @@
get { return monitor; }
}
- public int OpenFiles
- {
- get { return streamsBuffer.Count; }
- }
-
public int QueuedWrites
{
get { return this.bufferedWrites.Count; }
@@ -78,7 +73,7 @@
#region Constructors
- public DiskManager(ClientEngine engine)
+ internal DiskManager(ClientEngine engine, IPieceWriter writer)
{
this.bufferedReads = new Queue<BufferedFileRead>();
this.bufferedWrites = new Queue<BufferedIO>();
@@ -88,9 +83,9 @@
this.monitor = new ConnectionMonitor();
this.queueLock = new object();
this.rateLimiter = new RateLimiter();
- this.streamsBuffer = new
FileStreamBuffer(engine.Settings.MaxOpenFiles);
this.streamsLock = new ReaderWriterLock();
this.threadWait = new ManualResetEvent(false);
+ this.writer = writer;
this.ioThread.Start();
}
@@ -101,43 +96,20 @@
internal void CloseFileStreams(TorrentManager manager)
{
- Array.ForEach<TorrentFile>(manager.Torrent.Files,
delegate(TorrentFile f) { streamsBuffer.CloseStream(f); });
+ writer.CloseFileStreams(manager);
}
- /// <summary>
- /// Generates the full path to the supplied TorrentFile
- /// </summary>
- /// <param name="file">The TorrentFile to generate the full path
to</param>
- /// <param name="baseDirectory">The name of the directory that the
files are contained in</param>
- /// <param name="savePath">The path to the directory that contains the
BaseDirectory</param>
- /// <returns>The full path to the TorrentFile</returns>
- private static string GenerateFilePath(TorrentFile file, string
baseDirectory, string savePath)
+ public void Dispose()
{
- string path;
-
- path = Path.Combine(savePath, baseDirectory);
- path = Path.Combine(path, file.Path);
-
- if (!Directory.Exists(Path.GetDirectoryName(path)) &&
!string.IsNullOrEmpty(Path.GetDirectoryName(path)))
- Directory.CreateDirectory(Path.GetDirectoryName(path));
-
- return path;
+ ioActive = false;
+ this.threadWait.Set();
+ this.ioThread.Join();
+ this.writer.Dispose();
}
/// <summary>
- /// Opens all the filestreams with the specified file access
- /// </summary>
- /// <param name="fileAccess"></param>
- internal TorrentFileStream GetStream(FileManager manager, TorrentFile
file, FileAccess access)
- {
- string filePath = GenerateFilePath(file, manager.BaseDirectory,
manager.SavePath);
- return streamsBuffer.GetStream(file, filePath, access);
- }
-
-
- /// <summary>
/// Performs the buffered write
/// </summary>
/// <param name="bufferedFileIO"></param>
@@ -156,14 +128,15 @@
{
// Calculate the index where we will start to write the data
long writeIndex = (long)message.PieceIndex *
message.PieceLength + message.StartOffset;
- Write(bufferedFileIO, recieveBuffer.Array,
recieveBuffer.Offset, writeIndex, message.RequestLength);
+ writer.Write(bufferedFileIO, recieveBuffer.Array,
recieveBuffer.Offset, writeIndex, message.RequestLength);
}
piece.Blocks[index].Written = true;
id.TorrentManager.FileManager.RaiseBlockWritten(new
BlockEventArgs(id.TorrentManager, piece.Blocks[index], piece, id));
// Release the buffer back into the buffer manager.
- ClientEngine.BufferManager.FreeBuffer(ref bufferedFileIO.Buffer);
+ //ClientEngine.BufferManager.FreeBuffer(ref bufferedFileIO.Buffer);
+#warning FIX THIS - don't free the buffer here anymore
// If we haven't written all the pieces to disk, there's no point
in hash checking
if (!piece.AllBlocksWritten)
@@ -199,11 +172,17 @@
/// <param name="bufferedFileIO"></param>
private void PerformRead(BufferedFileRead io)
{
- io.BytesRead = Read(io.Manager, io.Buffer, io.BufferOffset,
io.PieceStartIndex, io.Count);
+ io.BytesRead = writer.Read(io.Manager, io.Buffer, io.BufferOffset,
io.PieceStartIndex, io.Count);
io.WaitHandle.Set();
}
+ internal int Read(FileManager fileManager, byte[] buffer, int
bufferOffset, long pieceStartIndex, int bytesToRead)
+ {
+ return writer.Read(fileManager, buffer, bufferOffset,
pieceStartIndex, bytesToRead);
+ }
+
+
/// <summary>
/// Queues a block of data to be written asynchronously
/// </summary>
@@ -239,55 +218,6 @@
/// <summary>
- /// This method reads 'count' number of bytes from the filestream
starting at index 'offset'.
- /// The bytes are read into the buffer starting at index
'bufferOffset'.
- /// </summary>
- /// <param name="buffer">The byte[] containing the bytes to
write</param>
- /// <param name="bufferOffset">The offset in the byte[] at which to
save the data</param>
- /// <param name="offset">The offset in the file at which to start
reading the data</param>
- /// <param name="count">The number of bytes to read</param>
- /// <returns>The number of bytes successfully read</returns>
- internal int Read(FileManager manager, byte[] buffer, int
bufferOffset, long offset, int count)
- {
- if (buffer == null)
- throw new ArgumentNullException("buffer");
-
- if (offset < 0 || offset + count > manager.FileSize)
- throw new ArgumentOutOfRangeException("offset");
-
- int i = 0;
- int bytesRead = 0;
- int totalRead = 0;
-
- for (i = 0; i < manager.Files.Length; i++) // This section
loops through all the available
- { // files until
we find the file which contains
- if (offset < manager.Files[i].Length) // the
start of the data we want to read
- break;
-
- offset -= manager.Files[i].Length; // Offset now
contains the index of the data we want
- } // to read
from fileStream[i].
-
- while (totalRead < count) // We keep
reading until we have read 'count' bytes.
- {
- if (i == manager.Files.Length)
- break;
-
- lock (manager.Files[i])
- {
- TorrentFileStream s = GetStream(manager, manager.Files[i],
FileAccess.Read);
- s.Seek(offset, SeekOrigin.Begin);
- offset = 0; // Any further files need to be read from the
beginning
- bytesRead = s.Read(buffer, bufferOffset + totalRead, count
- totalRead);
- totalRead += bytesRead;
- i++;
- }
- }
- monitor.BytesSent(totalRead, TransferType.Data);
- return totalRead;
- }
-
-
- /// <summary>
/// This method runs in a dedicated thread. It performs all the async
reads and writes as they are queued
/// </summary>
private void RunIO()
@@ -345,74 +275,11 @@
this.threadWait.Reset();
}
-
- /// <summary>
- /// This method reads 'count' number of bytes starting at the position
'offset' into the
- /// byte[] 'buffer'. The data gets written in the buffer starting at
index 'bufferOffset'
- /// </summary>
- /// <param name="buffer">The byte[] to read the data into</param>
- /// <param name="bufferOffset">The offset within the array to save the
data</param>
- /// <param name="offset">The offset in the file from which to read the
data</param>
- /// <param name="count">The number of bytes to read</param>
- private void Write(BufferedIO io, byte[] buffer, int bufferOffset,
long offset, int count)
- {
- FileManager manager = io.Id.TorrentManager.FileManager;
- if (buffer == null)
- throw new ArgumentNullException("buffer");
-
- if (offset < 0 || offset + count > manager.FileSize)
- throw new ArgumentOutOfRangeException("offset");
-
- int i = 0;
- long bytesWritten = 0;
- long totalWritten = 0;
- long bytesWeCanWrite = 0;
-
- for (i = 0; i < manager.Files.Length; i++) // This
section loops through all the available
- { // files until
we find the file which contains
- if (offset < manager.Files[i].Length) // the start
of the data we want to write
- break;
-
- offset -= manager.Files[i].Length; // Offset now
contains the index of the data we want
- } // to write to
fileStream[i].
-
- while (totalWritten < count) // We keep
writing until we have written 'count' bytes.
- {
- lock (manager.Files[i])
- {
- TorrentFileStream stream = GetStream(manager,
manager.Files[i], FileAccess.ReadWrite);
- stream.Seek(offset, SeekOrigin.Begin);
-
- // Find the maximum number of bytes we can write before we
reach the end of the file
- bytesWeCanWrite = manager.Files[i].Length - offset;
-
- // Any further files need to be written from the beginning
of the file
- offset = 0;
-
- // If the amount of data we are going to write is larger
than the amount we can write, just write the allowed
- // amount and let the rest of the data be written with the
next filestream
- bytesWritten = ((count - totalWritten) > bytesWeCanWrite)
? bytesWeCanWrite : (count - totalWritten);
-
- // Write the data
- stream.Write(buffer, bufferOffset + (int)totalWritten,
(int)bytesWritten);
-
- // Any further data should be written to the next
available file
- totalWritten += bytesWritten;
- i++;
- }
- }
-
- monitor.BytesReceived((int)totalWritten, TransferType.Data);
- }
-
#endregion
- public void Dispose()
+ internal void Flush(TorrentManager manager)
{
- ioActive = false;
- this.threadWait.Set();
- this.ioThread.Join();
- this.streamsBuffer.Dispose();
+ writer.Flush(manager);
}
}
}
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/PieceManager.cs
===================================================================
--- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/PieceManager.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/PieceManager.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -78,7 +78,7 @@
/// </summary>
public bool LinearPickingEnabled
{
- get { return piecePicker.LinearPickingEnabled; }
+ get { return true;}// piecePicker.LinearPickingEnabled; }
set { piecePicker.LinearPickingEnabled = value; }
}
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/TorrentManager.cs
===================================================================
---
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/TorrentManager.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/TorrentManager.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -737,6 +737,7 @@
internal void RaiseTorrentStateChanged(TorrentStateChangedEventArgs e)
{
+ engine.DiskManager.Flush(this);
ThreadPool.QueueUserWorkItem(delegate {
EventHandler<TorrentStateChangedEventArgs> h =
TorrentStateChanged;
if (h != null)
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/DiskWriter.cs
===================================================================
--- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/DiskWriter.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/DiskWriter.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -8,31 +8,28 @@
{
public class DiskWriter : IPieceWriter
{
- public void Dispose()
+ private FileStreamBuffer streamsBuffer;
+
+ public int OpenFiles
{
+ get { return streamsBuffer.Count; }
}
- public DiskWriter()
+ public DiskWriter(int maxOpenFiles)
{
- //this.streamsBuffer = new
FileStreamBuffer(engine.Settings.MaxOpenFiles);
+ this.streamsBuffer = new FileStreamBuffer(maxOpenFiles);
}
- internal void CloseFileStreams(TorrentManager manager)
+
+ public void CloseFileStreams(TorrentManager manager)
{
Array.ForEach<TorrentFile>(manager.Torrent.Files,
delegate(TorrentFile f) { streamsBuffer.CloseStream(f); });
}
- private FileStreamBuffer streamsBuffer;
- public int OpenFiles
+ public void Dispose()
{
- get { return streamsBuffer.Count; }
+ streamsBuffer.Dispose();
}
- /// <summary>
- /// Generates the full path to the supplied TorrentFile
- /// </summary>
- /// <param name="file">The TorrentFile to generate the full path
to</param>
- /// <param name="baseDirectory">The name of the directory that the
files are contained in</param>
- /// <param name="savePath">The path to the directory that contains the
BaseDirectory</param>
- /// <returns>The full path to the TorrentFile</returns>
+
private static string GenerateFilePath(TorrentFile file, string
baseDirectory, string savePath)
{
string path;
@@ -46,18 +43,12 @@
return path;
}
-
- /// <summary>
- /// Opens all the filestreams with the specified file access
- /// </summary>
- /// <param name="fileAccess"></param>
internal TorrentFileStream GetStream(FileManager manager, TorrentFile
file, FileAccess access)
{
string filePath = GenerateFilePath(file, manager.BaseDirectory,
manager.SavePath);
return streamsBuffer.GetStream(file, filePath, access);
}
-
public int Read(FileManager manager, byte[] buffer, int bufferOffset,
long offset, int count)
{
if (buffer == null)
@@ -70,12 +61,12 @@
int bytesRead = 0;
int totalRead = 0;
- for (i = 0; i < manager.Files.Length; i++) // This section
loops through all the available
+ for (i = 0; i < manager.Files.Length; i++) // This
section loops through all the available
{ // files until
we find the file which contains
- if (offset < manager.Files[i].Length) // the
start of the data we want to read
+ if (offset < manager.Files[i].Length) // the start
of the data we want to read
break;
- offset -= manager.Files[i].Length; // Offset now
contains the index of the data we want
+ offset -= manager.Files[i].Length; // Offset now
contains the index of the data we want
} // to read
from fileStream[i].
while (totalRead < count) // We keep
reading until we have read 'count' bytes.
@@ -138,6 +129,7 @@
// Write the data
stream.Write(buffer, bufferOffset + (int)totalWritten,
(int)bytesWritten);
+ stream.Flush();
// Any further data should be written to the next
available file
totalWritten += bytesWritten;
@@ -147,5 +139,10 @@
//monitor.BytesReceived((int)totalWritten, TransferType.Data);
}
+
+ public void Flush(TorrentManager manager)
+ {
+ // No buffering done here
+ }
}
}
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs
===================================================================
---
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -1,13 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
+using MonoTorrent.Common;
namespace MonoTorrent.Client.PieceWriter
{
interface IPieceWriter : IDisposable
{
int Read(FileManager manager, byte[] buffer, int bufferOffset, long
offset, int count);
+
+ void Write(BufferedIO io, byte[] buffer, int bufferOffset, long
offset, int count);
- void Write(BufferedIO io, byte[] buffer, int bufferOffset, long
offset, int count);
+ void CloseFileStreams(TorrentManager manager);
+
+ void Flush(TorrentManager manager);
}
}
Modified:
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs
===================================================================
---
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs
2008-02-09 20:43:15 UTC (rev 95343)
+++
trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs
2008-02-09 21:47:50 UTC (rev 95344)
@@ -6,120 +6,142 @@
namespace MonoTorrent.Client.PieceWriter
{
+ internal class MemIO
+ {
+ public FileManager manager;
+ public byte[] buffer;
+ public int bufferOffset;
+ public long offset;
+ public int count;
+ public BufferedIO io;
+
+ public MemIO(FileManager manager, BufferedIO io, byte[] buffer, int
bufferOffset, long offset, int count)
+ {
+ this.manager = manager;
+ this.io = io;
+ this.buffer = buffer;
+ this.bufferOffset = bufferOffset;
+ this.offset = offset;
+ this.count = count;
+ }
+ }
public class MemoryWriter : IPieceWriter
{
- public void Dispose()
+ private int capacity;
+ private List<MemIO> memoryBuffer;
+ private IPieceWriter writer;
+
+
+ public int Capacity
{
+ get { return capacity; }
}
- private int bufferSize;
- private List <BufferedIO> memoryBuffer;
- public int BufferSize = 8 * 1024 * 1024;
public int Used
{
get
{
int count = 0;
- memoryBuffer.ForEach(delegate(BufferedIO i) { count +=
i.Buffer.Count; });
+ memoryBuffer.ForEach(delegate(MemIO i) { count += i.count; });
return count;
}
}
- public MemoryWriter()
+ internal MemoryWriter(IPieceWriter writer)
+ : this(writer, 8 * 1024 * 1024)
{
- memoryBuffer = new List<BufferedIO>();
+
}
+ internal MemoryWriter(IPieceWriter writer, int capacity)
+ {
+ if (writer == null)
+ throw new ArgumentNullException("writer");
- public int Read(FileManager manager, byte[] buffer, int bufferOffset,
long offset, int count)
- {/*
- if (buffer == null)
- throw new ArgumentNullException("buffer");
+ if (capacity < 0)
+ throw new ArgumentOutOfRangeException("capacity");
- if (offset < 0 || offset + count > manager.FileSize)
- throw new ArgumentOutOfRangeException("offset");
+ memoryBuffer = new List<MemIO>();
+ this.capacity = capacity;
+ this.writer = writer;
+ }
- int i = 0;
- int bytesRead = 0;
- int totalRead = 0;
+ public void Dispose()
+ {
- for (i = 0; i < manager.Files.Length; i++) // This section
loops through all the available
- { // files until
we find the file which contains
- if (offset < manager.Files[i].Length) // the
start of the data we want to read
- break;
+ }
- offset -= manager.Files[i].Length; // Offset now
contains the index of the data we want
- } // to read
from fileStream[i].
- while (totalRead < count) // We keep
reading until we have read 'count' bytes.
+ public int Read(FileManager manager, byte[] buffer, int bufferOffset,
long offset, int count)
+ {
+ int origCount = count;
+ while (count != 0)
{
- if (i == manager.Files.Length)
- break;
-
- lock (manager.Files[i])
+ memoryBuffer.Sort(delegate(MemIO left, MemIO right) { return
left.offset.CompareTo(right.offset); });
+ MemIO io = memoryBuffer.Find(delegate(MemIO m) { return
((offset >= m.offset) && (offset < (m.offset + m.count))); });
+ if (io != null)
{
- TorrentFileStream s = GetStream(manager, manager.Files[i],
FileAccess.Read);
- s.Seek(offset, SeekOrigin.Begin);
- offset = 0; // Any further files need to be read from the
beginning
- bytesRead = s.Read(buffer, bufferOffset + totalRead, count
- totalRead);
- totalRead += bytesRead;
- i++;
+ int toCopy = Math.Min(count, io.count + (int)(io.offset -
offset));
+ Buffer.BlockCopy(io.buffer, io.bufferOffset +
(int)(io.offset - offset), buffer, bufferOffset + (origCount - count), toCopy);
+ offset += toCopy;
+ count -= toCopy;
}
+ else
+ break;
}
- monitor.BytesSent(totalRead, TransferType.Data);
- return totalRead;*/
- return 1;
+ if(count == 0)
+ return origCount;
+
+ return writer.Read(manager, buffer, bufferOffset, offset, count) +
(origCount - count);
}
+ private void Write(MemIO m)
+ {
+ Write(m.io, m.buffer, m.bufferOffset, m.offset, m.count, true);
+ }
+
+
public void Write(BufferedIO io, byte[] buffer, int bufferOffset, long
offset, int count)
- {/*
- FileManager manager = io.Id.TorrentManager.FileManager;
- if (buffer == null)
- throw new ArgumentNullException("buffer");
+ {
+ Write(io, buffer, bufferOffset, offset, count, false);
+ }
- if (offset < 0 || offset + count > manager.FileSize)
- throw new ArgumentOutOfRangeException("offset");
+ public void Write(BufferedIO io, byte[] buffer, int bufferOffset, long
offset, int count, bool forceWrite)
+ {
+ if (forceWrite)
+ {
+ writer.Write(io, buffer, bufferOffset, offset, count);
+ return;
+ }
- int i = 0;
- long bytesWritten = 0;
- long totalWritten = 0;
- long bytesWeCanWrite = 0;
+ if (Used >= (Capacity - count))
+ FlushSome();
- for (i = 0; i < manager.Files.Length; i++) // This
section loops through all the available
- { // files until
we find the file which contains
- if (offset < manager.Files[i].Length) // the start
of the data we want to write
- break;
+ memoryBuffer.Add(new MemIO(io.Id.TorrentManager.FileManager, io,
buffer, bufferOffset, offset, count));
+ }
- offset -= manager.Files[i].Length; // Offset now
contains the index of the data we want
- } // to write to
fileStream[i].
+ private void FlushSome()
+ {
+ int count = Math.Min(5, memoryBuffer.Count);
+ for (int i = 0; i < count; i++)
+ Write(memoryBuffer[i]);
- while (totalWritten < count) // We keep
writing until we have written 'count' bytes.
- {
- lock (manager.Files[i])
- {
- TorrentFileStream stream = GetStream(manager,
manager.Files[i], FileAccess.ReadWrite);
- stream.Seek(offset, SeekOrigin.Begin);
+ memoryBuffer.RemoveRange(0, count);
+ }
- // Find the maximum number of bytes we can write before we
reach the end of the file
- bytesWeCanWrite = manager.Files[i].Length - offset;
- // Any further files need to be written from the beginning
of the file
- offset = 0;
- // If the amount of data we are going to write is larger
than the amount we can write, just write the allowed
- // amount and let the rest of the data be written with the
next filestream
- bytesWritten = ((count - totalWritten) > bytesWeCanWrite)
? bytesWeCanWrite : (count - totalWritten);
+ public void CloseFileStreams(TorrentManager manager)
+ {
+ Flush(manager);
+ writer.CloseFileStreams(manager);
+ }
- // Write the data
- stream.Write(buffer, bufferOffset + (int)totalWritten,
(int)bytesWritten);
- // Any further data should be written to the next
available file
- totalWritten += bytesWritten;
- i++;
- }
- }
-
- monitor.BytesReceived((int)totalWritten, TransferType.Data);*/
+ public void Flush(TorrentManager manager)
+ {
+ memoryBuffer.ForEach(delegate(MemIO io) { if (io.manager ==
manager.FileManager) Write(io); });
+ memoryBuffer.RemoveAll(delegate(MemIO io) { return io.manager ==
manager.FileManager; });
}
}
}
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches