Explorar o código

Disard cache when checking checksum

This will slow down checksum checking but does not thrash cache.
Tatsuhiro Tsujikawa %!s(int64=11) %!d(string=hai) anos
pai
achega
8750d7be99

+ 1 - 0
configure.ac

@@ -724,6 +724,7 @@ AC_CHECK_FUNCS([__argz_count \
                 mmap \
                 munmap \
                 nl_langinfo \
+		posix_fadvise \
                 posix_memalign \
 		pow \
                 putenv \

+ 8 - 0
src/AbstractDiskWriter.cc

@@ -38,6 +38,7 @@
 #ifdef HAVE_MMAP
 #  include <sys/mman.h>
 #endif // HAVE_MMAP
+#include <fcntl.h>
 
 #include <cerrno>
 #include <cstring>
@@ -547,4 +548,11 @@ void AbstractDiskWriter::enableMmap()
   enableMmap_ = true;
 }
 
+void AbstractDiskWriter::dropCache(int64_t len, int64_t offset)
+{
+#ifdef HAVE_POSIX_FADVISE
+  posix_fadvise(fd_, offset, len, POSIX_FADV_DONTNEED);
+#endif // HAVE_POSIX_FADVISE
+}
+
 } // namespace aria2

+ 2 - 0
src/AbstractDiskWriter.h

@@ -96,6 +96,8 @@ public:
   virtual void disableReadOnly() CXX11_OVERRIDE;
 
   virtual void enableMmap() CXX11_OVERRIDE;
+
+  virtual void dropCache(int64_t len, int64_t offset) CXX11_OVERRIDE;
 };
 
 } // namespace aria2

+ 12 - 0
src/AbstractSingleDiskAdaptor.cc

@@ -83,6 +83,18 @@ ssize_t AbstractSingleDiskAdaptor::readData
   return diskWriter_->readData(data, len, offset);
 }
 
+ssize_t AbstractSingleDiskAdaptor::readDataDropCache
+(unsigned char* data, size_t len, int64_t offset)
+{
+  auto rv = readData(data, len, offset);
+
+  if(rv > 0) {
+    diskWriter_->dropCache(len, offset);
+  }
+
+  return rv;
+}
+
 void AbstractSingleDiskAdaptor::writeCache(const WrDiskCacheEntry* entry)
 {
   // Write cached data in 4KiB aligned offset. This reduces disk

+ 4 - 0
src/AbstractSingleDiskAdaptor.h

@@ -66,6 +66,10 @@ public:
   virtual ssize_t readData(unsigned char* data, size_t len, int64_t offset)
     CXX11_OVERRIDE;
 
+  virtual ssize_t readDataDropCache(unsigned char* data, size_t len,
+                                    int64_t offset)
+    CXX11_OVERRIDE;
+
   virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
 
   virtual bool fileExists() CXX11_OVERRIDE;

+ 4 - 0
src/DiskAdaptor.h

@@ -107,6 +107,10 @@ public:
   // successfully changed.
   virtual size_t utime(const Time& actime, const Time& modtime) = 0;
 
+  // Just like readData(), but drop cache after read.
+  virtual ssize_t readDataDropCache(unsigned char* data, size_t len,
+                                    int64_t offset) = 0;
+
   // Writes cached data to the underlying disk.
   virtual void writeCache(const WrDiskCacheEntry* entry) = 0;
 

+ 3 - 0
src/DiskWriter.h

@@ -82,6 +82,9 @@ public:
 
   // Enables mmap.
   virtual void enableMmap() {}
+
+  // Drops cache in range [offset, offset + len)
+  virtual void dropCache(int64_t len, int64_t offset) {}
 };
 
 } // namespace aria2

+ 1 - 1
src/IteratableChecksumValidator.cc

@@ -64,7 +64,7 @@ void IteratableChecksumValidator::validateChunk()
   // Don't guard with !finished() to allow zero-length file to be
   // verified.
   unsigned char buf[4096];
-  size_t length = pieceStorage_->getDiskAdaptor()->readData
+  size_t length = pieceStorage_->getDiskAdaptor()->readDataDropCache
     (buf, sizeof(buf), currentOffset_);
   ctx_->update(buf, length);
   currentOffset_ += length;

+ 1 - 1
src/IteratableChunkChecksumValidator.cc

@@ -125,7 +125,7 @@ std::string IteratableChunkChecksumValidator::digest(int64_t offset, size_t leng
   ctx_->reset();
   int64_t max = offset+length;
   while(offset < max) {
-    size_t r = pieceStorage_->getDiskAdaptor()->readData
+    size_t r = pieceStorage_->getDiskAdaptor()->readDataDropCache
       (buf, std::min(static_cast<int64_t>(sizeof(buf)), max-offset), offset);
     if(r == 0) {
       throw DL_ABORT_EX

+ 15 - 0
src/MultiDiskAdaptor.cc

@@ -366,6 +366,18 @@ void MultiDiskAdaptor::writeData(const unsigned char* data, size_t len,
 
 ssize_t MultiDiskAdaptor::readData
 (unsigned char* data, size_t len, int64_t offset)
+{
+  return readData(data, len, offset, false);
+}
+
+ssize_t MultiDiskAdaptor::readDataDropCache
+(unsigned char* data, size_t len, int64_t offset)
+{
+  return readData(data, len, offset, true);
+}
+
+ssize_t MultiDiskAdaptor::readData
+(unsigned char* data, size_t len, int64_t offset, bool dropCache)
 {
   auto first = findFirstDiskWriterEntry(diskWriterEntries_, offset);
   ssize_t rem = len;
@@ -380,6 +392,9 @@ ssize_t MultiDiskAdaptor::readData
     totalReadLength +=
       (*i)->getDiskWriter()->readData(data+(len-rem), readLength, fileOffset);
     rem -= readLength;
+    if(dropCache) {
+      (*i)->getDiskWriter()->dropCache(readLength, fileOffset);
+    }
     fileOffset = 0;
     if(rem == 0) {
       break;

+ 7 - 0
src/MultiDiskAdaptor.h

@@ -123,6 +123,9 @@ private:
 
   void openIfNot(DiskWriterEntry* entry, void (DiskWriterEntry::*f)());
 
+  ssize_t readData(unsigned char* data, size_t len, int64_t offset,
+                   bool dropCache);
+
   static const int DEFAULT_MAX_OPEN_FILES = 100;
 
 public:
@@ -143,6 +146,10 @@ public:
   virtual ssize_t readData(unsigned char* data, size_t len, int64_t offset)
     CXX11_OVERRIDE;
 
+  virtual ssize_t readDataDropCache(unsigned char* data, size_t len,
+                                    int64_t offset)
+    CXX11_OVERRIDE;
+
   virtual void writeCache(const WrDiskCacheEntry* entry) CXX11_OVERRIDE;
 
   virtual bool fileExists() CXX11_OVERRIDE;