📄 tools.cc
字号:
void Tools::uncompressRLE( unsigned long blockSize, byte* in, unsigned long lin, byte** out, unsigned long& lout){ if (lin == 0) { *out = 0; lout = 0; return; } byte *data = 0, *pdata = 0, *pin;#ifdef _MSC_VER // MSVC doesn't like non-const array initialisers byte* cv = new byte[blockSize]; byte* pv = new byte[blockSize];#else byte cv[blockSize], pv[blockSize];#endif//_MSC_VER byte rl; unsigned long bufferLength = 2 * lin; pin = in; memcpy(cv, pin, blockSize); pv[0] = ~cv[0]; // force next character to be different. assert(pv[0] != cv[0]); data = new byte[bufferLength]; pdata = data; while (pin < in + lin) { memcpy(cv, pin, blockSize); pin += blockSize; assert(pin <= in + lin); if ( bufferLength - static_cast<unsigned long>(pdata - data) <= blockSize ) { byte* tmp; try { tmp = new byte[2 * bufferLength]; } catch(...) { delete[] data;#ifdef _MSC_VER delete[] cv; delete[] pv;#endif//_MSC_VER throw; } memcpy(tmp, data, bufferLength); pdata = tmp + (pdata - data); byte* tmp2 = data; data = tmp; delete[] tmp2; bufferLength *= 2; } memcpy(pdata, cv, blockSize); pdata += blockSize; if (memcmp(cv, pv, blockSize) == 0 && pin < in + lin) { memcpy(&rl, pin, sizeof(byte)); pin += sizeof(byte); assert(pin <= in + lin); if ( bufferLength - static_cast<unsigned long>(pdata - data) <= rl * blockSize ) { unsigned long l = std::max(bufferLength, rl * blockSize); byte* tmp; try { tmp = new byte[2 * l]; } catch(...) { delete[] data;#ifdef _MSC_VER delete[] cv; delete[] pv;#endif//_MSC_VER throw; } memcpy(tmp, data, bufferLength); pdata = tmp + (pdata - data); byte* tmp2 = data; data = tmp; delete[] tmp2; bufferLength = 2 * l; } while (rl > 0) { memcpy(pdata, cv, blockSize); pdata += blockSize; rl--; } memcpy(cv, pin, blockSize); pv[0] = ~cv[0]; assert(pv[0] != cv[0]); } else memcpy(pv, cv, blockSize); } lout = pdata - data; try { *out = new byte[lout]; } catch(...) { delete[] data;#ifdef _MSC_VER delete[] cv; delete[] pv;#endif//_MSC_VER throw; } memcpy(*out, data, lout); delete[] data;#ifdef _MSC_VER delete[] cv; delete[] pv;#endif//_MSC_VER}#if HAVE_GETTIMEOFDAYTools::ResourceUsage::ResourceUsage(){ reset();}void Tools::ResourceUsage::start(){ struct timezone dummy; if (getrusage(RUSAGE_SELF, &m_tmpRU) != 0) throw IllegalStateException( "Tools::ResourceUsage::start: getrusage failed." ); if (gettimeofday(&m_tmpTV, &dummy) != 0) throw IllegalStateException( "Tools::ResourceUsage::start: gettimeofday failed." ); // maximum resident set size m_peakMemory = std::max(m_peakMemory, m_tmpRU.ru_maxrss); // total memory m_totalMemory = std::max(m_totalMemory, m_tmpRU.ru_ixrss + m_tmpRU.ru_idrss + m_tmpRU.ru_isrss + m_tmpRU.ru_maxrss);}void Tools::ResourceUsage::stop(){ struct timezone dummy; struct timeval dif; struct rusage ru; struct timeval tv; if (getrusage(RUSAGE_SELF, &ru) != 0) throw IllegalStateException( "Tools::ResourceUsage::stop: getrusage failed." ); if (gettimeofday(&tv, &dummy) != 0) throw IllegalStateException( "Tools::ResourceUsage::stop: gettimeofday failed." ); // total_time subtractTimeval(dif, tv, m_tmpTV); addTimeval(m_totalTime, dif); // system_time subtractTimeval(dif, ru.ru_stime, m_tmpRU.ru_stime); addTimeval(m_systemTime, dif); // user_time subtractTimeval(dif, ru.ru_utime, m_tmpRU.ru_utime); addTimeval(m_userTime, dif); // readIO, writeIOs m_readIO += ru.ru_inblock - m_tmpRU.ru_inblock; m_writeIO += ru.ru_oublock - m_tmpRU.ru_oublock; // maximum resident set size m_peakMemory = std::max(m_peakMemory, ru.ru_maxrss); // total memory m_totalMemory = std::max(m_totalMemory, ru.ru_ixrss + ru.ru_idrss + ru.ru_isrss + ru.ru_maxrss); // page faults m_pageFaults += ru.ru_majflt - m_tmpRU.ru_majflt;}void Tools::ResourceUsage::reset(){ m_pageFaults = 0; m_readIO = 0; m_writeIO = 0; m_peakMemory = 0; m_totalMemory = 0; m_totalTime.tv_sec = 0; m_totalTime.tv_usec = 0; m_userTime.tv_sec = 0; m_userTime.tv_usec = 0; m_systemTime.tv_sec = 0; m_systemTime.tv_usec = 0;}double Tools::ResourceUsage::combineTime(const struct timeval& t){ return static_cast<double>(t.tv_sec) + static_cast<double>(t.tv_usec) / 1000000.0;}void Tools::ResourceUsage::addTimeval(struct timeval& result, const struct timeval& a){ result.tv_sec += a.tv_sec; result.tv_usec += a.tv_usec; if (result.tv_usec > 1000000) { long div = result.tv_usec / 1000000; result.tv_sec += div; result.tv_usec -= div * 1000000; }}void Tools::ResourceUsage::subtractTimeval(struct timeval& result, const struct timeval& a, const struct timeval& b){ result.tv_sec = a.tv_sec - b.tv_sec; result.tv_usec = a.tv_usec - b.tv_usec; if (result.tv_usec < 0) { result.tv_sec -= 1; result.tv_usec += 1000000; }}double Tools::ResourceUsage::getTotalTime(){ return combineTime(m_totalTime);}double Tools::ResourceUsage::getUserTime(){ return combineTime(m_userTime);}double Tools::ResourceUsage::getSystemTime(){ return combineTime(m_systemTime);}long Tools::ResourceUsage::getPageFaults(){ return m_pageFaults;}long Tools::ResourceUsage::getReadIO(){ return m_readIO;}long Tools::ResourceUsage::getWriteIO(){ return m_writeIO;}long Tools::ResourceUsage::getPeakResidentMemoryUsage(){ return m_peakMemory;}long Tools::ResourceUsage::getTotalMemoryUsage(){ return m_totalMemory;}#endif#if BUILD_CPU_I686Tools::CycleCounter::CycleCounter() : m_totalCycles(0), m_bRunning(false){}double Tools::CycleCounter::getCPUMHz(){ unsigned long long v1 = rdtsc(); sleep(10); unsigned long long v2 = rdtsc(); return ((v2 - v1) / 1e7);}double Tools::CycleCounter::getCyclesPerSecond(){ unsigned long long v1 = rdtsc(); sleep(10); unsigned long long v2 = rdtsc(); return ((v2 - v1) / 10);}inline unsigned long long Tools::CycleCounter::rdtsc(){ unsigned long long ret; __asm__ __volatile__("rdtsc": "=A" (ret):); return ret;}void Tools::CycleCounter::start(){ if (! m_bRunning) { m_tmpCycles = rdtsc(); m_bRunning = true; }}void Tools::CycleCounter::stop(){ if (m_bRunning) { unsigned long long t = rdtsc(); m_totalCycles += t - m_tmpCycles; m_bRunning = false; }}void Tools::CycleCounter::reset(){ m_totalCycles = 0; m_bRunning = false;}double Tools::CycleCounter::getTotalCycles(){ return m_totalCycles;}#endif#if HAVE_PTHREAD_HTools::SharedLock::SharedLock(pthread_rwlock_t* pLock) : m_pLock(pLock){ pthread_rwlock_rdlock(m_pLock);}Tools::SharedLock::~SharedLock(){ pthread_rwlock_unlock(m_pLock);}Tools::ExclusiveLock::ExclusiveLock(pthread_rwlock_t* pLock) : m_pLock(pLock){ pthread_rwlock_wrlock(m_pLock);}Tools::ExclusiveLock::~ExclusiveLock(){ pthread_rwlock_unlock(m_pLock);}#endifTools::StringTokenizer::StringTokenizer(const std::string& str, const std::string& delimiters) : m_index(0){ // Skip delimiters at beginning. std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". std::string::size_type pos = str.find_first_of(delimiters, lastPos); while (std::string::npos != pos || std::string::npos != lastPos) { // Found a token, add it to the vector. m_token.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); }}std::string Tools::StringTokenizer::getNextToken(){ return m_token.at(m_index++);}bool Tools::StringTokenizer::hasMoreTokens(){ return (m_index < m_token.size());}void Tools::StringTokenizer::reset(){ m_index = 0;}std::string Tools::trimLeft(const std::string& source, const std::string& t){ std::string str = source; return str.erase(0, source.find_first_not_of(t));}std::string Tools::trimRight(const std::string& source, const std::string& t){ std::string str = source; return str.erase(str.find_last_not_of(t) + 1);}std::string Tools::trim(const std::string& source, const std::string& t){ std::string str = source; return trimLeft(trimRight(str, t), t);}char Tools::toLower(char c){#ifdef _MSC_VER // MSVC doesn't seem to have std::tolower(char) std::locale loc; return std::tolower(c, loc);#else return std::tolower(c);#endif//_MSC_VER}char Tools::toUpper(char c){#ifdef _MSC_VER // MSVC doesn't seem to have std::toupper(char) std::locale loc; return std::toupper(c, loc);#else return std::toupper(c);#endif//_MSC_VER}std::string Tools::toUpperCase(const std::string& s){ std::string t = s; transform(t.begin(), t.end(), t.begin(), Tools::toUpper); return t;}std::string Tools::toLowerCase(const std::string& s){ std::string t = s; transform(t.begin(), t.end(), t.begin(), Tools::toLower); return t;}unsigned long long choose(unsigned long a, unsigned long k){ unsigned long long cnm = 1, n = a, m = k; unsigned long long i, f; if (m * 2 > n) m = n - m; for (i = 1 ; i <= m; n--, i++) { if ((f = n) % i == 0) f /= i; else cnm /= i; cnm *= f; } return cnm;}Tools::Architecture Tools::System::getArchitecture(){ union {double f; unsigned long i[2];} convert; convert.f = 1.0; // Note: Old versions of the Gnu g++ compiler may make an error here, // compile with the option -fenum-int-equiv to fix the problem if (convert.i[1] == 0x3FF00000) return ARCH_LITTLEENDIAN; else if (convert.i[0] == 0x3FF00000) return ARCH_BIGENDIAN; else return ARCH_NONIEEE;}std::ostream& Tools::operator<<(std::ostream& os, const Tools::PropertySet& p){ std::map<std::string, Variant>::const_iterator it; for (it = p.m_propertySet.begin(); it != p.m_propertySet.end(); it++) { if (it != p.m_propertySet.begin()) os << ", "; switch ((*it).second.m_varType) { case VT_LONG: os << (*it).first << ": " << (*it).second.m_val.lVal; break; case VT_LONGLONG: os << (*it).first << ": " << (*it).second.m_val.llVal; break; case VT_BYTE: os << (*it).first << ": " << (*it).second.m_val.bVal; break; case VT_SHORT: os << (*it).first << ": " << (*it).second.m_val.iVal; break; case VT_FLOAT: os << (*it).first << ": " << (*it).second.m_val.fltVal; break; case VT_DOUBLE: os << (*it).first << ": " << (*it).second.m_val.dblVal; break; case VT_CHAR: os << (*it).first << ": " << (*it).second.m_val.cVal; break; case VT_USHORT: os << (*it).first << ": " << (*it).second.m_val.uiVal; break; case VT_ULONG: os << (*it).first << ": " << (*it).second.m_val.ulVal; break; case VT_ULONGLONG: os << (*it).first << ": " << (*it).second.m_val.ullVal; break; case VT_INT: os << (*it).first << ": " << (*it).second.m_val.intVal; break; case VT_UINT: os << (*it).first << ": " << (*it).second.m_val.uintVal; break; case VT_BOOL: os << (*it).first << ": " << (*it).second.m_val.blVal; break; case VT_PCHAR: os << (*it).first << ": " << (*it).second.m_val.pcVal; break; case VT_PVOID: os << (*it).first << ": ?"; break; case VT_EMPTY: os << (*it).first << ": empty"; break; default: os << (*it).first << ": unknown"; } } return os;}std::ostream& Tools::operator<<(std::ostream& os, const Tools::Interval& iv){ os << iv.m_type << " " << iv.m_low << " " << iv.m_high; return os;}std::ostream& Tools::operator<<(std::ostream& os, const Tools::UniversalHash& h){ os << h.m_k; for (unsigned long i = 0; i < h.m_k; i++) os << " " << h.m_a[i]; return os;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -