From 660cd9d93e40aa72b1e579aa73a115a737bfe54d Mon Sep 17 00:00:00 2001 From: yanyiwu Date: Wed, 28 Jan 2015 21:27:46 +0800 Subject: [PATCH] upload limonp for Colors.hpp and use ColorPrintln in load_test.cpp --- src/Limonp/ArgvContext.hpp | 117 ++++---- src/Limonp/BlockingQueue.hpp | 185 ++++++------ src/Limonp/BoundedQueue.hpp | 110 ++++---- src/Limonp/CastFloat.hpp | 142 +++++----- src/Limonp/Colors.hpp | 36 +++ src/Limonp/Condition.hpp | 53 ++-- src/Limonp/Config.hpp | 183 ++++++------ src/Limonp/InitOnOff.hpp | 32 ++- src/Limonp/LocalVector.hpp | 284 +++++++++---------- src/Limonp/Logger.hpp | 80 +++--- src/Limonp/Md5.hpp | 127 ++++----- src/Limonp/MutexLock.hpp | 82 +++--- src/Limonp/MysqlClient.hpp | 194 ++++++------- src/Limonp/NonCopyable.hpp | 20 +- src/Limonp/StdExtension.hpp | 228 +++++++-------- src/Limonp/StringUtil.hpp | 532 ++++++++++++++++------------------- src/Limonp/Thread.hpp | 74 +++-- src/Limonp/ThreadPool.hpp | 169 +++++------ test/load_test.cpp | 7 +- 19 files changed, 1229 insertions(+), 1426 deletions(-) create mode 100644 src/Limonp/Colors.hpp diff --git a/src/Limonp/ArgvContext.hpp b/src/Limonp/ArgvContext.hpp index d26675a..0db265b 100644 --- a/src/Limonp/ArgvContext.hpp +++ b/src/Limonp/ArgvContext.hpp @@ -10,75 +10,58 @@ #include #include "StringUtil.hpp" -namespace Limonp -{ - using namespace std; - class ArgvContext - { - public : - ArgvContext(int argc, const char* const * argv) - { +namespace Limonp { +using namespace std; +class ArgvContext { + public : + ArgvContext(int argc, const char* const * argv) { - for(int i = 0; i < argc; i++) - { - if(startsWith(argv[i], "-")) - { - if(i + 1 < argc && !startsWith(argv[i + 1], "-")) - { - mpss_[argv[i]] = argv[i+1]; - i++; - } - else - { - sset_.insert(argv[i]); - } - } - else - { - args_.push_back(argv[i]); - } - } - } - ~ArgvContext(){}; - public: - friend ostream& operator << (ostream& os, const ArgvContext& args); - string operator [](size_t i) const - { - if(i < args_.size()) - { - return args_[i]; - } - return ""; - } - string operator [](const string& key) const - { - map::const_iterator it = mpss_.find(key); - if(it != mpss_.end()) - { - return it->second; - } - return ""; - } - public: - bool hasKey(const string& key) const - { - if(mpss_.find(key) != mpss_.end() || sset_.find(key) != sset_.end()) - { - return true; - } - return false; - } - private: - vector args_; - map mpss_; - set sset_; - - }; - - inline ostream& operator << (ostream& os, const ArgvContext& args) - { - return os<::const_iterator it = mpss_.find(key); + if(it != mpss_.end()) { + return it->second; + } + return ""; + } + public: + bool hasKey(const string& key) const { + if(mpss_.find(key) != mpss_.end() || sset_.find(key) != sset_.end()) { + return true; + } + return false; + } + private: + vector args_; + map mpss_; + set sset_; + +}; + +inline ostream& operator << (ostream& os, const ArgvContext& args) { + return os< - class BlockingQueue: NonCopyable - { - public: - BlockingQueue() - : mutex_(), notEmpty_(mutex_), queue_() - { - } +namespace Limonp { +template +class BlockingQueue: NonCopyable { + public: + BlockingQueue() + : mutex_(), notEmpty_(mutex_), queue_() { + } - void push(const T& x) - { - MutexLockGuard lock(mutex_); - queue_.push(x); - notEmpty_.notify(); // wait morphing saves us - } + void push(const T& x) { + MutexLockGuard lock(mutex_); + queue_.push(x); + notEmpty_.notify(); // wait morphing saves us + } - T pop() - { - MutexLockGuard lock(mutex_); - // always use a while-loop, due to spurious wakeup - while (queue_.empty()) - { - notEmpty_.wait(); - } - assert(!queue_.empty()); - T front(queue_.front()); - queue_.pop(); - return front; - } + T pop() { + MutexLockGuard lock(mutex_); + // always use a while-loop, due to spurious wakeup + while (queue_.empty()) { + notEmpty_.wait(); + } + assert(!queue_.empty()); + T front(queue_.front()); + queue_.pop(); + return front; + } - size_t size() const - { - MutexLockGuard lock(mutex_); - return queue_.size(); - } - bool empty() const - { - return size() == 0; - } + size_t size() const { + MutexLockGuard lock(mutex_); + return queue_.size(); + } + bool empty() const { + return size() == 0; + } - private: - mutable MutexLock mutex_; - Condition notEmpty_; - std::queue queue_; - }; + private: + mutable MutexLock mutex_; + Condition notEmpty_; + std::queue queue_; +}; - template - class BoundedBlockingQueue : NonCopyable - { - public: - explicit BoundedBlockingQueue(size_t maxSize) - : mutex_(), - notEmpty_(mutex_), - notFull_(mutex_), - queue_(maxSize) - {} +template +class BoundedBlockingQueue : NonCopyable { + public: + explicit BoundedBlockingQueue(size_t maxSize) + : mutex_(), + notEmpty_(mutex_), + notFull_(mutex_), + queue_(maxSize) { + } - void push(const T& x) - { - MutexLockGuard lock(mutex_); - while (queue_.full()) - { - notFull_.wait(); - } - assert(!queue_.full()); - queue_.push(x); - notEmpty_.notify(); - } + void push(const T& x) { + MutexLockGuard lock(mutex_); + while (queue_.full()) { + notFull_.wait(); + } + assert(!queue_.full()); + queue_.push(x); + notEmpty_.notify(); + } - T pop() - { - MutexLockGuard lock(mutex_); - while (queue_.empty()) - { - notEmpty_.wait(); - } - assert(!queue_.empty()); - T res = queue_.pop(); - notFull_.notify(); - return res; - } + T pop() { + MutexLockGuard lock(mutex_); + while (queue_.empty()) { + notEmpty_.wait(); + } + assert(!queue_.empty()); + T res = queue_.pop(); + notFull_.notify(); + return res; + } - bool empty() const - { - MutexLockGuard lock(mutex_); - return queue_.empty(); - } + bool empty() const { + MutexLockGuard lock(mutex_); + return queue_.empty(); + } - bool full() const - { - MutexLockGuard lock(mutex_); - return queue_.full(); - } + bool full() const { + MutexLockGuard lock(mutex_); + return queue_.full(); + } - size_t size() const - { - MutexLockGuard lock(mutex_); - return queue_.size(); - } + size_t size() const { + MutexLockGuard lock(mutex_); + return queue_.size(); + } - size_t capacity() const - { - return queue_.capacity(); - } + size_t capacity() const { + return queue_.capacity(); + } - private: - mutable MutexLock mutex_; - Condition notEmpty_; - Condition notFull_; - BoundedQueue queue_; - }; + private: + mutable MutexLock mutex_; + Condition notEmpty_; + Condition notFull_; + BoundedQueue queue_; +}; } diff --git a/src/Limonp/BoundedQueue.hpp b/src/Limonp/BoundedQueue.hpp index d438428..3f9eef4 100644 --- a/src/Limonp/BoundedQueue.hpp +++ b/src/Limonp/BoundedQueue.hpp @@ -5,69 +5,59 @@ #include #include -namespace Limonp -{ - using namespace std; - template - class BoundedQueue - { - private: - size_t head_; - size_t tail_; - size_t size_; - const size_t capacity_; - vector circular__buffer; - public: - explicit BoundedQueue(size_t capacity): capacity_(capacity), circular__buffer(capacity) - { - head_ = 0; - tail_ = 0; - size_ = 0; - assert(capacity_); - } - ~BoundedQueue(){} - public: - void clear() - { - head_ = 0; - tail_ = 0; - size_ = 0; - } - bool empty() const - { - return !size_; - } - bool full() const - { - return capacity_ == size_; - } - size_t size() const - { - return size_; - } - size_t capacity() const - { - return capacity_; - } +namespace Limonp { +using namespace std; +template +class BoundedQueue { + private: + size_t head_; + size_t tail_; + size_t size_; + const size_t capacity_; + vector circular__buffer; + public: + explicit BoundedQueue(size_t capacity): capacity_(capacity), circular__buffer(capacity) { + head_ = 0; + tail_ = 0; + size_ = 0; + assert(capacity_); + } + ~BoundedQueue() {} + public: + void clear() { + head_ = 0; + tail_ = 0; + size_ = 0; + } + bool empty() const { + return !size_; + } + bool full() const { + return capacity_ == size_; + } + size_t size() const { + return size_; + } + size_t capacity() const { + return capacity_; + } - void push(const T& t) - { - assert(!full()); - circular__buffer[tail_] = t; - tail_ = (tail_ + 1) % capacity_; - size_ ++; - } + void push(const T& t) { + assert(!full()); + circular__buffer[tail_] = t; + tail_ = (tail_ + 1) % capacity_; + size_ ++; + } - T pop() - { - assert(!empty()); - size_t oldPos = head_; - head_ = (head_ + 1) % capacity_; - size_ --; - return circular__buffer[oldPos]; - } + T pop() { + assert(!empty()); + size_t oldPos = head_; + head_ = (head_ + 1) % capacity_; + size_ --; + return circular__buffer[oldPos]; + } - }; +}; } #endif diff --git a/src/Limonp/CastFloat.hpp b/src/Limonp/CastFloat.hpp index ebd8b64..9af0069 100644 --- a/src/Limonp/CastFloat.hpp +++ b/src/Limonp/CastFloat.hpp @@ -1,90 +1,82 @@ #ifndef LIMONP_CAST_FUNCTS_H #define LIMONP_CAST_FUNCTS_H -namespace Limonp -{ - namespace CastFloat - { - //logical and or - static const int sign_32 = 0xC0000000; - static const int exponent_32 = 0x07800000; - static const int mantissa_32 = 0x007FE000; - static const int sign_exponent_32 = 0x40000000; - static const int loss_32 = 0x38000000; +namespace Limonp { +namespace CastFloat { +//logical and or +static const int sign_32 = 0xC0000000; +static const int exponent_32 = 0x07800000; +static const int mantissa_32 = 0x007FE000; +static const int sign_exponent_32 = 0x40000000; +static const int loss_32 = 0x38000000; - static const short sign_16 = (short)0xC000; - static const short exponent_16 = (short)0x3C00; - static const short mantissa_16 = (short)0x03FF; - static const short sign_exponent_16 = (short)0x4000; - static const int exponent_fill_32 = 0x38000000; +static const short sign_16 = (short)0xC000; +static const short exponent_16 = (short)0x3C00; +static const short mantissa_16 = (short)0x03FF; +static const short sign_exponent_16 = (short)0x4000; +static const int exponent_fill_32 = 0x38000000; - //infinite - static const short infinite_16 = (short) 0x7FFF; - static const short infinitesmall_16 = (short) 0x0000; +//infinite +static const short infinite_16 = (short) 0x7FFF; +static const short infinitesmall_16 = (short) 0x0000; - inline float intBitsToFloat(unsigned int x) - { - union - { - float f; - int i; - }u; - u.i = x; - return u.f; - } +inline float intBitsToFloat(unsigned int x) { + union { + float f; + int i; + } u; + u.i = x; + return u.f; +} - inline int floatToIntBits(float f) - { - union - { - float f; - int i ; - }u; - u.f = f; - return u.i; - } +inline int floatToIntBits(float f) { + union { + float f; + int i ; + } u; + u.f = f; + return u.i; +} - inline short floatToShortBits(float f) - { - int fi = floatToIntBits(f); +inline short floatToShortBits(float f) { + int fi = floatToIntBits(f); - // 提取关键信息 - short sign = (short) ((unsigned int)(fi & sign_32) >> 16); - short exponent = (short) ((unsigned int)(fi & exponent_32) >> 13); - short mantissa = (short) ((unsigned int)(fi & mantissa_32) >> 13); - // 生成编码结果 - short code = (short) (sign | exponent | mantissa); - // 无穷大量、无穷小量的处理 - if ((fi & loss_32) > 0 && (fi & sign_exponent_32) > 0) { - // 当指数符号为1时(正次方),且左234位为1,返回无穷大量 - return (short) (code | infinite_16); - } - if (((fi & loss_32) ^ loss_32) > 0 && (fi & sign_exponent_32) == 0) { - // 当指数符号位0时(负次方),且左234位为0(与111异或>0),返回无穷小量 - return infinitesmall_16; - } + // 提取关键信息 + short sign = (short) ((unsigned int)(fi & sign_32) >> 16); + short exponent = (short) ((unsigned int)(fi & exponent_32) >> 13); + short mantissa = (short) ((unsigned int)(fi & mantissa_32) >> 13); + // 生成编码结果 + short code = (short) (sign | exponent | mantissa); + // 无穷大量、无穷小量的处理 + if ((fi & loss_32) > 0 && (fi & sign_exponent_32) > 0) { + // 当指数符号为1时(正次方),且左234位为1,返回无穷大量 + return (short) (code | infinite_16); + } + if (((fi & loss_32) ^ loss_32) > 0 && (fi & sign_exponent_32) == 0) { + // 当指数符号位0时(负次方),且左234位为0(与111异或>0),返回无穷小量 + return infinitesmall_16; + } - return code; - } + return code; +} - inline float shortBitsToFloat(short s) - { - /* - * 指数空余3位:若符号位为1,补0;若符号位为0,补1。 尾数位在后补0(13个) - */ - int sign = ((int) (s & sign_16)) << 16; - int exponent = ((int) (s & exponent_16)) << 13; - // 指数符号位为0,234位补1 - if ((s & sign_exponent_16) == 0 && s != 0) { - exponent |= exponent_fill_32; - } - int mantissa = ((int) (s & mantissa_16)) << 13; - // 生成解码结果 - int code = sign | exponent | mantissa; - return intBitsToFloat(code); +inline float shortBitsToFloat(short s) { + /* + * 指数空余3位:若符号位为1,补0;若符号位为0,补1。 尾数位在后补0(13个) + */ + int sign = ((int) (s & sign_16)) << 16; + int exponent = ((int) (s & exponent_16)) << 13; + // 指数符号位为0,234位补1 + if ((s & sign_exponent_16) == 0 && s != 0) { + exponent |= exponent_fill_32; + } + int mantissa = ((int) (s & mantissa_16)) << 13; + // 生成解码结果 + int code = sign | exponent | mantissa; + return intBitsToFloat(code); - } - } +} +} } #endif diff --git a/src/Limonp/Colors.hpp b/src/Limonp/Colors.hpp new file mode 100644 index 0000000..591037c --- /dev/null +++ b/src/Limonp/Colors.hpp @@ -0,0 +1,36 @@ +#ifndef LIMONP_COLOR_PRINT_HPP +#define LIMONP_COLOR_PRINT_HPP + +#include +#include + +namespace Limonp { +using std::string; + +enum COLOR { + BLACK = 30, + RED, + GREEN, + YELLOW, + BLUE, + PURPLE +}; + +static void ColorPrintln(enum COLOR color, const char * fmt, ...) { + va_list ap; + printf("\033[0;%dm", color); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + printf("\033[0m\n"); // if not \n , in some situation , the next lines will be set the same color unexpectedly +} + +#if 0 +static void ColorPrint(const string& str, enum COLOR color = GREEN) { + printf("\033[0;%dm%s\033[0m", color, str.c_str()); +} +#endif + +} // namespace Limonp + +#endif diff --git a/src/Limonp/Condition.hpp b/src/Limonp/Condition.hpp index 13c14ed..9687e37 100644 --- a/src/Limonp/Condition.hpp +++ b/src/Limonp/Condition.hpp @@ -7,41 +7,34 @@ #include "MutexLock.hpp" -namespace Limonp -{ - class Condition : NonCopyable - { - public: - explicit Condition(MutexLock& mutex) - : mutex_(mutex) - { - LIMONP_CHECK(!pthread_cond_init(&pcond_, NULL)); - } +namespace Limonp { +class Condition : NonCopyable { + public: + explicit Condition(MutexLock& mutex) + : mutex_(mutex) { + LIMONP_CHECK(!pthread_cond_init(&pcond_, NULL)); + } - ~Condition() - { - LIMONP_CHECK(!pthread_cond_destroy(&pcond_)); - } + ~Condition() { + LIMONP_CHECK(!pthread_cond_destroy(&pcond_)); + } - void wait() - { - LIMONP_CHECK(!pthread_cond_wait(&pcond_, mutex_.getPthreadMutex())); - } + void wait() { + LIMONP_CHECK(!pthread_cond_wait(&pcond_, mutex_.getPthreadMutex())); + } - void notify() - { - LIMONP_CHECK(!pthread_cond_signal(&pcond_)); - } + void notify() { + LIMONP_CHECK(!pthread_cond_signal(&pcond_)); + } - void notifyAll() - { - LIMONP_CHECK(!pthread_cond_broadcast(&pcond_)); - } + void notifyAll() { + LIMONP_CHECK(!pthread_cond_broadcast(&pcond_)); + } - private: - MutexLock& mutex_; - pthread_cond_t pcond_; - }; + private: + MutexLock& mutex_; + pthread_cond_t pcond_; +}; } diff --git a/src/Limonp/Config.hpp b/src/Limonp/Config.hpp index cce94c1..e49bca6 100644 --- a/src/Limonp/Config.hpp +++ b/src/Limonp/Config.hpp @@ -12,107 +12,90 @@ #include #include "StringUtil.hpp" -namespace Limonp -{ - using namespace std; - class Config - { - public: - explicit Config(const string& filePath) - { - loadFile_(filePath); - } - public: - operator bool () - { - return !map_.empty(); - } - private: - void loadFile_(const string& filePath) - { - ifstream ifs(filePath.c_str()); - assert(ifs); - string line; - vector vecBuf; - size_t lineno = 0; - while(getline(ifs, line)) - { - lineno ++; - trim(line); - if(line.empty() || startsWith(line, "#")) - { - continue; - } - vecBuf.clear(); - if(!split(line, vecBuf, "=") || 2 != vecBuf.size()) - { - fprintf(stderr, "line[%s] illegal.\n", line.c_str()); - assert(false); - continue; - } - string& key = vecBuf[0]; - string& value = vecBuf[1]; - trim(key); - trim(value); - if(!map_.insert(make_pair(key, value)).second) - { - fprintf(stderr, "key[%s] already exits.\n", key.c_str()); - assert(false); - continue; - } - } - ifs.close(); - } - public: - bool get(const string& key, string& value) const - { - map::const_iterator it = map_.find(key); - if(map_.end() != it) - { - value = it->second; - return true; - } - return false; - } - bool get(const string& key, int & value) const - { - string str; - if(!get(key, str)) { - return false; - } - value = atoi(str.c_str()); - return true; - } - const char* operator [] (const char* key) const - { - if(NULL == key) - { - return NULL; - } - map::const_iterator it = map_.find(key); - if(map_.end() != it) - { - return it->second.c_str(); - } - return NULL; - } - public: - string getConfigInfo() const - { - string res; - res << *this; - return res; - } - private: - map map_; - private: - friend ostream& operator << (ostream& os, const Config& config); - }; - - inline ostream& operator << (ostream& os, const Config& config) - { - return os << config.map_; +namespace Limonp { +using namespace std; +class Config { + public: + explicit Config(const string& filePath) { + loadFile_(filePath); + } + public: + operator bool () { + return !map_.empty(); + } + private: + void loadFile_(const string& filePath) { + ifstream ifs(filePath.c_str()); + assert(ifs); + string line; + vector vecBuf; + size_t lineno = 0; + while(getline(ifs, line)) { + lineno ++; + trim(line); + if(line.empty() || startsWith(line, "#")) { + continue; + } + vecBuf.clear(); + if(!split(line, vecBuf, "=") || 2 != vecBuf.size()) { + fprintf(stderr, "line[%s] illegal.\n", line.c_str()); + assert(false); + continue; + } + string& key = vecBuf[0]; + string& value = vecBuf[1]; + trim(key); + trim(value); + if(!map_.insert(make_pair(key, value)).second) { + fprintf(stderr, "key[%s] already exits.\n", key.c_str()); + assert(false); + continue; + } } + ifs.close(); + } + public: + bool get(const string& key, string& value) const { + map::const_iterator it = map_.find(key); + if(map_.end() != it) { + value = it->second; + return true; + } + return false; + } + bool get(const string& key, int & value) const { + string str; + if(!get(key, str)) { + return false; + } + value = atoi(str.c_str()); + return true; + } + const char* operator [] (const char* key) const { + if(NULL == key) { + return NULL; + } + map::const_iterator it = map_.find(key); + if(map_.end() != it) { + return it->second.c_str(); + } + return NULL; + } + public: + string getConfigInfo() const { + string res; + res << *this; + return res; + } + private: + map map_; + private: + friend ostream& operator << (ostream& os, const Config& config); +}; + +inline ostream& operator << (ostream& os, const Config& config) { + return os << config.map_; +} } #endif diff --git a/src/Limonp/InitOnOff.hpp b/src/Limonp/InitOnOff.hpp index b74f0ff..c420155 100644 --- a/src/Limonp/InitOnOff.hpp +++ b/src/Limonp/InitOnOff.hpp @@ -1,21 +1,25 @@ #ifndef LIMONP_INITONOFF_H #define LIMONP_INITONOFF_H -namespace Limonp -{ - class InitOnOff - { - public: - InitOnOff():isInited_(false){}; - ~InitOnOff(){}; - protected: - bool isInited_; - bool getInitFlag_()const{return isInited_;}; - bool setInitFlag_(bool flag){return isInited_ = flag;}; - public: - operator bool() const {return getInitFlag_();}; +namespace Limonp { +class InitOnOff { + public: + InitOnOff():isInited_(false) {}; + ~InitOnOff() {}; + protected: + bool isInited_; + bool getInitFlag_()const { + return isInited_; + }; + bool setInitFlag_(bool flag) { + return isInited_ = flag; + }; + public: + operator bool() const { + return getInitFlag_(); + }; - }; +}; } #endif diff --git a/src/Limonp/LocalVector.hpp b/src/Limonp/LocalVector.hpp index ce1a741..93baf1f 100644 --- a/src/Limonp/LocalVector.hpp +++ b/src/Limonp/LocalVector.hpp @@ -6,165 +6,133 @@ #include #include -namespace Limonp -{ - using namespace std; - /* - * LocalVector : T must be primitive type (char , int, size_t), if T is struct or class, LocalVector may be dangerous.. - * LocalVector is simple and not well-tested. - */ - const size_t LOCAL_VECTOR_BUFFER_SIZE = 16; - template - class LocalVector - { - public: - typedef const T* const_iterator ; - typedef T value_type; - typedef size_t size_type; - private: - T buffer_[LOCAL_VECTOR_BUFFER_SIZE]; - T * ptr_; - size_t size_; - size_t capacity_; - public: - LocalVector() - { - init_(); - }; - LocalVector(const LocalVector& vec) - { - init_(); - *this = vec; - } - LocalVector(const_iterator begin, const_iterator end) // TODO: make it faster - { - init_(); - while(begin != end) - { - push_back(*begin++); - } - } - LocalVector(size_t size, const T& t) // TODO: make it faster - { - init_(); - while(size--) - { - push_back(t); - } - } - ~LocalVector() - { - if(ptr_ != buffer_) - { - free(ptr_); - } - }; - public: - LocalVector& operator = (const LocalVector& vec) - { - clear(); - size_ = vec.size(); - capacity_ = vec.capacity(); - if(vec.buffer_ == vec.ptr_) - { - memcpy(buffer_, vec.buffer_, sizeof(T) * size_); - ptr_ = buffer_; - } - else - { - ptr_ = (T*) malloc(vec.capacity() * sizeof(T)); - assert(ptr_); - memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T)); - } - return *this; - } - private: - void init_() - { - ptr_ = buffer_; - size_ = 0; - capacity_ = LOCAL_VECTOR_BUFFER_SIZE; - } - public: - T& operator [] (size_t i) - { - return ptr_[i]; - } - const T& operator [] (size_t i) const - { - return ptr_[i]; - } - void push_back(const T& t) - { - if(size_ == capacity_) - { - assert(capacity_); - reserve(capacity_ * 2); - } - ptr_[size_ ++ ] = t; - } - void reserve(size_t size) - { - if(size <= capacity_) - { - return; - } - T * next = (T*)malloc(sizeof(T) * size); - assert(next); - T * old = ptr_; - ptr_ = next; - memcpy(ptr_, old, sizeof(T) * capacity_); - capacity_ = size; - if(old != buffer_) - { - free(old); - } - } - bool empty() const - { - return 0 == size(); - } - size_t size() const - { - return size_; - } - size_t capacity() const - { - return capacity_; - } - const_iterator begin() const - { - return ptr_; - } - const_iterator end() const - { - return ptr_ + size_; - } - void clear() - { - if(ptr_ != buffer_) - { - free(ptr_); - } - init_(); - } - }; +namespace Limonp { +using namespace std; +/* + * LocalVector : T must be primitive type (char , int, size_t), if T is struct or class, LocalVector may be dangerous.. + * LocalVector is simple and not well-tested. + */ +const size_t LOCAL_VECTOR_BUFFER_SIZE = 16; +template +class LocalVector { + public: + typedef const T* const_iterator ; + typedef T value_type; + typedef size_t size_type; + private: + T buffer_[LOCAL_VECTOR_BUFFER_SIZE]; + T * ptr_; + size_t size_; + size_t capacity_; + public: + LocalVector() { + init_(); + }; + LocalVector(const LocalVector& vec) { + init_(); + *this = vec; + } + LocalVector(const_iterator begin, const_iterator end) { // TODO: make it faster + init_(); + while(begin != end) { + push_back(*begin++); + } + } + LocalVector(size_t size, const T& t) { // TODO: make it faster + init_(); + while(size--) { + push_back(t); + } + } + ~LocalVector() { + if(ptr_ != buffer_) { + free(ptr_); + } + }; + public: + LocalVector& operator = (const LocalVector& vec) { + clear(); + size_ = vec.size(); + capacity_ = vec.capacity(); + if(vec.buffer_ == vec.ptr_) { + memcpy(buffer_, vec.buffer_, sizeof(T) * size_); + ptr_ = buffer_; + } else { + ptr_ = (T*) malloc(vec.capacity() * sizeof(T)); + assert(ptr_); + memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T)); + } + return *this; + } + private: + void init_() { + ptr_ = buffer_; + size_ = 0; + capacity_ = LOCAL_VECTOR_BUFFER_SIZE; + } + public: + T& operator [] (size_t i) { + return ptr_[i]; + } + const T& operator [] (size_t i) const { + return ptr_[i]; + } + void push_back(const T& t) { + if(size_ == capacity_) { + assert(capacity_); + reserve(capacity_ * 2); + } + ptr_[size_ ++ ] = t; + } + void reserve(size_t size) { + if(size <= capacity_) { + return; + } + T * next = (T*)malloc(sizeof(T) * size); + assert(next); + T * old = ptr_; + ptr_ = next; + memcpy(ptr_, old, sizeof(T) * capacity_); + capacity_ = size; + if(old != buffer_) { + free(old); + } + } + bool empty() const { + return 0 == size(); + } + size_t size() const { + return size_; + } + size_t capacity() const { + return capacity_; + } + const_iterator begin() const { + return ptr_; + } + const_iterator end() const { + return ptr_ + size_; + } + void clear() { + if(ptr_ != buffer_) { + free(ptr_); + } + init_(); + } +}; - template - ostream & operator << (ostream& os, const LocalVector& vec) - { - if(vec.empty()) - { - return os << "[]"; - } - os<<"[\""< +ostream & operator << (ostream& os, const LocalVector& vec) { + if(vec.empty()) { + return os << "[]"; + } + os<<"[\""< -1 && n < size) { - msg.resize(n); - break; - } - if (n > -1) - size = n + 1; - else - size *= 2; - } - Logging(level, msg, fileName, lineno); - } - }; + int size = 256; + string msg; + va_list ap; + while (1) { + msg.resize(size); + va_start(ap, fmt); + int n = vsnprintf((char *)msg.c_str(), size, fmt, ap); + va_end(ap); + if (n > -1 && n < size) { + msg.resize(n); + break; + } + if (n > -1) + size = n + 1; + else + size *= 2; + } + Logging(level, msg, fileName, lineno); + } +}; } #endif diff --git a/src/Limonp/Md5.hpp b/src/Limonp/Md5.hpp index 98bda92..2b82bbd 100644 --- a/src/Limonp/Md5.hpp +++ b/src/Limonp/Md5.hpp @@ -31,8 +31,7 @@ #include #include -namespace Limonp -{ +namespace Limonp { //#pragma region MD5 defines // Constants for MD5Transform routine. @@ -106,9 +105,8 @@ static unsigned char PADDING[64] = { }; // convenient object that wraps // the C-functions for use in C++ only -class MD5 -{ -private: +class MD5 { + private: struct __context_t { UINT4 state[4]; /* state (ABCD) */ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ @@ -118,8 +116,7 @@ private: //#pragma region static helper functions // The core of the MD5 algorithm is here. // MD5 basic transformation. Transforms state based on block. - static void MD5Transform( UINT4 state[4], unsigned char block[64] ) - { + static void MD5Transform( UINT4 state[4], unsigned char block[64] ) { UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode (x, block, 64); @@ -207,8 +204,7 @@ private: // Encodes input (UINT4) into output (unsigned char). Assumes len is // a multiple of 4. - static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) - { + static void Encode( unsigned char *output, UINT4 *input, unsigned int len ) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) { @@ -221,29 +217,26 @@ private: // Decodes input (unsigned char) into output (UINT4). Assumes len is // a multiple of 4. - static void Decode( UINT4 *output, unsigned char *input, unsigned int len ) - { + static void Decode( UINT4 *output, unsigned char *input, unsigned int len ) { unsigned int i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); + (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); } //#pragma endregion -public: + public: // MAIN FUNCTIONS - MD5() - { + MD5() { Init() ; } // MD5 initialization. Begins an MD5 operation, writing a new context. - void Init() - { + void Init() { context.count[0] = context.count[1] = 0; - + // Load magic initialization constants. context.state[0] = 0x67452301; context.state[1] = 0xefcdab89; @@ -256,8 +249,7 @@ public: // context. void Update( unsigned char *input, // input block - unsigned int inputLen ) // length of input block - { + unsigned int inputLen ) { // length of input block unsigned int i, index, partLen; // Compute number of bytes mod 64 @@ -265,7 +257,7 @@ public: // Update number of bits if ((context.count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) context.count[1]++; context.count[1] += ((UINT4)inputLen >> 29); @@ -280,8 +272,7 @@ public: MD5Transform (context.state, &input[i]); index = 0; - } - else + } else i = 0; /* Buffer remaining input */ @@ -291,8 +282,7 @@ public: // MD5 finalization. Ends an MD5 message-digest operation, writing the // the message digest and zeroizing the context. // Writes to digestRaw - void Final() - { + void Final() { unsigned char bits[8]; unsigned int index, padLen; @@ -316,9 +306,8 @@ public: writeToString() ; } - /// Buffer must be 32+1 (nul) = 33 chars long at least - void writeToString() - { + /// Buffer must be 32+1 (nul) = 33 chars long at least + void writeToString() { int pos ; for( pos = 0 ; pos < 16 ; pos++ ) @@ -326,7 +315,7 @@ public: } -public: + public: // an MD5 digest is a 16-byte number (32 hex digits) BYTE digestRaw[ 16 ] ; @@ -336,19 +325,17 @@ public: /// Load a file from disk and digest it // Digests a file and returns the result. - const char* digestFile( const char *filename ) - { + const char* digestFile( const char *filename ) { if (NULL == filename || strcmp(filename, "") == 0) - return NULL; + return NULL; Init() ; FILE *file; - + unsigned char buffer[1024] ; - if((file = fopen (filename, "rb")) == NULL) - { + if((file = fopen (filename, "rb")) == NULL) { return NULL; } int len; @@ -362,23 +349,21 @@ public: } /// Digests a byte-array already in memory - const char* digestMemory( BYTE *memchunk, int len ) - { + const char* digestMemory( BYTE *memchunk, int len ) { if (NULL == memchunk) - return NULL; + return NULL; Init() ; Update( memchunk, len ) ; Final() ; - + return digestChars ; } // Digests a string and prints the result. - const char* digestString(const char *string ) - { + const char* digestString(const char *string ) { if (string == NULL) - return NULL; + return NULL; Init() ; Update( (unsigned char*)string, strlen(string) ) ; @@ -388,45 +373,39 @@ public: } }; -inline bool md5String(const char* str, std::string& res) -{ - if (NULL == str) - { - res = ""; - return false; - } +inline bool md5String(const char* str, std::string& res) { + if (NULL == str) { + res = ""; + return false; + } - MD5 md5; - const char *pRes = md5.digestString(str); - if (NULL == pRes) - { - res = ""; - return false; - } + MD5 md5; + const char *pRes = md5.digestString(str); + if (NULL == pRes) { + res = ""; + return false; + } - res = pRes; - return true; + res = pRes; + return true; } -inline bool md5File(const char* filepath, std::string& res) -{ - if (NULL == filepath || strcmp(filepath, "") == 0) - { - res = ""; - return false; - } +inline bool md5File(const char* filepath, std::string& res) { + if (NULL == filepath || strcmp(filepath, "") == 0) { + res = ""; + return false; + } - MD5 md5; - const char *pRes = md5.digestFile(filepath); + MD5 md5; + const char *pRes = md5.digestFile(filepath); - if (NULL == pRes) - { - res = ""; - return false; - } + if (NULL == pRes) { + res = ""; + return false; + } - res = pRes; - return true; + res = pRes; + return true; } } #endif diff --git a/src/Limonp/MutexLock.hpp b/src/Limonp/MutexLock.hpp index d0d546c..5f9ecbd 100644 --- a/src/Limonp/MutexLock.hpp +++ b/src/Limonp/MutexLock.hpp @@ -5,52 +5,42 @@ #include "NonCopyable.hpp" #include "HandyMacro.hpp" -namespace Limonp -{ - class MutexLock: NonCopyable - { - private: - pthread_mutex_t mutex_; - public: - pthread_mutex_t* getPthreadMutex() - { - return &mutex_; - } - public: - MutexLock() - { - LIMONP_CHECK(!pthread_mutex_init(&mutex_, NULL)); - } - ~MutexLock() - { - LIMONP_CHECK(!pthread_mutex_destroy(&mutex_)); - } - private: - void lock() - { - LIMONP_CHECK(!pthread_mutex_lock(&mutex_)); - } - void unlock() - { - LIMONP_CHECK(!pthread_mutex_unlock(&mutex_)); - } - friend class MutexLockGuard; - }; - class MutexLockGuard: NonCopyable - { - public: - explicit MutexLockGuard(MutexLock & mutex) - : mutex_(mutex) - { - mutex_.lock(); - } - ~MutexLockGuard() - { - mutex_.unlock(); - } - private: - MutexLock & mutex_; - }; +namespace Limonp { +class MutexLock: NonCopyable { + private: + pthread_mutex_t mutex_; + public: + pthread_mutex_t* getPthreadMutex() { + return &mutex_; + } + public: + MutexLock() { + LIMONP_CHECK(!pthread_mutex_init(&mutex_, NULL)); + } + ~MutexLock() { + LIMONP_CHECK(!pthread_mutex_destroy(&mutex_)); + } + private: + void lock() { + LIMONP_CHECK(!pthread_mutex_lock(&mutex_)); + } + void unlock() { + LIMONP_CHECK(!pthread_mutex_unlock(&mutex_)); + } + friend class MutexLockGuard; +}; +class MutexLockGuard: NonCopyable { + public: + explicit MutexLockGuard(MutexLock & mutex) + : mutex_(mutex) { + mutex_.lock(); + } + ~MutexLockGuard() { + mutex_.unlock(); + } + private: + MutexLock & mutex_; +}; #define MutexLockGuard(x) assert(false); } diff --git a/src/Limonp/MysqlClient.hpp b/src/Limonp/MysqlClient.hpp index 570ac37..7395fa9 100644 --- a/src/Limonp/MysqlClient.hpp +++ b/src/Limonp/MysqlClient.hpp @@ -8,118 +8,100 @@ #include "Logger.hpp" #include "InitOnOff.hpp" -namespace Limonp -{ - using namespace std; - class MysqlClient: public InitOnOff - { - public: - typedef vector< vector > RowsType; - private: - const string host_; - const size_t port_; - const string user_; - const string passwd_; - const string db_; - const string charset_; - public: - MysqlClient(const string& host, size_t port, const string& user, const string& passwd, const string& db, const string& charset = "utf8"): host_(host), port_(port), user_(user), passwd_(passwd), db_(db), charset_(charset), conn_(NULL) - { - setInitFlag_(init_()); - } - ~MysqlClient() - { - if(conn_) - { - mysql_close(conn_); - } - }; - private: - bool init_() - { - //cout< > RowsType; + private: + const string host_; + const size_t port_; + const string user_; + const string passwd_; + const string db_; + const string charset_; + public: + MysqlClient(const string& host, size_t port, const string& user, const string& passwd, const string& db, const string& charset = "utf8"): host_(host), port_(port), user_(user), passwd_(passwd), db_(db), charset_(charset), conn_(NULL) { + setInitFlag_(init_()); + } + ~MysqlClient() { + if(conn_) { + mysql_close(conn_); + } + }; + private: + bool init_() { + //cout<& vals) - { - size_t retn = 0; - string sql; - for(size_t i = 0; i < vals.size(); i ++) - { - sql.clear(); - string_format(sql, "insert into %s (%s) values %s", tableName.c_str(), keys.c_str(), vals[i].c_str()); - retn += executeSql(sql.c_str()); - } - return retn; - } - bool select(const string& sql, RowsType& rows) - { - if(!executeSql(sql)) - { - LogError("executeSql failed. [%s]", sql.c_str()); - return false; - } - MYSQL_RES * result = mysql_store_result(conn_); - if(!result) - { - LogError("mysql_store_result failed.[%d]", mysql_error(conn_)); - return false; - } - size_t num_fields = mysql_num_fields(result); - MYSQL_ROW row; - while((row = mysql_fetch_row(result))) - { - vector vec; - for(size_t i = 0; i < num_fields; i ++) - { - row[i] ? vec.push_back(row[i]) : vec.push_back("NULL"); - } - rows.push_back(vec); - } - mysql_free_result(result); - return true; - } + LogInfo("MysqlClient {host: %s, database:%s, charset:%s}", host_.c_str(), db_.c_str(), charset_.c_str()); + return true; + } + public: + bool executeSql(const string& sql) { + assert(getInitFlag_()); + if(mysql_query(conn_, sql.c_str())) { + LogError("mysql_query failed. %s", mysql_error(conn_)); + return false; + } + return true; + } + size_t insert(const string& tableName, const string& keys, const vector& vals) { + size_t retn = 0; + string sql; + for(size_t i = 0; i < vals.size(); i ++) { + sql.clear(); + string_format(sql, "insert into %s (%s) values %s", tableName.c_str(), keys.c_str(), vals[i].c_str()); + retn += executeSql(sql.c_str()); + } + return retn; + } + bool select(const string& sql, RowsType& rows) { + if(!executeSql(sql)) { + LogError("executeSql failed. [%s]", sql.c_str()); + return false; + } + MYSQL_RES * result = mysql_store_result(conn_); + if(!result) { + LogError("mysql_store_result failed.[%d]", mysql_error(conn_)); + return false; + } + size_t num_fields = mysql_num_fields(result); + MYSQL_ROW row; + while((row = mysql_fetch_row(result))) { + vector vec; + for(size_t i = 0; i < num_fields; i ++) { + row[i] ? vec.push_back(row[i]) : vec.push_back("NULL"); + } + rows.push_back(vec); + } + mysql_free_result(result); + return true; + } - private: - MYSQL * conn_; + private: + MYSQL * conn_; - }; +}; } #endif diff --git a/src/Limonp/NonCopyable.hpp b/src/Limonp/NonCopyable.hpp index 2cf50a5..c47e66b 100644 --- a/src/Limonp/NonCopyable.hpp +++ b/src/Limonp/NonCopyable.hpp @@ -6,17 +6,15 @@ #include #include -namespace Limonp -{ - class NonCopyable - { - protected: - NonCopyable(){}; - ~NonCopyable(){}; - private: - NonCopyable(const NonCopyable& ); - const NonCopyable& operator=(const NonCopyable& ); - }; +namespace Limonp { +class NonCopyable { + protected: + NonCopyable() {}; + ~NonCopyable() {}; + private: + NonCopyable(const NonCopyable& ); + const NonCopyable& operator=(const NonCopyable& ); +}; } #endif diff --git a/src/Limonp/StdExtension.hpp b/src/Limonp/StdExtension.hpp index 83e9b6e..e7d974c 100644 --- a/src/Limonp/StdExtension.hpp +++ b/src/Limonp/StdExtension.hpp @@ -9,131 +9,131 @@ #else #include #include -namespace std -{ - using std::tr1::unordered_map; - using std::tr1::unordered_set; +namespace std { +using std::tr1::unordered_map; +using std::tr1::unordered_set; } #endif #include +#include #include +#include #include #include -namespace std -{ - template - ostream& operator << (ostream& os, const vector& vec) - { - if(vec.empty()) - { - return os << "[]"; - } - os<<"[\""< - ostream& operator << (ostream& os, const pair& pr) - { - os << pr.first << ":" << pr.second ; - return os; - } +namespace std { - - template - string& operator << (string& str, const T& obj) - { - stringstream ss; - ss << obj; // call ostream& operator << (ostream& os, - return str = ss.str(); - } - - template - ostream& operator << (ostream& os, const map& mp) - { - if(mp.empty()) - { - os<<"{}"; - return os; - } - os<<'{'; - typename map::const_iterator it = mp.begin(); - os<<*it; - it++; - while(it != mp.end()) - { - os<<", "<<*it; - it++; - } - os<<'}'; - return os; - } - template - ostream& operator << (ostream& os, const std::unordered_map& mp) - { - if(mp.empty()) - { - return os << "{}"; - } - os<<'{'; - typename std::unordered_map::const_iterator it = mp.begin(); - os<<*it; - it++; - while(it != mp.end()) - { - os<<", "<<*it++; - } - return os<<'}'; - } - - template - ostream& operator << (ostream& os, const set& st) - { - if(st.empty()) - { - os << "{}"; - return os; - } - os<<'{'; - typename set::const_iterator it = st.begin(); - os<<*it; - it++; - while(it != st.end()) - { - os<<", "<<*it; - it++; - } - os<<'}'; - return os; - } - - template - bool isIn(const ContainType& contain, const KeyType& key) - { - return contain.end() != contain.find(key); - } - - template - basic_string & operator << (basic_string & s, ifstream & ifs) - { - return s.assign((istreambuf_iterator(ifs)), istreambuf_iterator()); - } - - template - ofstream & operator << (ofstream & ofs, const basic_string& s) - { - ostreambuf_iterator itr (ofs); - copy(s.begin(), s.end(), itr); - return ofs; - } +template +ostream& operator << (ostream& os, const vector& v) { + if(v.empty()) { + return os << "[]"; + } + os<<"[\""< +ostream& operator << (ostream& os, const deque& dq) { + if(dq.empty()) { + return os << "[]"; + } + os<<"[\""< +ostream& operator << (ostream& os, const pair& pr) { + os << pr.first << ":" << pr.second ; + return os; +} + + +template +string& operator << (string& str, const T& obj) { + stringstream ss; + ss << obj; // call ostream& operator << (ostream& os, + return str = ss.str(); +} + +template +ostream& operator << (ostream& os, const map& mp) { + if(mp.empty()) { + os<<"{}"; + return os; + } + os<<'{'; + typename map::const_iterator it = mp.begin(); + os<<*it; + it++; + while(it != mp.end()) { + os<<", "<<*it; + it++; + } + os<<'}'; + return os; +} +template +ostream& operator << (ostream& os, const std::unordered_map& mp) { + if(mp.empty()) { + return os << "{}"; + } + os<<'{'; + typename std::unordered_map::const_iterator it = mp.begin(); + os<<*it; + it++; + while(it != mp.end()) { + os<<", "<<*it++; + } + return os<<'}'; +} + +template +ostream& operator << (ostream& os, const set& st) { + if(st.empty()) { + os << "{}"; + return os; + } + os<<'{'; + typename set::const_iterator it = st.begin(); + os<<*it; + it++; + while(it != st.end()) { + os<<", "<<*it; + it++; + } + os<<'}'; + return os; +} + +template +bool isIn(const ContainType& contain, const KeyType& key) { + return contain.end() != contain.find(key); +} + +template +basic_string & operator << (basic_string & s, ifstream & ifs) { + return s.assign((istreambuf_iterator(ifs)), istreambuf_iterator()); +} + +template +ofstream & operator << (ofstream & ofs, const basic_string& s) { + ostreambuf_iterator itr (ofs); + copy(s.begin(), s.end(), itr); + return ofs; +} + +} // namespace std + #endif diff --git a/src/Limonp/StringUtil.hpp b/src/Limonp/StringUtil.hpp index ed8fdbc..61ebd60 100644 --- a/src/Limonp/StringUtil.hpp +++ b/src/Limonp/StringUtil.hpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include #include @@ -23,327 +23,273 @@ #include #include "StdExtension.hpp" -namespace Limonp -{ - using namespace std; - inline string string_format(const char* fmt, ...) - { - int size = 256; - std::string str; - va_list ap; - while (1) { - str.resize(size); - va_start(ap, fmt); - int n = vsnprintf((char *)str.c_str(), size, fmt, ap); - va_end(ap); - if (n > -1 && n < size) { - str.resize(n); - return str; - } - if (n > -1) - size = n + 1; - else - size *= 2; - } - return str; +namespace Limonp { +using namespace std; +inline string string_format(const char* fmt, ...) { + int size = 256; + std::string str; + va_list ap; + while (1) { + str.resize(size); + va_start(ap, fmt); + int n = vsnprintf((char *)str.c_str(), size, fmt, ap); + va_end(ap); + if (n > -1 && n < size) { + str.resize(n); + return str; } + if (n > -1) + size = n + 1; + else + size *= 2; + } + return str; +} - template - void join(T begin, T end, string& res, const string& connector) - { - if(begin == end) - { - return; - } - stringstream ss; - ss<<*begin; - begin++; - while(begin != end) - { - ss << connector << *begin; - begin ++; - } - res = ss.str(); - } +template +void join(T begin, T end, string& res, const string& connector) { + if(begin == end) { + return; + } + stringstream ss; + ss<<*begin; + begin++; + while(begin != end) { + ss << connector << *begin; + begin ++; + } + res = ss.str(); +} - template - string join(T begin, T end, const string& connector) - { - string res; - join(begin ,end, res, connector); - return res; - } +template +string join(T begin, T end, const string& connector) { + string res; + join(begin ,end, res, connector); + return res; +} - inline bool split(const string& src, vector& res, const string& pattern, size_t offset = 0, size_t len = string::npos) - { - if(src.empty()) - { - return false; - } - res.clear(); +inline bool split(const string& src, vector& res, const string& pattern, size_t offset = 0, size_t len = string::npos) { + if(src.empty()) { + return false; + } + res.clear(); - size_t start = 0; - size_t end = 0; - size_t cnt = 0; - while(start < src.size() && res.size() < len) - { - end = src.find_first_of(pattern, start); - if(string::npos == end) - { - if(cnt >= offset) - { - res.push_back(src.substr(start)); - } - return true; - } - //if(end == src.size() - 1) - //{ - // res.push_back(""); - // return true; - //} - if(cnt >= offset) - { - res.push_back(src.substr(start, end - start)); - } - cnt ++; - start = end + 1; - } - return true; + size_t start = 0; + size_t end = 0; + size_t cnt = 0; + while(start < src.size() && res.size() < len) { + end = src.find_first_of(pattern, start); + if(string::npos == end) { + if(cnt >= offset) { + res.push_back(src.substr(start)); + } + return true; } + //if(end == src.size() - 1) + //{ + // res.push_back(""); + // return true; + //} + if(cnt >= offset) { + res.push_back(src.substr(start, end - start)); + } + cnt ++; + start = end + 1; + } + return true; +} - inline string& upper(string& str) - { - transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper); - return str; - } +inline string& upper(string& str) { + transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper); + return str; +} - inline string& lower(string& str) - { - transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower); - return str; - } +inline string& lower(string& str) { + transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower); + return str; +} - inline std::string <rim(std::string &s) - { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); - return s; - } +inline std::string <rim(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); + return s; +} - inline std::string &rtrim(std::string &s) - { - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); - return s; - } +inline std::string &rtrim(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + return s; +} - inline std::string &trim(std::string &s) - { - return ltrim(rtrim(s)); - } +inline std::string &trim(std::string &s) { + return ltrim(rtrim(s)); +} - inline std::string & ltrim(std::string & s, char x) - { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::bind2nd(std::equal_to(), x)))); - return s; - } +inline std::string & ltrim(std::string & s, char x) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::bind2nd(std::equal_to(), x)))); + return s; +} - inline std::string & rtrim(std::string & s, char x) - { - s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::bind2nd(std::equal_to(), x))).base(), s.end()); - return s; - } +inline std::string & rtrim(std::string & s, char x) { + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::bind2nd(std::equal_to(), x))).base(), s.end()); + return s; +} - inline std::string &trim(std::string &s, char x) - { - return ltrim(rtrim(s, x), x); - } +inline std::string &trim(std::string &s, char x) { + return ltrim(rtrim(s, x), x); +} - inline bool startsWith(const string& str, const string& prefix) - { - if(prefix.length() > str.length()) - { - return false; - } - return 0 == str.compare(0, prefix.length(), prefix); - } +inline bool startsWith(const string& str, const string& prefix) { + if(prefix.length() > str.length()) { + return false; + } + return 0 == str.compare(0, prefix.length(), prefix); +} - inline bool endsWith(const string& str, const string& suffix) - { - if(suffix.length() > str.length()) - { - return false; - } - return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix); - } +inline bool endsWith(const string& str, const string& suffix) { + if(suffix.length() > str.length()) { + return false; + } + return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix); +} - inline bool isInStr(const string& str, char ch) - { - return str.find(ch) != string::npos; - } +inline bool isInStr(const string& str, char ch) { + return str.find(ch) != string::npos; +} - inline uint16_t twocharToUint16(char high, char low) - { - return (((uint16_t(high) & 0x00ff ) << 8) | (uint16_t(low) & 0x00ff)); - } +inline uint16_t twocharToUint16(char high, char low) { + return (((uint16_t(high) & 0x00ff ) << 8) | (uint16_t(low) & 0x00ff)); +} - template - bool utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) - { - if(!str) - { - return false; - } - char ch1, ch2; - uint16_t tmp; - vec.clear(); - for(size_t i = 0;i < len;) - { - if(!(str[i] & 0x80)) // 0xxxxxxx - { - vec.push_back(str[i]); - i++; - } - else if ((uint8_t)str[i] <= 0xdf && i + 1 < len) // 110xxxxxx - { - ch1 = (str[i] >> 2) & 0x07; - ch2 = (str[i+1] & 0x3f) | ((str[i] & 0x03) << 6 ); - tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff)); - vec.push_back(tmp); - i += 2; - } - else if((uint8_t)str[i] <= 0xef && i + 2 < len) - { - ch1 = ((uint8_t)str[i] << 4) | ((str[i+1] >> 2) & 0x0f ); - ch2 = (((uint8_t)str[i+1]<<6) & 0xc0) | (str[i+2] & 0x3f); - tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff)); - vec.push_back(tmp); - i += 3; - } - else - { - return false; - } - } - return true; - } - template - bool utf8ToUnicode(const string& str, Uint16Container& vec) - { - return utf8ToUnicode(str.c_str(), str.size(), vec); +template +bool utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) { + if(!str) { + return false; + } + char ch1, ch2; + uint16_t tmp; + vec.clear(); + for(size_t i = 0; i < len;) { + if(!(str[i] & 0x80)) { // 0xxxxxxx + vec.push_back(str[i]); + i++; + } else if ((uint8_t)str[i] <= 0xdf && i + 1 < len) { // 110xxxxxx + ch1 = (str[i] >> 2) & 0x07; + ch2 = (str[i+1] & 0x3f) | ((str[i] & 0x03) << 6 ); + tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff)); + vec.push_back(tmp); + i += 2; + } else if((uint8_t)str[i] <= 0xef && i + 2 < len) { + ch1 = ((uint8_t)str[i] << 4) | ((str[i+1] >> 2) & 0x0f ); + ch2 = (((uint8_t)str[i+1]<<6) & 0xc0) | (str[i+2] & 0x3f); + tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff)); + vec.push_back(tmp); + i += 3; + } else { + return false; } + } + return true; +} +template +bool utf8ToUnicode(const string& str, Uint16Container& vec) { + return utf8ToUnicode(str.c_str(), str.size(), vec); +} - template - bool unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) - { - if(begin >= end) - { - return false; - } - res.clear(); - uint16_t ui; - while(begin != end) - { - ui = *begin; - if(ui <= 0x7f) - { - res += char(ui); - } - else if(ui <= 0x7ff) - { - res += char(((ui>>6) & 0x1f) | 0xc0); - res += char((ui & 0x3f) | 0x80); - } - else - { - res += char(((ui >> 12) & 0x0f )| 0xe0); - res += char(((ui>>6) & 0x3f )| 0x80 ); - res += char((ui & 0x3f) | 0x80); - } - begin ++; - } - return true; +template +bool unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) { + if(begin >= end) { + return false; + } + res.clear(); + uint16_t ui; + while(begin != end) { + ui = *begin; + if(ui <= 0x7f) { + res += char(ui); + } else if(ui <= 0x7ff) { + res += char(((ui>>6) & 0x1f) | 0xc0); + res += char((ui & 0x3f) | 0x80); + } else { + res += char(((ui >> 12) & 0x0f )| 0xe0); + res += char(((ui>>6) & 0x3f )| 0x80 ); + res += char((ui & 0x3f) | 0x80); } + begin ++; + } + return true; +} - - template - bool gbkTrans(const char* const str, size_t len, Uint16Container& vec) - { - vec.clear(); - if(!str) - { - return false; - } - size_t i = 0; - while(i < len) - { - if(0 == (str[i] & 0x80)) - { - vec.push_back(uint16_t(str[i])); - i++; - } - else - { - if(i + 1 < len) //&& (str[i+1] & 0x80)) - { - uint16_t tmp = (((uint16_t(str[i]) & 0x00ff ) << 8) | (uint16_t(str[i+1]) & 0x00ff)); - vec.push_back(tmp); - i += 2; - } - else - { - return false; - } - } - } - return true; - } - template - bool gbkTrans(const string& str, Uint16Container& vec) - { - return gbkTrans(str.c_str(), str.size(), vec); +template +bool gbkTrans(const char* const str, size_t len, Uint16Container& vec) { + vec.clear(); + if(!str) { + return false; + } + size_t i = 0; + while(i < len) { + if(0 == (str[i] & 0x80)) { + vec.push_back(uint16_t(str[i])); + i++; + } else { + if(i + 1 < len) { //&& (str[i+1] & 0x80)) + uint16_t tmp = (((uint16_t(str[i]) & 0x00ff ) << 8) | (uint16_t(str[i+1]) & 0x00ff)); + vec.push_back(tmp); + i += 2; + } else { + return false; + } } + } + return true; +} - template - bool gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) - { - if(begin >= end) - { - return false; - } - res.clear(); - //pair pa; - char first, second; - while(begin != end) - { - //pa = uint16ToChar2(*begin); - first = ((*begin)>>8) & 0x00ff; - second = (*begin) & 0x00ff; - if(first & 0x80) - { - res += first; - res += second; - } - else - { - res += second; - } - begin++; - } - return true; - } +template +bool gbkTrans(const string& str, Uint16Container& vec) { + return gbkTrans(str.c_str(), str.size(), vec); +} - /* - * format example: "%Y-%m-%d %H:%M:%S" - */ - inline void getTime(const string& format, string& timeStr) - { - time_t timeNow; - time(&timeNow); - timeStr.resize(64); - size_t len = strftime((char*)timeStr.c_str(), timeStr.size(), format.c_str(), localtime(&timeNow)); - timeStr.resize(len); +template +bool gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) { + if(begin >= end) { + return false; + } + res.clear(); + //pair pa; + char first, second; + while(begin != end) { + //pa = uint16ToChar2(*begin); + first = ((*begin)>>8) & 0x00ff; + second = (*begin) & 0x00ff; + if(first & 0x80) { + res += first; + res += second; + } else { + res += second; } + begin++; + } + return true; +} + +/* + * format example: "%Y-%m-%d %H:%M:%S" + */ +inline void getTime(const string& format, string& timeStr) { + time_t timeNow; + time(&timeNow); + timeStr.resize(64); + size_t len = strftime((char*)timeStr.c_str(), timeStr.size(), format.c_str(), localtime(&timeNow)); + timeStr.resize(len); +} + +inline string pathJoin(const string& path1, const string& path2) { + if(endsWith(path1, "/")) { + return path1 + path2; + } + return path1 + "/" + path2; +} + } #endif diff --git a/src/Limonp/Thread.hpp b/src/Limonp/Thread.hpp index a5b3153..563ec60 100644 --- a/src/Limonp/Thread.hpp +++ b/src/Limonp/Thread.hpp @@ -4,47 +4,39 @@ #include "HandyMacro.hpp" #include "NonCopyable.hpp" -namespace Limonp -{ - class IThread: NonCopyable - { - private: - pthread_t thread_; - bool isStarted; - bool isJoined; - public: - IThread(): isStarted(false), isJoined(false) - { - } - virtual ~IThread() - { - if(isStarted && !isJoined) - { - LIMONP_CHECK(!pthread_detach(thread_)); - } - }; - public: - virtual void run() = 0; - void start() - { - assert(!isStarted); - LIMONP_CHECK(!pthread_create(&thread_, NULL, worker_, this)); - isStarted = true; - } - void join() - { - assert(!isJoined); - LIMONP_CHECK(!pthread_join(thread_, NULL)); - isJoined = true; - } - private: - static void * worker_(void * data) - { - IThread * ptr = (IThread* ) data; - ptr->run(); - return NULL; - } - }; +namespace Limonp { +class IThread: NonCopyable { + private: + pthread_t thread_; + bool isStarted; + bool isJoined; + public: + IThread(): isStarted(false), isJoined(false) { + } + virtual ~IThread() { + if(isStarted && !isJoined) { + LIMONP_CHECK(!pthread_detach(thread_)); + } + }; + public: + virtual void run() = 0; + void start() { + LIMONP_CHECK(!isStarted); + LIMONP_CHECK(!pthread_create(&thread_, NULL, worker_, this)); + isStarted = true; + } + void join() { + LIMONP_CHECK(!isJoined); + LIMONP_CHECK(!pthread_join(thread_, NULL)); + isJoined = true; + } + private: + static void * worker_(void * data) { + IThread * ptr = (IThread* ) data; + ptr->run(); + return NULL; + } +}; } #endif diff --git a/src/Limonp/ThreadPool.hpp b/src/Limonp/ThreadPool.hpp index 493c2ce..cc68516 100644 --- a/src/Limonp/ThreadPool.hpp +++ b/src/Limonp/ThreadPool.hpp @@ -4,102 +4,87 @@ #include "Thread.hpp" #include "BlockingQueue.hpp" -namespace Limonp -{ - class ITask - { - public: - virtual void run() = 0; - virtual ~ITask() {} - }; +namespace Limonp { +class ITask { + public: + virtual void run() = 0; + virtual ~ITask() {} +}; - template - ITask* CreateTask(ArgType arg) - { - return new TaskType(arg); - } - template - ITask* CreateTask(ArgType0 arg0, ArgType1 arg1) - { - return new TaskType(arg0, arg1); +template +ITask* CreateTask(ArgType arg) { + return new TaskType(arg); +} +template +ITask* CreateTask(ArgType0 arg0, ArgType1 arg1) { + return new TaskType(arg0, arg1); +} +template +ITask* CreateTask(ArgType0 arg0, ArgType1 arg1, ArgType2 arg2) { + return new TaskType(arg0, arg1, arg2); +} + +//class ThreadPool; +class ThreadPool: NonCopyable { + private: + class Worker: public IThread { + private: + ThreadPool * ptThreadPool_; + public: + Worker(ThreadPool* pool): ptThreadPool_(pool) { + assert(ptThreadPool_); + } + virtual ~Worker() { + } + public: + virtual void run() { + while(true) { + ITask * task = ptThreadPool_->queue_.pop(); + if(task == NULL) { + break; } + task->run(); + delete task; + } + } + }; + private: + friend class Worker; + private: + vector threads_; + BoundedBlockingQueue queue_; + //mutable MutexLock mutex_; + //Condition isEmpty__; + public: + ThreadPool(size_t threadNum, size_t queueMaxSize): threads_(threadNum), queue_(queueMaxSize) { //, mutex_(), isEmpty__(mutex_) + assert(threadNum); + assert(queueMaxSize); + for(size_t i = 0; i < threads_.size(); i ++) { + threads_[i] = new Worker(this); + } + } + ~ThreadPool() { + for(size_t i = 0; i < threads_.size(); i ++) { + queue_.push(NULL); + } + for(size_t i = 0; i < threads_.size(); i ++) { + threads_[i]->join(); + delete threads_[i]; + } + } - //class ThreadPool; - class ThreadPool: NonCopyable - { - private: - class Worker: public IThread - { - private: - ThreadPool * ptThreadPool_; - public: - Worker(ThreadPool* pool): ptThreadPool_(pool) - { - assert(ptThreadPool_); - } - virtual ~Worker() - { - } - public: - virtual void run() - { - while(true) - { - ITask * task = ptThreadPool_->queue_.pop(); - if(task == NULL) - { - break; - } - task->run(); - delete task; - } - } - }; - private: - friend class Worker; - private: - vector threads_; - BoundedBlockingQueue queue_; - //mutable MutexLock mutex_; - //Condition isEmpty__; - public: - ThreadPool(size_t threadNum, size_t queueMaxSize): threads_(threadNum), queue_(queueMaxSize)//, mutex_(), isEmpty__(mutex_) - { - assert(threadNum); - assert(queueMaxSize); - for(size_t i = 0; i < threads_.size(); i ++) - { - threads_[i] = new Worker(this); - } - } - ~ThreadPool() - { - for(size_t i = 0; i < threads_.size(); i ++) - { - queue_.push(NULL); - } - for(size_t i = 0; i < threads_.size(); i ++) - { - threads_[i]->join(); - delete threads_[i]; - } - } - - public: - void start() - { - for(size_t i = 0; i < threads_.size(); i++) - { - threads_[i]->start(); - } - } + public: + void start() { + for(size_t i = 0; i < threads_.size(); i++) { + threads_[i]->start(); + } + } - void add(ITask* task) - { - assert(task); - queue_.push(task); - } - }; + void add(ITask* task) { + assert(task); + queue_.push(task); + } +}; } #endif diff --git a/test/load_test.cpp b/test/load_test.cpp index 5abe2e7..6ac3ef6 100644 --- a/test/load_test.cpp +++ b/test/load_test.cpp @@ -5,6 +5,7 @@ #include "../src/HMMSegment.hpp" #include "../src/MixSegment.hpp" #include "../src/KeywordExtractor.hpp" +#include "../src/Limonp/Colors.hpp" using namespace CppJieba; @@ -24,8 +25,9 @@ void cut(size_t times = 50) res.clear(); seg.cut(doc, res); } + printf("\n"); long endTime = clock(); - printf("\ncut: [%.3lf seconds]time consumed.\n", double(endTime - beginTime)/CLOCKS_PER_SEC); + ColorPrintln(GREEN, "cut: [%.3lf seconds]time consumed.", double(endTime - beginTime)/CLOCKS_PER_SEC); } void extract(size_t times = 400) @@ -44,8 +46,9 @@ void extract(size_t times = 400) words.clear(); extractor.extract(doc, words, 5); } + printf("\n"); long endTime = clock(); - printf("\nextract: [%.3lf seconds]time consumed.\n", double(endTime - beginTime)/CLOCKS_PER_SEC); + ColorPrintln(GREEN, "extract: [%.3lf seconds]time consumed.", double(endTime - beginTime)/CLOCKS_PER_SEC); } int main(int argc, char ** argv)