All pastes #165966 Raw Edit

Something

public text v1 · immutable
·published 2006-09-10 11:53 UTC
rendered paste body
diff -u old_client/HashManager.cpp client/HashManager.cpp
--- old_client/HashManager.cpp	2006-06-23 22:51:48.000000000 +0300
+++ client/HashManager.cpp	2006-09-10 13:22:08.000000000 +0300
@@ -1,3 +1,4 @@
+// vim: ai ts=4 sts=4 noet sw=4
 /*
  * Copyright (C) 2001-2006 Jacek Sieka, arnetheduck on gmail point com
  *
@@ -27,6 +28,10 @@
 #include "ZUtils.h"
 #include "SFVReader.h"
 
+#ifndef _WIN32
+#include <sys/mman.h> // mmap, munmap, madvise
+#endif
+
 #define HASH_FILE_VERSION_STRING "2"
 static const u_int32_t HASH_FILE_VERSION=2;
 const int64_t HashManager::MIN_BLOCK_SIZE = 64*1024;
@@ -438,9 +443,10 @@
 	}
 }
 
+#ifdef _WIN32
+
 #define BUF_SIZE (256*1024)
 
-#ifdef _WIN32
 bool HashManager::Hasher::fastHash(const string& fname, u_int8_t* buf, TigerTree& tth, int64_t size, CRC32Filter* xcrc32) {
 	HANDLE h = INVALID_HANDLE_VALUE;
 	DWORD x, y;
@@ -545,6 +551,67 @@
 	::CloseHandle(h);
 	return ok;
 }
+
+#else
+
+static const int64_t BUF_SIZE = 0x1000000 - (0x1000000 % getpagesize());
+
+bool HashManager::Hasher::fastHash(const string& filename, u_int8_t* , TigerTree& tth, int64_t size, CRC32Filter* xcrc32) {
+	int fd = open(filename.c_str(), O_RDONLY | O_LARGEFILE);
+	if(fd == -1)
+		return false;
+
+	int64_t size_left = size;
+	int64_t pos = 0;
+	int64_t size_read = 0;
+	void *buf = 0;
+
+	u_int32_t lastRead = GET_TICK();
+	while(pos < size) {
+		size_read = std::min(size_left, BUF_SIZE);
+		buf = mmap(0, size_read, PROT_READ, MAP_SHARED, fd, pos);
+		if(buf == MAP_FAILED) {
+			close(fd);
+			return false;
+		}
+
+		madvise(buf, size_read, MADV_SEQUENTIAL | MADV_WILLNEED);
+
+		if(SETTING(MAX_HASH_SPEED) > 0) {
+			u_int32_t now = GET_TICK();
+			// XXX is this correct?
+			u_int32_t minTime = size_read * 1000LL / (SETTING(MAX_HASH_SPEED) * 1024LL * 1024LL);
+			if(lastRead + minTime > now) {
+				u_int32_t diff = now - lastRead;
+				Thread::sleep(minTime - diff);
+			}
+			lastRead = lastRead + minTime;
+		} else {
+			lastRead = GET_TICK();
+		}
+
+		tth.update(buf, size_read);
+		if(xcrc32) {
+			(*xcrc32)(buf, size_read);
+		}
+
+		{
+			Lock lock(cs);
+			currentSize =  max(static_cast<u_int64_t>(currentSize - size_read), static_cast<u_int64_t>(0));
+		}
+		munmap(buf, size_read);
+		pos += size_read;
+		size_left -= size_read;
+	}
+	return true;
+}
+
 #endif
 
 int HashManager::Hasher::run() {
@@ -607,13 +674,16 @@
 					xcrc32 = &crc32;
 
 				size_t n = 0;
-#ifdef _WIN32
 				TigerTree fastTTH(bs);
 				tth = &fastTTH;
+#ifdef _WIN32
 				if(!virtualBuf || !fastHash(fname, buf, fastTTH, size, xcrc32)) {
+#else
+				if(!fastHash(fname, 0, fastTTH, size, xcrc32)) {
+#endif
 					tth = &slowTTH;
 					crc32 = CRC32Filter();
-#endif
 					u_int32_t lastRead = GET_TICK();
 
 					do {
@@ -638,11 +708,9 @@
 						}
 						sizeLeft -= n;
 					} while (n > 0 && !stop);
-#ifdef _WIN32
 				} else {
 					sizeLeft = 0;
 				}
-#endif
 				f.close();
 				tth->finalize();
 				u_int32_t end = GET_TICK();
diff -u old_client/HashManager.h client/HashManager.h
--- old_client/HashManager.h	2006-06-15 21:30:50.000000000 +0300
+++ client/HashManager.h	2006-09-10 11:34:27.000000000 +0300
@@ -139,9 +139,7 @@
 		}
 
 		virtual int run();
-#ifdef _WIN32
 		bool fastHash(const string& fname, u_int8_t* buf, TigerTree& tth, int64_t size, CRC32Filter* xcrc32);
-#endif
 		void getStats(string& curFile, int64_t& bytesLeft, size_t& filesLeft) {
 			Lock l(cs);
 			curFile = currentFile;