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 // 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(currentSize - size_read), static_cast(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;