← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2781: Use FileReader for hashmanager, remove fasthash option

 

------------------------------------------------------------
revno: 2781
committer: Jacek Sieka <arnetheduck@xxxxxxxxx>
branch nick: dcplusplus
timestamp: Sun 2012-01-01 15:22:32 +0100
message:
  Use FileReader for hashmanager, remove fasthash option
modified:
  dcpp/File.cpp
  dcpp/FileReader.cpp
  dcpp/FileReader.h
  dcpp/HashManager.cpp
  dcpp/SettingsManager.cpp
  dcpp/SettingsManager.h
  utils/xsum.cpp
  win32/AdvancedPage.cpp


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'dcpp/File.cpp'
--- dcpp/File.cpp	2011-04-13 19:16:51 +0000
+++ dcpp/File.cpp	2012-01-01 14:22:32 +0000
@@ -80,13 +80,12 @@
 }
 
 int64_t File::getSize() noexcept {
-	DWORD x;
-	DWORD l = ::GetFileSize(h, &x);
-
-	if( (l == INVALID_FILE_SIZE) && (GetLastError() != NO_ERROR))
+	LARGE_INTEGER x;
+	if(!::GetFileSizeEx(h, &x)) {
 		return -1;
+	}
 
-	return (int64_t)l | ((int64_t)x)<<32;
+	return x.QuadPart;
 }
 int64_t File::getPos() noexcept {
 	LONG x = 0;

=== modified file 'dcpp/FileReader.cpp'
--- dcpp/FileReader.cpp	2011-12-31 15:13:51 +0000
+++ dcpp/FileReader.cpp	2012-01-01 14:22:32 +0000
@@ -43,8 +43,9 @@
 
 	size_t total = 0;
 	size_t n = buffer.size();
-	while(f.read(buf, n) > 0) {
-		callback(buf, n);
+	bool go = true;
+	while(f.read(buf, n) > 0 && go) {
+		go = callback(buf, n);
 		total += n;
 		n = buffer.size();
 	}
@@ -129,13 +130,14 @@
 	}
 	over.Offset = hn;
 
-	for (; hn == bufSize;) {
+	bool go = true;
+	for (; hn == bufSize && go;) {
 		// Start a new overlapped read
 		res = ::ReadFile(h, rbuf, bufSize, NULL, &over);
 		auto err = ::GetLastError();
 
 		// Process the previously read data
-		callback(hbuf, hn);
+		go = callback(hbuf, hn);
 
 		if (!res && err != ERROR_IO_PENDING) {
 			if(err != ERROR_HANDLE_EOF) {
@@ -201,14 +203,15 @@
 	auto blockSize = getBlockSize(si.dwPageSize);
 
 	LARGE_INTEGER total = { 0 };
-	while(size.QuadPart > 0) {
+	bool go = true;
+	while(size.QuadPart > 0 && go) {
 		auto n = min(size.QuadPart, (int64_t)blockSize);
 		auto p = ::MapViewOfFile(hmap, FILE_MAP_READ, total.HighPart, total.LowPart, static_cast<DWORD>(n));
 		if(!p) {
 			throw FileException(Util::translateError(::GetLastError()));
 		}
 
-		callback(p, n);
+		go = callback(p, n);
 
 		if(!::UnmapViewOfFile(p)) {
 			throw FileException(Util::translateError(::GetLastError()));
@@ -223,12 +226,98 @@
 
 #else
 
+#include <sys/mman.h> // mmap, munmap, madvise
+#include <signal.h>  // for handling read errors from previous trio
+#include <setjmp.h>
+
 size_t FileReader::readDirect(const string& file, const DataCallback& callback) {
 	return READ_FAILED;
 }
 
-size_t FileReader::readMapped(const string& file, const DataCallback& callback) {
-	return READ_FAILED;
+static const int64_t BUF_SIZE = 0x1000000 - (0x1000000 % getpagesize());
+static sigjmp_buf sb_env;
+
+static void sigbus_handler(int signum, siginfo_t* info, void* context) {
+	// Jump back to the readMapped which will return error. Apparently truncating
+	// a file in Solaris sets si_code to BUS_OBJERR
+	if (signum == SIGBUS && (info->si_code == BUS_ADRERR || info->si_code == BUS_OBJERR))
+		siglongjmp(sb_env, 1);
+}
+
+size_t FileReader::readMapped(const string& filename, const DataCallback& callback) {
+	int fd = open(Text::fromUtf8(filename).c_str(), O_RDONLY);
+	if(fd == -1) {
+		dcdebug("Error opening file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
+		return READ_FAILED;
+	}
+
+	int64_t pos = 0;
+	auto size =0;
+
+	// Prepare and setup a signal handler in case of SIGBUS during mmapped file reads.
+	// SIGBUS can be sent when the file is truncated or in case of read errors.
+	struct sigaction act, oldact;
+	sigset_t signalset;
+
+	sigemptyset(&signalset);
+
+	act.sa_handler = NULL;
+	act.sa_sigaction = sigbus_handler;
+	act.sa_mask = signalset;
+	act.sa_flags = SA_SIGINFO | SA_RESETHAND;
+
+	if (sigaction(SIGBUS, &act, &oldact) == -1) {
+		dcdebug("Failed to set signal handler for fastHash\n");
+		close(fd);
+		return READ_FAILED;	// Better luck with the slow hash.
+	}
+
+	void* buf = NULL;
+	int64_t size_read = 0;
+
+	uint64_t lastRead = GET_TICK();
+	while (pos < size) {
+		size_read = std::min(size - pos, BUF_SIZE);
+		buf = mmap(0, size_read, PROT_READ, MAP_SHARED, fd, pos);
+		if (buf == MAP_FAILED) {
+			dcdebug("Error calling mmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
+			break;
+		}
+
+		if (sigsetjmp(sb_env, 1)) {
+			dcdebug("Caught SIGBUS for file %s\n", filename.c_str());
+			break;
+		}
+
+		if (posix_madvise(buf, size_read, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) == -1) {
+			dcdebug("Error calling madvise for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
+			break;
+		}
+
+		if(!callback(buf, size_read)) {
+			break;
+		}
+
+		if (munmap(buf, size_read) == -1) {
+			dcdebug("Error calling munmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
+			break;
+		}
+
+		buf = NULL;
+		pos += size_read;
+	}
+
+	if (buf != NULL && buf != MAP_FAILED && munmap(buf, size_read) == -1) {
+		dcdebug("Error calling munmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
+	}
+
+	::close(fd);
+
+	if (sigaction(SIGBUS, &oldact, NULL) == -1) {
+		dcdebug("Failed to reset old signal handler for SIGBUS\n");
+	}
+
+	return pos == size ? pos : READ_FAILED;
 }
 
 #endif

=== modified file 'dcpp/FileReader.h'
--- dcpp/FileReader.h	2011-12-31 15:13:51 +0000
+++ dcpp/FileReader.h	2012-01-01 14:22:32 +0000
@@ -43,7 +43,7 @@
 		CACHED
 	};
 
-	typedef function<void(void*, size_t)> DataCallback;
+	typedef function<bool(const void*, size_t)> DataCallback;
 
 	/**
 	 * Set up file reader
@@ -60,6 +60,7 @@
 	 * @throw FileException if the read fails
 	 */
 	size_t read(const string& file, const DataCallback& callback);
+
 private:
 	static const size_t DEFAULT_BLOCK_SIZE = 64*1024;
 	static const size_t DEFAULT_MMAP_SIZE = 64*1024*1024;

=== modified file 'dcpp/HashManager.cpp'
--- dcpp/HashManager.cpp	2011-12-22 22:14:45 +0000
+++ dcpp/HashManager.cpp	2012-01-01 14:22:32 +0000
@@ -24,15 +24,10 @@
 #include "SimpleXML.h"
 #include "LogManager.h"
 #include "File.h"
+#include "FileReader.h"
 #include "ZUtils.h"
 #include "SFVReader.h"
 
-#ifndef _WIN32
-#include <sys/mman.h> // mmap, munmap, madvise
-#include <signal.h>  // for handling read errors from previous trio
-#include <setjmp.h>
-#endif
-
 namespace dcpp {
 
 using std::swap;
@@ -384,7 +379,6 @@
 static const string sType = "Type";
 static const string sTTH = "TTH";
 static const string sIndex = "Index";
-static const string sLeafSize = "LeafSize"; // Residue from v1 as well
 static const string sBlockSize = "BlockSize";
 static const string sTimeStamp = "TimeStamp";
 static const string sRoot = "Root";
@@ -533,236 +527,11 @@
 		s.wait();
 }
 
-#ifdef _WIN32
-#define BUF_SIZE (256*1024)
-
-bool HashManager::Hasher::fastHash(const string& fname, uint8_t* buf, TigerTree& tth, int64_t size, CRC32Filter* xcrc32) {
-	HANDLE h = INVALID_HANDLE_VALUE;
-	DWORD x, y;
-	if (!GetDiskFreeSpace(Text::toT(Util::getFilePath(fname)).c_str(), &y, &x, &y, &y)) {
-		return false;
-	} else {
-		if ((BUF_SIZE % x) != 0) {
-			return false;
-		} else {
-			h = ::CreateFile(Text::toT(fname).c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
-			    FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, NULL);
-			if (h == INVALID_HANDLE_VALUE)
-				return false;
-		}
-	}
-	DWORD hn = 0;
-	DWORD rn = 0;
-	uint8_t* hbuf = buf + BUF_SIZE;
-	uint8_t* rbuf = buf;
-
-	OVERLAPPED over = { 0 };
-	BOOL res = TRUE;
-	over.hEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
-
-	bool ok = false;
-
-	uint64_t lastRead = GET_TICK();
-	if (!::ReadFile(h, hbuf, BUF_SIZE, &hn, &over)) {
-		if (GetLastError() == ERROR_HANDLE_EOF) {
-			hn = 0;
-		} else if (GetLastError() == ERROR_IO_PENDING) {
-			if (!GetOverlappedResult(h, &over, &hn, TRUE)) {
-				if (GetLastError() == ERROR_HANDLE_EOF) {
-					hn = 0;
-				} else {
-					goto cleanup;
-				}
-			}
-		} else {
-			goto cleanup;
-		}
-	}
-
-	over.Offset = hn;
-	size -= hn;
-	while (!stop) {
-		if (size > 0) {
-			// Start a new overlapped read
-			ResetEvent(over.hEvent);
-			if (SETTING(MAX_HASH_SPEED) > 0) {
-				uint64_t now = GET_TICK();
-				uint64_t minTime = hn * 1000LL / (SETTING(MAX_HASH_SPEED) * 1024LL * 1024LL);
-				if (lastRead + minTime > now) {
-					uint64_t diff = now - lastRead;
-					Thread::sleep(minTime - diff);
-				}
-				lastRead = lastRead + minTime;
-			} else {
-				lastRead = GET_TICK();
-			}
-			res = ReadFile(h, rbuf, BUF_SIZE, &rn, &over);
-		} else {
-			rn = 0;
-		}
-
-		tth.update(hbuf, hn);
-		if (xcrc32)
-			(*xcrc32)(hbuf, hn);
-
-		{
-			Lock l(cs);
-			currentSize = max(currentSize - hn, _LL(0));
-		}
-
-		if (size == 0) {
-			ok = true;
-			break;
-		}
-
-		if (!res) {
-			// deal with the error code
-			switch (GetLastError()) {
-			case ERROR_IO_PENDING:
-				if (!GetOverlappedResult(h, &over, &rn, TRUE)) {
-					dcdebug("Error 0x%x: %s\n", GetLastError(), Util::translateError(GetLastError()).c_str());
-					goto cleanup;
-				}
-				break;
-				default:
-				dcdebug("Error 0x%x: %s\n", GetLastError(), Util::translateError(GetLastError()).c_str());
-				goto cleanup;
-			}
-		}
-
-		instantPause();
-
-		*((uint64_t*)&over.Offset) += rn;
-		size -= rn;
-
-		swap(rbuf, hbuf);
-		swap(rn, hn);
-	}
-
-	cleanup:
-	::CloseHandle(over.hEvent);
-	::CloseHandle(h);
-	return ok;
-}
-
-#else // !_WIN32
-static const int64_t BUF_SIZE = 0x1000000 - (0x1000000 % getpagesize());
-static sigjmp_buf sb_env;
-
-static void sigbus_handler(int signum, siginfo_t* info, void* context) {
-	// Jump back to the fastHash which will return error. Apparently truncating
-	// a file in Solaris sets si_code to BUS_OBJERR
-	if (signum == SIGBUS && (info->si_code == BUS_ADRERR || info->si_code == BUS_OBJERR))
-		siglongjmp(sb_env, 1);
-}
-
-bool HashManager::Hasher::fastHash(const string& filename, uint8_t* , TigerTree& tth, int64_t size, CRC32Filter* xcrc32) {
-	int fd = open(Text::fromUtf8(filename).c_str(), O_RDONLY);
-	if(fd == -1) {
-		dcdebug("Error opening file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
-		return false;
-	}
-
-	int64_t pos = 0;
-	int64_t size_read = 0;
-	void *buf = NULL;
-	bool ok = false;
-
-	// Prepare and setup a signal handler in case of SIGBUS during mmapped file reads.
-	// SIGBUS can be sent when the file is truncated or in case of read errors.	 
-	struct sigaction act, oldact;
-	sigset_t signalset;
-
-	sigemptyset(&signalset);
-
-	act.sa_handler = NULL;
-	act.sa_sigaction = sigbus_handler;
-	act.sa_mask = signalset;
-	act.sa_flags = SA_SIGINFO | SA_RESETHAND;
-
-	if (sigaction(SIGBUS, &act, &oldact) == -1) {
-		dcdebug("Failed to set signal handler for fastHash\n");
-		close(fd);
-		return false;	// Better luck with the slow hash.
-	}
-
-	uint64_t lastRead = GET_TICK();
-	while (pos < size && !stop) {
-		size_read = std::min(size - pos, BUF_SIZE);
-		buf = mmap(0, size_read, PROT_READ, MAP_SHARED, fd, pos);
-		if (buf == MAP_FAILED) {
-			dcdebug("Error calling mmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
-			break;
-		}
-
-		if (sigsetjmp(sb_env, 1)) {
-			dcdebug("Caught SIGBUS for file %s\n", filename.c_str());
-			break;
-		}
-
-		if (posix_madvise(buf, size_read, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) == -1) {
-			dcdebug("Error calling madvise for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
-			break;
-		}
-
-		if (SETTING(MAX_HASH_SPEED) > 0) {
-			uint64_t now = GET_TICK();
-			uint64_t minTime = size_read * 1000LL / (SETTING(MAX_HASH_SPEED) * 1024LL * 1024LL);
-			if (lastRead + minTime > now) {
-				uint64_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 l(cs);
-			currentSize = max(static_cast<uint64_t>(currentSize - size_read), static_cast<uint64_t>(0));
-		}
-
-		if (munmap(buf, size_read) == -1) {
-			dcdebug("Error calling munmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
-			break;
-		}
-
-		buf = NULL;
-		pos += size_read;
-
-		instantPause();
-
-		if (pos == size) {
-			ok = true;
-		}
-	}
-
-	if (buf != NULL && buf != MAP_FAILED && munmap(buf, size_read) == -1) {
-		dcdebug("Error calling munmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str());
-	}
-
-	close(fd);
-
-	if (sigaction(SIGBUS, &oldact, NULL) == -1) {
-		dcdebug("Failed to reset old signal handler for SIGBUS\n");
-	}
-
-	return ok;
-}
-
-#endif // !_WIN32
 int HashManager::Hasher::run() {
 	setThreadPriority(Thread::IDLE);
 
-	uint8_t* buf = NULL;
-	bool virtualBuf = true;
-
 	string fname;
-	bool last = false;
+
 	for(;;) {
 		s.wait();
 		if(stop)
@@ -779,34 +548,24 @@
 				currentFile = fname = w.begin()->first;
 				currentSize = w.begin()->second;
 				w.erase(w.begin());
-				last = w.empty();
 			} else {
-				last = true;
 				fname.clear();
 			}
 		}
 		running = true;
 
 		if(!fname.empty()) {
-			int64_t size = File::getSize(fname);
-			int64_t sizeLeft = size;
-#ifdef _WIN32
-			if(buf == NULL) {
-				virtualBuf = true;
-				buf = (uint8_t*)VirtualAlloc(NULL, 2*BUF_SIZE, MEM_COMMIT, PAGE_READWRITE);
-			}
-#endif
-			if(buf == NULL) {
-				virtualBuf = false;
-				buf = new uint8_t[BUF_SIZE];
-			}
 			try {
+				auto start = GET_TICK();
+
 				File f(fname, File::READ, File::OPEN);
-				int64_t bs = max(TigerTree::calcBlockSize(f.getSize(), 10), MIN_BLOCK_SIZE);
-				uint64_t start = GET_TICK();
-				uint32_t timestamp = f.getLastModified();
-				TigerTree slowTTH(bs);
-				TigerTree* tth = &slowTTH;
+				auto size = f.getSize();
+				auto timestamp = f.getLastModified();
+
+				auto sizeLeft = size;
+				auto bs = max(TigerTree::calcBlockSize(size, 10), MIN_BLOCK_SIZE);
+
+				TigerTree tt(bs);
 
 				CRC32Filter crc32;
 				SFVReader sfv(fname);
@@ -814,58 +573,48 @@
 				if(sfv.hasCRC())
 					xcrc32 = &crc32;
 
-				size_t n = 0;
-				TigerTree fastTTH(bs);
-				tth = &fastTTH;
-#ifdef _WIN32
-				if(!virtualBuf || !BOOLSETTING(FAST_HASH) || !fastHash(fname, buf, fastTTH, size, xcrc32)) {
-#else
-				if(!BOOLSETTING(FAST_HASH) || !fastHash(fname, 0, fastTTH, size, xcrc32)) {
-#endif
-					tth = &slowTTH;
-					crc32 = CRC32Filter();
-					uint64_t lastRead = GET_TICK();
-
-					do {
-						size_t bufSize = BUF_SIZE;
-						if(SETTING(MAX_HASH_SPEED)> 0) {
-							uint64_t now = GET_TICK();
-							uint64_t minTime = n * 1000LL / (SETTING(MAX_HASH_SPEED) * 1024LL * 1024LL);
-							if(lastRead + minTime> now) {
-								Thread::sleep(minTime - (now - lastRead));
-							}
-							lastRead = lastRead + minTime;
-						} else {
-							lastRead = GET_TICK();
-						}
-						n = f.read(buf, bufSize);
-						tth->update(buf, n);
-						if(xcrc32)
-							(*xcrc32)(buf, n);
-
-						{
-							Lock l(cs);
-							currentSize = max(static_cast<uint64_t>(currentSize - n), static_cast<uint64_t>(0));
-						}
-						sizeLeft -= n;
-
-						instantPause();
-					}while (n> 0 && !stop);
-				} else {
-					sizeLeft = 0;
-				}
+				auto lastRead = GET_TICK();
+
+				FileReader fr;
+
+				fr.read(fname, [&](const void* buf, size_t n) -> bool {
+					if(SETTING(MAX_HASH_SPEED)> 0) {
+						uint64_t now = GET_TICK();
+						uint64_t minTime = n * 1000LL / (SETTING(MAX_HASH_SPEED) * 1024LL * 1024LL);
+						if(lastRead + minTime> now) {
+							Thread::sleep(minTime - (now - lastRead));
+						}
+						lastRead = lastRead + minTime;
+					} else {
+						lastRead = GET_TICK();
+					}
+
+					tt.update(buf, n);
+					if(xcrc32)
+						(*xcrc32)(buf, n);
+
+					{
+						Lock l(cs);
+						currentSize = max(static_cast<uint64_t>(currentSize - n), static_cast<uint64_t>(0));
+					}
+					sizeLeft -= n;
+
+					instantPause();
+					return !stop;
+				});
 
 				f.close();
-				tth->finalize();
+				tt.finalize();
 				uint64_t end = GET_TICK();
 				int64_t speed = 0;
-				if(end> start) {
-					speed = size * _LL(1000) / (end - start);
+				if(end > start) {
+					speed = size * 1000 / (end - start);
 				}
+
 				if(xcrc32 && xcrc32->getValue() != sfv.getCRC()) {
 					LogManager::getInstance()->message(str(F_("%1% not shared; calculated CRC32 does not match the one found in SFV file.") % Util::addBrackets(fname)));
 				} else {
-					HashManager::getInstance()->hashDone(fname, timestamp, *tth, speed, size);
+					HashManager::getInstance()->hashDone(fname, timestamp, tt, speed, size);
 				}
 			} catch(const FileException& e) {
 				LogManager::getInstance()->message(str(F_("Error hashing %1%: %2%") % Util::addBrackets(fname) % e.getError()));
@@ -877,16 +626,6 @@
 			currentSize = 0;
 		}
 		running = false;
-		if(buf != NULL && (last || stop)) {
-			if(virtualBuf) {
-#ifdef _WIN32
-				VirtualFree(buf, 0, MEM_RELEASE);
-#endif
-			} else {
-				delete [] buf;
-			}
-			buf = NULL;
-		}
 	}
 	return 0;
 }

=== modified file 'dcpp/SettingsManager.cpp'
--- dcpp/SettingsManager.cpp	2011-12-26 12:53:16 +0000
+++ dcpp/SettingsManager.cpp	2012-01-01 14:22:32 +0000
@@ -82,7 +82,7 @@
 	"BoldSystemLog", "AutoRefreshTime",
 	"UseTLS", "AutoSearchLimit", "AltSortOrder", "AutoKickNoFavs", "PromptPassword", "SpyFrameIgnoreTthSearches",
 	"DontDlAlreadyQueued", "MaxCommandLength", "AllowUntrustedHubs", "AllowUntrustedClients",
-	"TLSPort", "FastHash", "SortFavUsersFirst", "SegmentedDL", "FollowLinks",
+	"TLSPort", "SortFavUsersFirst", "SegmentedDL", "FollowLinks",
 	"SendBloom", "OwnerDrawnMenus", "Coral", "SearchFilterShared", "FinishedDLOnlyFull",
 	"ConfirmExit", "ConfirmHubClosing", "ConfirmHubRemoval", "ConfirmUserRemoval", "ConfirmItemRemoval", "ConfirmADLSRemoval",
 	"SearchMerge", "ToolbarSize", "TabWidth", "TabStyle",
@@ -283,7 +283,6 @@
 	setDefault(MAX_COMMAND_LENGTH, 16*1024*1024);
 	setDefault(ALLOW_UNTRUSTED_HUBS, true);
 	setDefault(ALLOW_UNTRUSTED_CLIENTS, true);
-	setDefault(FAST_HASH, true);
 	setDefault(SORT_FAVUSERS_FIRST, false);
 	setDefault(SEGMENTED_DL, true);
 	setDefault(FOLLOW_LINKS, false);

=== modified file 'dcpp/SettingsManager.h'
--- dcpp/SettingsManager.h	2011-12-03 21:53:57 +0000
+++ dcpp/SettingsManager.h	2012-01-01 14:22:32 +0000
@@ -100,7 +100,7 @@
 		BOLD_SYSTEM_LOG, AUTO_REFRESH_TIME,
 		USE_TLS, AUTO_SEARCH_LIMIT, ALT_SORT_ORDER, AUTO_KICK_NO_FAVS, PROMPT_PASSWORD, SPY_FRAME_IGNORE_TTH_SEARCHES,
 		DONT_DL_ALREADY_QUEUED, MAX_COMMAND_LENGTH, ALLOW_UNTRUSTED_HUBS, ALLOW_UNTRUSTED_CLIENTS,
-		TLS_PORT, FAST_HASH, SORT_FAVUSERS_FIRST, SEGMENTED_DL, FOLLOW_LINKS,
+		TLS_PORT, SORT_FAVUSERS_FIRST, SEGMENTED_DL, FOLLOW_LINKS,
 		SEND_BLOOM, OWNER_DRAWN_MENUS, CORAL, SEARCH_FILTER_SHARED, FINISHED_DL_ONLY_FULL,
 		CONFIRM_EXIT, CONFIRM_HUB_CLOSING, CONFIRM_HUB_REMOVAL, CONFIRM_USER_REMOVAL, CONFIRM_ITEM_REMOVAL, CONFIRM_ADLS_REMOVAL,
 		SEARCH_MERGE, TOOLBAR_SIZE, TAB_WIDTH, TAB_STYLE,

=== modified file 'utils/xsum.cpp'
--- utils/xsum.cpp	2011-12-31 15:50:55 +0000
+++ utils/xsum.cpp	2012-01-01 14:22:32 +0000
@@ -34,12 +34,14 @@
 
 		TigerTree tt;
 		size_t total = 0;
-		fr.read(x, [&](void* x, size_t n) {
+		fr.read(x, [&](const void* x, size_t n) -> bool {
 			tt.update(x, n);
 			total += n;
 			if(total % (1024*1024) == 0) {
 				std::cout << ".";
 			}
+
+			return true;
 		});
 
 		cout << endl << Encoder::toBase32(tt.finalize(), TigerTree::BYTES);

=== modified file 'win32/AdvancedPage.cpp'
--- win32/AdvancedPage.cpp	2011-05-04 19:32:00 +0000
+++ win32/AdvancedPage.cpp	2012-01-01 14:22:32 +0000
@@ -49,7 +49,6 @@
 	{ SettingsManager::OWNER_DRAWN_MENUS, N_("Use extended menus with icons and titles"), IDH_SETTINGS_ADVANCED_OWNER_DRAWN_MENUS },
 	{ SettingsManager::CORAL, N_("Use Coral network for HTTP downloads (improves reliability)"), IDH_SETTINGS_ADVANCED_CORAL },
 	{ SettingsManager::SEGMENTED_DL, N_("Enable segmented downloads"), IDH_SETTINGS_ADVANCED_SEGMENTED_DL },
-	{ SettingsManager::FAST_HASH, N_("Use fast hashing method (disable if you have problems with hashing)"), IDH_SETTINGS_ADVANCED_FAST_HASH },
 	{ 0, 0 }
 };