Author: alanmc Date: 2008-02-19 18:44:31 -0500 (Tue, 19 Feb 2008) New Revision: 96205
Added: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/Pressure.cs Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/PieceData.cs Log: Implemented first section of code needed to implement intelligent memory buffering Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs 2008-02-19 23:33:54 UTC (rev 96204) +++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/ClientEngine.cs 2008-02-19 23:44:31 UTC (rev 96205) @@ -343,6 +343,15 @@ this.torrents.Add(manager); manager.Engine = this; +/* + manager.PieceHashed += delegate (object sender, PieceHashedEventArgs e) { + diskManager.Writer.RemovePressure(e.TorrentManager, e.PieceIndex); + }; + + manager.PieceManager.BlockRequested += delegate(object sender, BlockEventArgs e) { + diskManager.Writer.AddPressure(e.TorrentManager, e.Piece.Index, e.Block.StartOffset / Piece.BlockSize); + }; +*/ } Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs 2008-02-19 23:33:54 UTC (rev 96204) +++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/Managers/DiskManager.cs 2008-02-19 23:44:31 UTC (rev 96205) @@ -68,6 +68,11 @@ get { return monitor.DataBytesDownloaded; } } + internal PieceWriter Writer + { + get { return writer; } + } + #endregion Properties Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs 2008-02-19 23:33:54 UTC (rev 96204) +++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/IPieceWriter.cs 2008-02-19 23:44:31 UTC (rev 96205) @@ -5,41 +5,80 @@ namespace MonoTorrent.Client.PieceWriters { - public abstract class PieceWriter - { - protected PieceWriter() - { + public abstract class PieceWriter + { + protected List<Pressure> pressures; - } + protected PieceWriter() + { + pressures = new List<Pressure>(); + } - public int ReadChunk(FileManager manager, byte[] buffer, int bufferOffset, long offset, int count) - { - int read = 0; - int totalRead = 0; + private IEnumerable<int> AllBlocks(TorrentManager manager) + { + for (int i = 0; i < manager.Torrent.PieceLength / Piece.BlockSize; i++) + yield return i; + } - while (totalRead != count) - { - read = Read(manager, buffer, bufferOffset + totalRead, offset + totalRead, count - totalRead); - totalRead += read; + public void AddPressure(TorrentManager manager, int pieceIndex) + { + foreach (int i in AllBlocks(manager)) + AddPressure(manager, pieceIndex, i); + } - if (read == 0) - return totalRead; - } + public virtual void AddPressure(TorrentManager manager, int pieceIndex, int blockIndex) + { + } - return totalRead; - } + public abstract void CloseFileStreams(TorrentManager manager); - public abstract int Read(FileManager manager, byte[] buffer, int bufferOffset, long offset, int count); + public virtual void Dispose() + { - public abstract void Write(PieceData data); + } - public abstract void CloseFileStreams(TorrentManager manager); + public abstract void Flush(TorrentManager manager); - public abstract void Flush(TorrentManager manager); + protected Pressure FindPressure(FileManager manager, int pieceIndex, int blockIndex) + { + if (manager == null) + throw new ArgumentNullException("manager"); - public virtual void Dispose() - { + return pressures.Find(delegate (Pressure p) { + return p.PieceIndex == pieceIndex && p.BlockIndex == blockIndex && p.Manager.FileManager == manager; + }); + } - } - } + public abstract int Read(FileManager manager, byte[] buffer, int bufferOffset, long offset, int count); + + public int ReadChunk(FileManager manager, byte[] buffer, int bufferOffset, long offset, int count) + { + int read = 0; + int totalRead = 0; + + while (totalRead != count) + { + read = Read(manager, buffer, bufferOffset + totalRead, offset + totalRead, count - totalRead); + totalRead += read; + + if (read == 0) + return totalRead; + } + + return totalRead; + } + + public void RemovePressure(TorrentManager manager, int pieceIndex) + { + foreach (int i in AllBlocks(manager)) + RemovePressure(manager, pieceIndex, i); + } + + public virtual void RemovePressure(TorrentManager manager, int pieceIndex, int blockIndex) + { + + } + + public abstract void Write(PieceData data); + } } \ No newline at end of file Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs 2008-02-19 23:33:54 UTC (rev 96204) +++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/MemoryWriter.cs 2008-02-19 23:44:31 UTC (rev 96205) @@ -78,13 +78,35 @@ memoryBuffer.Add(data); } - private Random r = new Random(5); + private void FlushSome() { - int count = Math.Min(1, memoryBuffer.Count); - int index = r.Next(0, memoryBuffer.Count); - Write(memoryBuffer[index], true); - memoryBuffer.RemoveAt(index); + if (memoryBuffer.Count == 0) + return; + + memoryBuffer.Sort(delegate(PieceData left, PieceData right) + { + Pressure lp = FindPressure(left.Manager, left.PieceIndex, left.BlockIndex); + Pressure rp = FindPressure(right.Manager, right.PieceIndex, right.BlockIndex); + // If there are no pressures associated with this piece, then return 0 + if (lp == null && rp == null || lp == rp) + return 0; + + // If only one of the pressures is null, we pretend that its pressure is 0 + // and compare the other pressure with that + if (lp == null) + return rp.Value.CompareTo(0); + + if (rp == null) + return lp.Value.CompareTo(0); + + return lp.Value.CompareTo(rp.Value); + }); + + PieceData data = memoryBuffer[0]; + Write(data, true); + memoryBuffer.RemoveAt(0); + pressures.Remove(FindPressure(data.Manager, data.PieceIndex, data.BlockIndex)); } public override void CloseFileStreams(TorrentManager manager) @@ -105,5 +127,33 @@ }); memoryBuffer.RemoveAll(delegate(PieceData io) { return io.Manager == manager.FileManager; }); } + + public override void AddPressure(TorrentManager manager, int pieceIndex, int blockIndex) + { + if (manager == null) + throw new ArgumentNullException("manager"); + + Pressure p = FindPressure(manager.FileManager, pieceIndex, blockIndex); + if (p != null) + p.Value++; + else + pressures.Add(new Pressure(manager, pieceIndex, blockIndex, 1)); + + writer.AddPressure(manager, pieceIndex, blockIndex); + } + + public override void RemovePressure(TorrentManager manager, int pieceIndex, int blockIndex) + { + if (manager == null) + throw new ArgumentNullException("manager"); + + Pressure p = FindPressure(manager.FileManager, pieceIndex, blockIndex); + if (p != null) + p.Value--; + else + pressures.Add(new Pressure(manager, pieceIndex, blockIndex, -1)); + + writer.RemovePressure(manager, pieceIndex, blockIndex); + } } } Modified: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/PieceData.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/PieceData.cs 2008-02-19 23:33:54 UTC (rev 96204) +++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/PieceData.cs 2008-02-19 23:44:31 UTC (rev 96205) @@ -12,9 +12,9 @@ private Piece piece; private int pieceIndex; private int startOffset; - private FileManager fileManager; + private FileManager fileManager; + private int pressure; - public int BlockIndex { get { return PiecePickerBase.GetBlockIndex(piece.Blocks, startOffset, count); } @@ -32,7 +32,7 @@ public FileManager Manager { - get { return fileManager; } + get { return fileManager; } } public Piece Piece @@ -46,6 +46,12 @@ get { return pieceIndex; } } + public int Pressure + { + get { return pressure; } + set { pressure = value; } + } + public int StartOffset { get { return startOffset; } @@ -69,10 +75,10 @@ this.fileManager = id.TorrentManager.FileManager; } - public PieceData(ArraySegment<byte> buffer, int pieceIndex, int startOffset, int count, FileManager manager) - : this(buffer, pieceIndex, startOffset, count, (PeerIdInternal)null) - { - fileManager = manager; - } + public PieceData(ArraySegment<byte> buffer, int pieceIndex, int startOffset, int count, FileManager manager) + : this(buffer, pieceIndex, startOffset, count, (PeerIdInternal)null) + { + fileManager = manager; + } } } Added: trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/Pressure.cs =================================================================== --- trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/Pressure.cs 2008-02-19 23:33:54 UTC (rev 96204) +++ trunk/bitsharp/src/MonoTorrent/MonoTorrent.Client/PieceWriter/Pressure.cs 2008-02-19 23:44:31 UTC (rev 96205) @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonoTorrent.Client.PieceWriters +{ + public class Pressure + { + private int blockIndex; + private int pieceIndex; + private int pressure; + private TorrentManager manager; + + public int BlockIndex + { + get { return blockIndex; } + } + + public int PieceIndex + { + get { return pieceIndex; } + } + + public int Value + { + get { return pressure; } + set { pressure = value; } + } + + public TorrentManager Manager + { + get { return manager; } + } + + public Pressure(TorrentManager manager, int pieceIndex, int blockIndex) + : this(manager, pieceIndex, blockIndex, 0) + { + + } + public Pressure(TorrentManager manager, int pieceIndex, int blockIndex, int pressure) + { + this.manager = manager; + this.pieceIndex = pieceIndex; + this.blockIndex = blockIndex; + this.pressure = pressure; + } + } +} _______________________________________________ Mono-patches maillist - Mono-patches@lists.ximian.com http://lists.ximian.com/mailman/listinfo/mono-patches