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

Reply via email to