Skip to content
This repository was archived by the owner on Jun 30, 2021. It is now read-only.

Commit 787b750

Browse files
committed
add disk cache
1 parent ccc957b commit 787b750

File tree

10 files changed

+226
-60
lines changed

10 files changed

+226
-60
lines changed

BaiduPCS_NET/Properties/AssemblyInfo.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.0.5.0")]
36-
[assembly: AssemblyFileVersion("1.0.5.0")]
35+
[assembly: AssemblyVersion("1.0.6.0")]
36+
[assembly: AssemblyFileVersion("1.0.6.0")]

Sample/Sample_0_FileExplorer/Common/AppSettings.cs

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public static class AppSettings
5454
/// </summary>
5555
public static bool OverWriteWhenUploadFile { get; set; }
5656

57+
/// <summary>
58+
/// 磁盘缓存大小
59+
/// </summary>
60+
public static long MaxCacheSize { get; set; }
61+
5762
public static bool Restore()
5863
{
5964
string filename = SettingsFileName;
@@ -114,6 +119,9 @@ public static bool RestoreFrom(TextReader reader)
114119
case "OverWriteWhenUploadFile":
115120
OverWriteWhenUploadFile = Convert.ToBoolean(value);
116121
break;
122+
case "MaxCacheSize":
123+
MaxCacheSize = Convert.ToInt64(value);
124+
break;
117125

118126
}
119127
}
@@ -160,6 +168,7 @@ public static bool SaveTo(Stream stream)
160168
WriteItem(writer, "AutomaticUploadMaxThreadCount", AutomaticUploadMaxThreadCount.ToString());
161169
WriteItem(writer, "RetryWhenUploadFailed", RetryWhenUploadFailed.ToString());
162170
WriteItem(writer, "OverWriteWhenUploadFile", OverWriteWhenUploadFile.ToString());
171+
WriteItem(writer, "MaxCacheSize", MaxCacheSize.ToString());
163172

164173
#endregion
165174

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace FileExplorer
7+
{
8+
public class Cache
9+
{
10+
public long TotalSize { get; set; }
11+
12+
public IBigFileHelper FileHelper { get; set; }
13+
14+
public List<Block> BlockList { get; private set; }
15+
16+
public Cache()
17+
{
18+
TotalSize = 0L;
19+
BlockList = new List<Block>();
20+
}
21+
22+
public bool Add(long position, byte[] data, int size)
23+
{
24+
Block block = new Block();
25+
block.Position = position;
26+
block.Data = data;
27+
block.Size = size;
28+
BlockList.Add(block);
29+
TotalSize += size;
30+
return true;
31+
}
32+
33+
public bool Flush()
34+
{
35+
BlockList.Sort(new BlockComparer());
36+
foreach (Block block in BlockList)
37+
{
38+
FileHelper.Update(block.Position, block.Data, 0, block.Size);
39+
}
40+
return true;
41+
}
42+
43+
public bool Reset()
44+
{
45+
TotalSize = 0;
46+
BlockList.Clear();
47+
return true;
48+
}
49+
50+
public class Block
51+
{
52+
public long Position { get; set; }
53+
54+
public int Size { get; set; }
55+
56+
public byte[] Data { get; set; }
57+
}
58+
59+
public class BlockComparer : IComparer<Block>
60+
{
61+
public int Compare(Block x, Block y)
62+
{
63+
long xpos = x == null ? 0L : x.Position;
64+
long ypos = y == null ? 0L : y.Position;
65+
return xpos < ypos ? -1 : (xpos > ypos ? 1 : 0);
66+
}
67+
}
68+
}
69+
}

Sample/Sample_0_FileExplorer/DU/MultiThreadDownloader.cs

+31-8
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public class MultiThreadDownloader : Downloader
3434
private long taskId = 0; //本地下载任务的 ID
3535
private long runningThreadCount = 0; //正在运行的线程数
3636
private object locker = new object();
37-
private object sliceFileLocker = new object();
37+
private Cache cache = new Cache();
3838

3939
public MultiThreadDownloader(BaiduPCS pcs, PcsFileInfo from, string to,
4040
string workfolder, int threadCount, int minSliceSize = MIN_SLICE_SIZE)
@@ -71,6 +71,11 @@ public override void Download()
7171
CreateDirectory(to); //创建目录
7272
CreateLocalFile(); // 如果需要则创建本地文件
7373
bigfile = new BigFileHelper(to, from.size); //映射文件到内存
74+
lock(cache)
75+
{
76+
cache.Reset();
77+
cache.FileHelper = bigfile;
78+
}
7479
foreach (Slice slice in SliceList)
7580
{
7681
if (slice.status != SliceStatus.Successed)
@@ -201,6 +206,8 @@ private void downloadTask(object objTID)
201206
string errmsg;
202207
pcs = this.pcs.clone();
203208
pcs.Write += onWrite;
209+
Random rnd = new Random(Environment.TickCount);
210+
Thread.Sleep(rnd.Next(1, 10));
204211
while (tid == Interlocked.Read(ref taskId))
205212
{
206213
slice = popSlice();
@@ -216,6 +223,16 @@ private void downloadTask(object objTID)
216223
rc = pcs.download(from.path, 0,
217224
slice.start + slice.doneSize,
218225
slice.totalSize - slice.doneSize);
226+
lock (cache)
227+
{
228+
if (cache.TotalSize > 0)
229+
{
230+
if (!cache.Flush())
231+
throw new Exception("Failed to flush cache.");
232+
cache.Reset();
233+
SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据
234+
}
235+
}
219236
if (rc == PcsRes.PCS_OK || slice.status == SliceStatus.Successed)
220237
slice.status = SliceStatus.Successed;
221238
else if (slice.status == SliceStatus.Cancelled)
@@ -288,13 +305,10 @@ private uint onWrite(BaiduPCS sender, byte[] data, uint contentlength, object us
288305
size = slice.totalSize - slice.doneSize;
289306
if (size > 0)
290307
{
291-
try
292-
{
293-
bigfile.Update(slice.start + slice.doneSize, data, 0, (int)size);
294-
}
295-
catch(Exception ex)
308+
lock (cache)
296309
{
297-
throw;
310+
if (!cache.Add(slice.start + slice.doneSize, data, (int)size))
311+
throw new Exception("Failed to add to disk cache.");
298312
}
299313
}
300314
slice.doneSize += size;
@@ -304,7 +318,16 @@ private uint onWrite(BaiduPCS sender, byte[] data, uint contentlength, object us
304318
slice.status = SliceStatus.Successed;
305319
size = 0;
306320
}
307-
lock (sliceFileLocker) SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据
321+
lock (cache)
322+
{
323+
if (cache.TotalSize >= AppSettings.MaxCacheSize * 1024)
324+
{
325+
if (!cache.Flush())
326+
throw new Exception("Failed to flush cache.");
327+
cache.Reset();
328+
SliceHelper.SaveSliceList(SliceFileName, SliceList); // 保存最新的分片数据
329+
}
330+
}
308331
long downloadedSize = 0;
309332
lock (locker) downloadedSize = DoneSize;
310333
ProgressEventArgs args = new ProgressEventArgs(downloadedSize, from.size);

Sample/Sample_0_FileExplorer/Forms/frmHistory.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ private void RefreshControls()
448448

449449
private void RefreshST()
450450
{
451-
lblStatusST.Text = runningThreadCount.ToString() + "/" + totalThreadCount.ToString() + " threads, " +
451+
lblStatusST.Text = runningThreadCount.ToString() + "/" + (totalThreadCount == 0 ? AppSettings.DownloadMaxThreadCount.ToString() : totalThreadCount.ToString()) + " threads, " +
452452
lvItems.Items.Count.ToString() + " items, " +
453453
Interlocked.Read(ref successCount).ToString() + " succeed";
454454
lblStatusST.ToolTipText = lvItems.Items.Count.ToString() + " items, "

Sample/Sample_0_FileExplorer/Forms/frmMain.cs

+6
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,12 @@ private void ReadAppSettings()
407407
AppSettings.AutomaticUploadMaxThreadCount = true;
408408
AppSettings.RetryWhenUploadFailed = false;
409409
AppSettings.UploadMaxThreadCount = 1;
410+
AppSettings.MaxCacheSize = 1024;
411+
}
412+
else
413+
{
414+
if (AppSettings.MaxCacheSize == 0)
415+
AppSettings.MaxCacheSize = 1024;
410416
}
411417
}
412418

0 commit comments

Comments
 (0)