public void CacheMap_GetOneMisingChunk() { var cm = new CacheMap(); cm.SetCached(0, 32); var missing = cm.GetMissingChunks(33, 10); Assert.AreEqual(1, missing.Count); Assert.AreEqual(new CachedFileChunk(33, 10), missing[0]); }
/// <summary> /// Reads buffer from backing stream /// </summary> /// <param name="buffer">Buffer that will hold </param> /// <param name="offset">Offset in a backing stream to start reading from</param> /// <param name="count">Maximum bytes to be read from stream</param> /// <returns>Number of bytes actually read</returns> public override int Read(byte[] buffer, int offset, int count) { // make sure we're not reading beyond the end of file if (offset > Length) { _log.Trace("Trying to read beyond the end of file."); return(0); } if (offset <= Length && (offset + count - 1) > Length) { count = (int)Length - offset; _log.Trace("This chunk is longer than our file stream. Trimed it down to {0} ({1}).", offset, count); } if (!_cacheMap.IsCached(offset, count)) { _log.Trace(String.Format("Chunk {0} ({1}) is not cached", offset, count)); var chunkList = _cacheMap.GetMissingChunks(offset, count); _log.Trace(String.Format("Will download {0} chunks", chunkList.Count)); foreach (var chunk in chunkList) { _log.Trace("Chunk #{0}", chunk); } var doneEvents = new ManualResetEvent[chunkList.Count]; for (var i = 0; i < chunkList.Count; i++) { var cachedFileChunk = chunkList[i]; doneEvents[i] = cachedFileChunk.DoneEvent; ThreadPool.QueueUserWorkItem(DownloadChunk, cachedFileChunk); } do { DokanNet.DokanResetTimeout(15000, _dokanInfo); // keep extending our time so OS will know we're still alive } while (!WaitHandle.WaitAll(doneEvents, 5000)); } else { _log.Trace(String.Format("Chunk {0} ({1}) is cached, reading it", offset, count)); } lock (_innerStream) { _innerStream.Position = _readPosition; _innerStream.Seek(offset, SeekOrigin.Begin); var read = _innerStream.Read(buffer, 0, count); _readPosition = _innerStream.Position; return(read); } }
public void CacheMap_GetMisingChunks() { var cm = new CacheMap(); cm.SetCached(5, 4); // overlaps with the second one cm.SetCached(1, 9); // overlaps with previous one cm.SetCached(20, 10); // has a gap before cm.SetCached(15, 1); // is adjascent to the next one cm.SetCached(16, 1); // is adjascent to the next one var missing = cm.GetMissingChunks(0, 31); Assert.AreEqual(4, missing.Count); Assert.AreEqual(new CachedFileChunk(new Range <int>(0, 0)), missing[0]); Assert.AreEqual(new CachedFileChunk(new Range <int>(10, 14)), missing[1]); Assert.AreEqual(new CachedFileChunk(new Range <int>(17, 19)), missing[2]); Assert.AreEqual(new CachedFileChunk(new Range <int>(30, 30)), missing[3]); }