upload limonp for Colors.hpp and use ColorPrintln in load_test.cpp

This commit is contained in:
yanyiwu 2015-01-28 21:27:46 +08:00
parent 8c23da4332
commit 660cd9d93e
19 changed files with 1229 additions and 1426 deletions

View File

@ -10,75 +10,58 @@
#include <sstream> #include <sstream>
#include "StringUtil.hpp" #include "StringUtil.hpp"
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; class ArgvContext {
class ArgvContext public :
{ ArgvContext(int argc, const char* const * argv) {
public :
ArgvContext(int argc, const char* const * argv)
{
for(int i = 0; i < argc; i++) for(int i = 0; i < argc; i++) {
{ if(startsWith(argv[i], "-")) {
if(startsWith(argv[i], "-")) if(i + 1 < argc && !startsWith(argv[i + 1], "-")) {
{ mpss_[argv[i]] = argv[i+1];
if(i + 1 < argc && !startsWith(argv[i + 1], "-")) i++;
{ } else {
mpss_[argv[i]] = argv[i+1]; sset_.insert(argv[i]);
i++; }
} } else {
else args_.push_back(argv[i]);
{ }
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<string, string>::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<string> args_;
map<string, string> mpss_;
set<string> sset_;
};
inline ostream& operator << (ostream& os, const ArgvContext& args)
{
return os<<args.args_<<args.mpss_<<args.sset_;
} }
}
~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<string, string>::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<string> args_;
map<string, string> mpss_;
set<string> sset_;
};
inline ostream& operator << (ostream& os, const ArgvContext& args) {
return os<<args.args_<<args.mpss_<<args.sset_;
}
} }
#endif #endif

View File

@ -9,119 +9,102 @@ https://github.com/chenshuo/muduo/blob/master/muduo/base/BlockingQueue.h
#include "BoundedQueue.hpp" #include "BoundedQueue.hpp"
#include "Condition.hpp" #include "Condition.hpp"
namespace Limonp namespace Limonp {
{ template<class T>
template<class T> class BlockingQueue: NonCopyable {
class BlockingQueue: NonCopyable public:
{ BlockingQueue()
public: : mutex_(), notEmpty_(mutex_), queue_() {
BlockingQueue() }
: mutex_(), notEmpty_(mutex_), queue_()
{
}
void push(const T& x) void push(const T& x) {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); queue_.push(x);
queue_.push(x); notEmpty_.notify(); // wait morphing saves us
notEmpty_.notify(); // wait morphing saves us }
}
T pop() T pop() {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); // always use a while-loop, due to spurious wakeup
// always use a while-loop, due to spurious wakeup while (queue_.empty()) {
while (queue_.empty()) notEmpty_.wait();
{ }
notEmpty_.wait(); assert(!queue_.empty());
} T front(queue_.front());
assert(!queue_.empty()); queue_.pop();
T front(queue_.front()); return front;
queue_.pop(); }
return front;
}
size_t size() const size_t size() const {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); return queue_.size();
return queue_.size(); }
} bool empty() const {
bool empty() const return size() == 0;
{ }
return size() == 0;
}
private: private:
mutable MutexLock mutex_; mutable MutexLock mutex_;
Condition notEmpty_; Condition notEmpty_;
std::queue<T> queue_; std::queue<T> queue_;
}; };
template<typename T> template<typename T>
class BoundedBlockingQueue : NonCopyable class BoundedBlockingQueue : NonCopyable {
{ public:
public: explicit BoundedBlockingQueue(size_t maxSize)
explicit BoundedBlockingQueue(size_t maxSize) : mutex_(),
: mutex_(), notEmpty_(mutex_),
notEmpty_(mutex_), notFull_(mutex_),
notFull_(mutex_), queue_(maxSize) {
queue_(maxSize) }
{}
void push(const T& x) void push(const T& x) {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); while (queue_.full()) {
while (queue_.full()) notFull_.wait();
{ }
notFull_.wait(); assert(!queue_.full());
} queue_.push(x);
assert(!queue_.full()); notEmpty_.notify();
queue_.push(x); }
notEmpty_.notify();
}
T pop() T pop() {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); while (queue_.empty()) {
while (queue_.empty()) notEmpty_.wait();
{ }
notEmpty_.wait(); assert(!queue_.empty());
} T res = queue_.pop();
assert(!queue_.empty()); notFull_.notify();
T res = queue_.pop(); return res;
notFull_.notify(); }
return res;
}
bool empty() const bool empty() const {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); return queue_.empty();
return queue_.empty(); }
}
bool full() const bool full() const {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); return queue_.full();
return queue_.full(); }
}
size_t size() const size_t size() const {
{ MutexLockGuard lock(mutex_);
MutexLockGuard lock(mutex_); return queue_.size();
return queue_.size(); }
}
size_t capacity() const size_t capacity() const {
{ return queue_.capacity();
return queue_.capacity(); }
}
private: private:
mutable MutexLock mutex_; mutable MutexLock mutex_;
Condition notEmpty_; Condition notEmpty_;
Condition notFull_; Condition notFull_;
BoundedQueue<T> queue_; BoundedQueue<T> queue_;
}; };
} }

View File

@ -5,69 +5,59 @@
#include <fstream> #include <fstream>
#include <cassert> #include <cassert>
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; template<class T>
template<class T> class BoundedQueue {
class BoundedQueue private:
{ size_t head_;
private: size_t tail_;
size_t head_; size_t size_;
size_t tail_; const size_t capacity_;
size_t size_; vector<T> circular__buffer;
const size_t capacity_; public:
vector<T> circular__buffer; explicit BoundedQueue(size_t capacity): capacity_(capacity), circular__buffer(capacity) {
public: head_ = 0;
explicit BoundedQueue(size_t capacity): capacity_(capacity), circular__buffer(capacity) tail_ = 0;
{ size_ = 0;
head_ = 0; assert(capacity_);
tail_ = 0; }
size_ = 0; ~BoundedQueue() {}
assert(capacity_); public:
} void clear() {
~BoundedQueue(){} head_ = 0;
public: tail_ = 0;
void clear() size_ = 0;
{ }
head_ = 0; bool empty() const {
tail_ = 0; return !size_;
size_ = 0; }
} bool full() const {
bool empty() const return capacity_ == size_;
{ }
return !size_; size_t size() const {
} return size_;
bool full() const }
{ size_t capacity() const {
return capacity_ == size_; return capacity_;
} }
size_t size() const
{
return size_;
}
size_t capacity() const
{
return capacity_;
}
void push(const T& t) void push(const T& t) {
{ assert(!full());
assert(!full()); circular__buffer[tail_] = t;
circular__buffer[tail_] = t; tail_ = (tail_ + 1) % capacity_;
tail_ = (tail_ + 1) % capacity_; size_ ++;
size_ ++; }
}
T pop() T pop() {
{ assert(!empty());
assert(!empty()); size_t oldPos = head_;
size_t oldPos = head_; head_ = (head_ + 1) % capacity_;
head_ = (head_ + 1) % capacity_; size_ --;
size_ --; return circular__buffer[oldPos];
return circular__buffer[oldPos]; }
}
}; };
} }
#endif #endif

View File

@ -1,90 +1,82 @@
#ifndef LIMONP_CAST_FUNCTS_H #ifndef LIMONP_CAST_FUNCTS_H
#define LIMONP_CAST_FUNCTS_H #define LIMONP_CAST_FUNCTS_H
namespace Limonp namespace Limonp {
{ namespace CastFloat {
namespace CastFloat //logical and or
{ static const int sign_32 = 0xC0000000;
//logical and or static const int exponent_32 = 0x07800000;
static const int sign_32 = 0xC0000000; static const int mantissa_32 = 0x007FE000;
static const int exponent_32 = 0x07800000; static const int sign_exponent_32 = 0x40000000;
static const int mantissa_32 = 0x007FE000; static const int loss_32 = 0x38000000;
static const int sign_exponent_32 = 0x40000000;
static const int loss_32 = 0x38000000;
static const short sign_16 = (short)0xC000; static const short sign_16 = (short)0xC000;
static const short exponent_16 = (short)0x3C00; static const short exponent_16 = (short)0x3C00;
static const short mantissa_16 = (short)0x03FF; static const short mantissa_16 = (short)0x03FF;
static const short sign_exponent_16 = (short)0x4000; static const short sign_exponent_16 = (short)0x4000;
static const int exponent_fill_32 = 0x38000000; static const int exponent_fill_32 = 0x38000000;
//infinite //infinite
static const short infinite_16 = (short) 0x7FFF; static const short infinite_16 = (short) 0x7FFF;
static const short infinitesmall_16 = (short) 0x0000; static const short infinitesmall_16 = (short) 0x0000;
inline float intBitsToFloat(unsigned int x) inline float intBitsToFloat(unsigned int x) {
{ union {
union float f;
{ int i;
float f; } u;
int i; u.i = x;
}u; return u.f;
u.i = x; }
return u.f;
}
inline int floatToIntBits(float f) inline int floatToIntBits(float f) {
{ union {
union float f;
{ int i ;
float f; } u;
int i ; u.f = f;
}u; return u.i;
u.f = f; }
return u.i;
}
inline short floatToShortBits(float f) inline short floatToShortBits(float f) {
{ int fi = floatToIntBits(f);
int fi = floatToIntBits(f);
// 提取关键信息 // 提取关键信息
short sign = (short) ((unsigned int)(fi & sign_32) >> 16); short sign = (short) ((unsigned int)(fi & sign_32) >> 16);
short exponent = (short) ((unsigned int)(fi & exponent_32) >> 13); short exponent = (short) ((unsigned int)(fi & exponent_32) >> 13);
short mantissa = (short) ((unsigned int)(fi & mantissa_32) >> 13); short mantissa = (short) ((unsigned int)(fi & mantissa_32) >> 13);
// 生成编码结果 // 生成编码结果
short code = (short) (sign | exponent | mantissa); short code = (short) (sign | exponent | mantissa);
// 无穷大量、无穷小量的处理 // 无穷大量、无穷小量的处理
if ((fi & loss_32) > 0 && (fi & sign_exponent_32) > 0) { if ((fi & loss_32) > 0 && (fi & sign_exponent_32) > 0) {
// 当指数符号为1时(正次方)且左234位为1返回无穷大量 // 当指数符号为1时(正次方)且左234位为1返回无穷大量
return (short) (code | infinite_16); return (short) (code | infinite_16);
} }
if (((fi & loss_32) ^ loss_32) > 0 && (fi & sign_exponent_32) == 0) { if (((fi & loss_32) ^ loss_32) > 0 && (fi & sign_exponent_32) == 0) {
// 当指数符号位0时(负次方)且左234位为0(与111异或>0),返回无穷小量 // 当指数符号位0时(负次方)且左234位为0(与111异或>0),返回无穷小量
return infinitesmall_16; return infinitesmall_16;
} }
return code; return code;
} }
inline float shortBitsToFloat(short s) inline float shortBitsToFloat(short s) {
{ /*
/* * 31001 0(13)
* 31001 0(13) */
*/ int sign = ((int) (s & sign_16)) << 16;
int sign = ((int) (s & sign_16)) << 16; int exponent = ((int) (s & exponent_16)) << 13;
int exponent = ((int) (s & exponent_16)) << 13; // 指数符号位为0234位补1
// 指数符号位为0234位补1 if ((s & sign_exponent_16) == 0 && s != 0) {
if ((s & sign_exponent_16) == 0 && s != 0) { exponent |= exponent_fill_32;
exponent |= exponent_fill_32; }
} int mantissa = ((int) (s & mantissa_16)) << 13;
int mantissa = ((int) (s & mantissa_16)) << 13; // 生成解码结果
// 生成解码结果 int code = sign | exponent | mantissa;
int code = sign | exponent | mantissa; return intBitsToFloat(code);
return intBitsToFloat(code);
} }
} }
} }
#endif #endif

36
src/Limonp/Colors.hpp Normal file
View File

@ -0,0 +1,36 @@
#ifndef LIMONP_COLOR_PRINT_HPP
#define LIMONP_COLOR_PRINT_HPP
#include <string>
#include <stdarg.h>
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

View File

@ -7,41 +7,34 @@
#include "MutexLock.hpp" #include "MutexLock.hpp"
namespace Limonp namespace Limonp {
{ class Condition : NonCopyable {
class Condition : NonCopyable public:
{ explicit Condition(MutexLock& mutex)
public: : mutex_(mutex) {
explicit Condition(MutexLock& mutex) LIMONP_CHECK(!pthread_cond_init(&pcond_, NULL));
: mutex_(mutex) }
{
LIMONP_CHECK(!pthread_cond_init(&pcond_, NULL));
}
~Condition() ~Condition() {
{ LIMONP_CHECK(!pthread_cond_destroy(&pcond_));
LIMONP_CHECK(!pthread_cond_destroy(&pcond_)); }
}
void wait() void wait() {
{ LIMONP_CHECK(!pthread_cond_wait(&pcond_, mutex_.getPthreadMutex()));
LIMONP_CHECK(!pthread_cond_wait(&pcond_, mutex_.getPthreadMutex())); }
}
void notify() void notify() {
{ LIMONP_CHECK(!pthread_cond_signal(&pcond_));
LIMONP_CHECK(!pthread_cond_signal(&pcond_)); }
}
void notifyAll() void notifyAll() {
{ LIMONP_CHECK(!pthread_cond_broadcast(&pcond_));
LIMONP_CHECK(!pthread_cond_broadcast(&pcond_)); }
}
private: private:
MutexLock& mutex_; MutexLock& mutex_;
pthread_cond_t pcond_; pthread_cond_t pcond_;
}; };
} }

View File

@ -12,107 +12,90 @@
#include <assert.h> #include <assert.h>
#include "StringUtil.hpp" #include "StringUtil.hpp"
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; class Config {
class Config public:
{ explicit Config(const string& filePath) {
public: loadFile_(filePath);
explicit Config(const string& filePath) }
{ public:
loadFile_(filePath); operator bool () {
} return !map_.empty();
public: }
operator bool () private:
{ void loadFile_(const string& filePath) {
return !map_.empty(); ifstream ifs(filePath.c_str());
} assert(ifs);
private: string line;
void loadFile_(const string& filePath) vector<string> vecBuf;
{ size_t lineno = 0;
ifstream ifs(filePath.c_str()); while(getline(ifs, line)) {
assert(ifs); lineno ++;
string line; trim(line);
vector<string> vecBuf; if(line.empty() || startsWith(line, "#")) {
size_t lineno = 0; continue;
while(getline(ifs, line)) }
{ vecBuf.clear();
lineno ++; if(!split(line, vecBuf, "=") || 2 != vecBuf.size()) {
trim(line); fprintf(stderr, "line[%s] illegal.\n", line.c_str());
if(line.empty() || startsWith(line, "#")) assert(false);
{ continue;
continue; }
} string& key = vecBuf[0];
vecBuf.clear(); string& value = vecBuf[1];
if(!split(line, vecBuf, "=") || 2 != vecBuf.size()) trim(key);
{ trim(value);
fprintf(stderr, "line[%s] illegal.\n", line.c_str()); if(!map_.insert(make_pair(key, value)).second) {
assert(false); fprintf(stderr, "key[%s] already exits.\n", key.c_str());
continue; 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<string, string>::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<string, string>::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<string, string> map_;
private:
friend ostream& operator << (ostream& os, const Config& config);
};
inline ostream& operator << (ostream& os, const Config& config)
{
return os << config.map_;
} }
ifs.close();
}
public:
bool get(const string& key, string& value) const {
map<string, string>::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<string, string>::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<string, string> map_;
private:
friend ostream& operator << (ostream& os, const Config& config);
};
inline ostream& operator << (ostream& os, const Config& config) {
return os << config.map_;
}
} }
#endif #endif

View File

@ -1,21 +1,25 @@
#ifndef LIMONP_INITONOFF_H #ifndef LIMONP_INITONOFF_H
#define LIMONP_INITONOFF_H #define LIMONP_INITONOFF_H
namespace Limonp namespace Limonp {
{ class InitOnOff {
class InitOnOff public:
{ InitOnOff():isInited_(false) {};
public: ~InitOnOff() {};
InitOnOff():isInited_(false){}; protected:
~InitOnOff(){}; bool isInited_;
protected: bool getInitFlag_()const {
bool isInited_; return isInited_;
bool getInitFlag_()const{return isInited_;}; };
bool setInitFlag_(bool flag){return isInited_ = flag;}; bool setInitFlag_(bool flag) {
public: return isInited_ = flag;
operator bool() const {return getInitFlag_();}; };
public:
operator bool() const {
return getInitFlag_();
};
}; };
} }
#endif #endif

View File

@ -6,165 +6,133 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; /*
/* * LocalVector<T> : T must be primitive type (char , int, size_t), if T is struct or class, LocalVector<T> may be dangerous..
* LocalVector<T> : T must be primitive type (char , int, size_t), if T is struct or class, LocalVector<T> may be dangerous.. * LocalVector<T> is simple and not well-tested.
* LocalVector<T> is simple and not well-tested. */
*/ const size_t LOCAL_VECTOR_BUFFER_SIZE = 16;
const size_t LOCAL_VECTOR_BUFFER_SIZE = 16; template <class T>
template <class T> class LocalVector {
class LocalVector public:
{ typedef const T* const_iterator ;
public: typedef T value_type;
typedef const T* const_iterator ; typedef size_t size_type;
typedef T value_type; private:
typedef size_t size_type; T buffer_[LOCAL_VECTOR_BUFFER_SIZE];
private: T * ptr_;
T buffer_[LOCAL_VECTOR_BUFFER_SIZE]; size_t size_;
T * ptr_; size_t capacity_;
size_t size_; public:
size_t capacity_; LocalVector() {
public: init_();
LocalVector() };
{ LocalVector(const LocalVector<T>& vec) {
init_(); init_();
}; *this = vec;
LocalVector(const LocalVector<T>& vec) }
{ LocalVector(const_iterator begin, const_iterator end) { // TODO: make it faster
init_(); init_();
*this = vec; while(begin != end) {
} push_back(*begin++);
LocalVector(const_iterator begin, const_iterator end) // TODO: make it faster }
{ }
init_(); LocalVector(size_t size, const T& t) { // TODO: make it faster
while(begin != end) init_();
{ while(size--) {
push_back(*begin++); push_back(t);
} }
} }
LocalVector(size_t size, const T& t) // TODO: make it faster ~LocalVector() {
{ if(ptr_ != buffer_) {
init_(); free(ptr_);
while(size--) }
{ };
push_back(t); public:
} LocalVector<T>& operator = (const LocalVector<T>& vec) {
} clear();
~LocalVector() size_ = vec.size();
{ capacity_ = vec.capacity();
if(ptr_ != buffer_) if(vec.buffer_ == vec.ptr_) {
{ memcpy(buffer_, vec.buffer_, sizeof(T) * size_);
free(ptr_); ptr_ = buffer_;
} } else {
}; ptr_ = (T*) malloc(vec.capacity() * sizeof(T));
public: assert(ptr_);
LocalVector<T>& operator = (const LocalVector<T>& vec) memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T));
{ }
clear(); return *this;
size_ = vec.size(); }
capacity_ = vec.capacity(); private:
if(vec.buffer_ == vec.ptr_) void init_() {
{ ptr_ = buffer_;
memcpy(buffer_, vec.buffer_, sizeof(T) * size_); size_ = 0;
ptr_ = buffer_; capacity_ = LOCAL_VECTOR_BUFFER_SIZE;
} }
else public:
{ T& operator [] (size_t i) {
ptr_ = (T*) malloc(vec.capacity() * sizeof(T)); return ptr_[i];
assert(ptr_); }
memcpy(ptr_, vec.ptr_, vec.size() * sizeof(T)); const T& operator [] (size_t i) const {
} return ptr_[i];
return *this; }
} void push_back(const T& t) {
private: if(size_ == capacity_) {
void init_() assert(capacity_);
{ reserve(capacity_ * 2);
ptr_ = buffer_; }
size_ = 0; ptr_[size_ ++ ] = t;
capacity_ = LOCAL_VECTOR_BUFFER_SIZE; }
} void reserve(size_t size) {
public: if(size <= capacity_) {
T& operator [] (size_t i) return;
{ }
return ptr_[i]; T * next = (T*)malloc(sizeof(T) * size);
} assert(next);
const T& operator [] (size_t i) const T * old = ptr_;
{ ptr_ = next;
return ptr_[i]; memcpy(ptr_, old, sizeof(T) * capacity_);
} capacity_ = size;
void push_back(const T& t) if(old != buffer_) {
{ free(old);
if(size_ == capacity_) }
{ }
assert(capacity_); bool empty() const {
reserve(capacity_ * 2); return 0 == size();
} }
ptr_[size_ ++ ] = t; size_t size() const {
} return size_;
void reserve(size_t size) }
{ size_t capacity() const {
if(size <= capacity_) return capacity_;
{ }
return; const_iterator begin() const {
} return ptr_;
T * next = (T*)malloc(sizeof(T) * size); }
assert(next); const_iterator end() const {
T * old = ptr_; return ptr_ + size_;
ptr_ = next; }
memcpy(ptr_, old, sizeof(T) * capacity_); void clear() {
capacity_ = size; if(ptr_ != buffer_) {
if(old != buffer_) free(ptr_);
{ }
free(old); init_();
} }
} };
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 <class T> template <class T>
ostream & operator << (ostream& os, const LocalVector<T>& vec) ostream & operator << (ostream& os, const LocalVector<T>& vec) {
{ if(vec.empty()) {
if(vec.empty()) return os << "[]";
{ }
return os << "[]"; os<<"[\""<<vec[0];
} for(size_t i = 1; i < vec.size(); i++) {
os<<"[\""<<vec[0]; os<<"\", \""<<vec[i];
for(size_t i = 1; i < vec.size(); i++) }
{ os<<"\"]";
os<<"\", \""<<vec[i]; return os;
} }
os<<"\"]";
return os;
}
} }

View File

@ -24,51 +24,47 @@
#define LogError(fmt, ...) Limonp::Logger::LoggingF(Limonp::LL_ERROR, FILE_BASENAME, __LINE__, fmt, ## __VA_ARGS__) #define LogError(fmt, ...) Limonp::Logger::LoggingF(Limonp::LL_ERROR, FILE_BASENAME, __LINE__, fmt, ## __VA_ARGS__)
#define LogFatal(fmt, ...) Limonp::Logger::LoggingF(Limonp::LL_FATAL, FILE_BASENAME, __LINE__, fmt, ## __VA_ARGS__) #define LogFatal(fmt, ...) Limonp::Logger::LoggingF(Limonp::LL_FATAL, FILE_BASENAME, __LINE__, fmt, ## __VA_ARGS__)
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; enum {LL_DEBUG = 0, LL_INFO = 1, LL_WARN = 2, LL_ERROR = 3, LL_FATAL = 4, LEVEL_ARRAY_SIZE = 5, CSTR_BUFFER_SIZE = 32};
enum {LL_DEBUG = 0, LL_INFO = 1, LL_WARN = 2, LL_ERROR = 3, LL_FATAL = 4, LEVEL_ARRAY_SIZE = 5, CSTR_BUFFER_SIZE = 32}; static const char * LOG_LEVEL_ARRAY[LEVEL_ARRAY_SIZE]= {"DEBUG","INFO","WARN","ERROR","FATAL"};
static const char * LOG_LEVEL_ARRAY[LEVEL_ARRAY_SIZE]= {"DEBUG","INFO","WARN","ERROR","FATAL"}; static const char * LOG_FORMAT = "%s %s:%d %s %s\n";
static const char * LOG_FORMAT = "%s %s:%d %s %s\n"; static const char * LOG_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
static const char * LOG_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
class Logger class Logger {
{ public:
public: static void Logging(size_t level, const string& msg, const char* fileName, int lineno) {
static void Logging(size_t level, const string& msg, const char* fileName, int lineno) assert(level <= LL_FATAL);
{ char buf[CSTR_BUFFER_SIZE];
assert(level <= LL_FATAL); time_t timeNow;
char buf[CSTR_BUFFER_SIZE]; time(&timeNow);
time_t timeNow; strftime(buf, sizeof(buf), LOG_TIME_FORMAT, localtime(&timeNow));
time(&timeNow); fprintf(stderr, LOG_FORMAT, buf, fileName, lineno,LOG_LEVEL_ARRAY[level], msg.c_str());
strftime(buf, sizeof(buf), LOG_TIME_FORMAT, localtime(&timeNow)); }
fprintf(stderr, LOG_FORMAT, buf, fileName, lineno,LOG_LEVEL_ARRAY[level], msg.c_str()); static void LoggingF(size_t level, const char* fileName, int lineno, const char* const fmt, ...) {
}
static void LoggingF(size_t level, const char* fileName, int lineno, const char* const fmt, ...)
{
#ifdef LOGGER_LEVEL #ifdef LOGGER_LEVEL
if(level < LOGGER_LEVEL) return; if(level < LOGGER_LEVEL) return;
#endif #endif
int size = 256; int size = 256;
string msg; string msg;
va_list ap; va_list ap;
while (1) { while (1) {
msg.resize(size); msg.resize(size);
va_start(ap, fmt); va_start(ap, fmt);
int n = vsnprintf((char *)msg.c_str(), size, fmt, ap); int n = vsnprintf((char *)msg.c_str(), size, fmt, ap);
va_end(ap); va_end(ap);
if (n > -1 && n < size) { if (n > -1 && n < size) {
msg.resize(n); msg.resize(n);
break; break;
} }
if (n > -1) if (n > -1)
size = n + 1; size = n + 1;
else else
size *= 2; size *= 2;
} }
Logging(level, msg, fileName, lineno); Logging(level, msg, fileName, lineno);
} }
}; };
} }
#endif #endif

View File

@ -31,8 +31,7 @@
#include <cstring> #include <cstring>
#include <iostream> #include <iostream>
namespace Limonp namespace Limonp {
{
//#pragma region MD5 defines //#pragma region MD5 defines
// Constants for MD5Transform routine. // Constants for MD5Transform routine.
@ -106,9 +105,8 @@ static unsigned char PADDING[64] = {
}; };
// convenient object that wraps // convenient object that wraps
// the C-functions for use in C++ only // the C-functions for use in C++ only
class MD5 class MD5 {
{ private:
private:
struct __context_t { struct __context_t {
UINT4 state[4]; /* state (ABCD) */ UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
@ -118,8 +116,7 @@ private:
//#pragma region static helper functions //#pragma region static helper functions
// The core of the MD5 algorithm is here. // The core of the MD5 algorithm is here.
// MD5 basic transformation. Transforms state based on block. // 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]; UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64); Decode (x, block, 64);
@ -207,8 +204,7 @@ private:
// Encodes input (UINT4) into output (unsigned char). Assumes len is // Encodes input (UINT4) into output (unsigned char). Assumes len is
// a multiple of 4. // 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; unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) { for (i = 0, j = 0; j < len; i++, j += 4) {
@ -221,27 +217,24 @@ private:
// Decodes input (unsigned char) into output (UINT4). Assumes len is // Decodes input (unsigned char) into output (UINT4). Assumes len is
// a multiple of 4. // 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; unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | 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 //#pragma endregion
public: public:
// MAIN FUNCTIONS // MAIN FUNCTIONS
MD5() MD5() {
{
Init() ; Init() ;
} }
// MD5 initialization. Begins an MD5 operation, writing a new context. // MD5 initialization. Begins an MD5 operation, writing a new context.
void Init() void Init() {
{
context.count[0] = context.count[1] = 0; context.count[0] = context.count[1] = 0;
// Load magic initialization constants. // Load magic initialization constants.
@ -256,8 +249,7 @@ public:
// context. // context.
void Update( void Update(
unsigned char *input, // input block unsigned char *input, // input block
unsigned int inputLen ) // length of input block unsigned int inputLen ) { // length of input block
{
unsigned int i, index, partLen; unsigned int i, index, partLen;
// Compute number of bytes mod 64 // Compute number of bytes mod 64
@ -265,7 +257,7 @@ public:
// Update number of bits // Update number of bits
if ((context.count[0] += ((UINT4)inputLen << 3)) if ((context.count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3))
context.count[1]++; context.count[1]++;
context.count[1] += ((UINT4)inputLen >> 29); context.count[1] += ((UINT4)inputLen >> 29);
@ -280,8 +272,7 @@ public:
MD5Transform (context.state, &input[i]); MD5Transform (context.state, &input[i]);
index = 0; index = 0;
} } else
else
i = 0; i = 0;
/* Buffer remaining input */ /* Buffer remaining input */
@ -291,8 +282,7 @@ public:
// MD5 finalization. Ends an MD5 message-digest operation, writing the // MD5 finalization. Ends an MD5 message-digest operation, writing the
// the message digest and zeroizing the context. // the message digest and zeroizing the context.
// Writes to digestRaw // Writes to digestRaw
void Final() void Final() {
{
unsigned char bits[8]; unsigned char bits[8];
unsigned int index, padLen; unsigned int index, padLen;
@ -317,8 +307,7 @@ public:
} }
/// Buffer must be 32+1 (nul) = 33 chars long at least /// Buffer must be 32+1 (nul) = 33 chars long at least
void writeToString() void writeToString() {
{
int pos ; int pos ;
for( pos = 0 ; pos < 16 ; 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) // an MD5 digest is a 16-byte number (32 hex digits)
BYTE digestRaw[ 16 ] ; BYTE digestRaw[ 16 ] ;
@ -336,10 +325,9 @@ public:
/// Load a file from disk and digest it /// Load a file from disk and digest it
// Digests a file and returns the result. // 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) if (NULL == filename || strcmp(filename, "") == 0)
return NULL; return NULL;
Init() ; Init() ;
@ -347,8 +335,7 @@ public:
unsigned char buffer[1024] ; unsigned char buffer[1024] ;
if((file = fopen (filename, "rb")) == NULL) if((file = fopen (filename, "rb")) == NULL) {
{
return NULL; return NULL;
} }
int len; int len;
@ -362,10 +349,9 @@ public:
} }
/// Digests a byte-array already in memory /// Digests a byte-array already in memory
const char* digestMemory( BYTE *memchunk, int len ) const char* digestMemory( BYTE *memchunk, int len ) {
{
if (NULL == memchunk) if (NULL == memchunk)
return NULL; return NULL;
Init() ; Init() ;
Update( memchunk, len ) ; Update( memchunk, len ) ;
@ -375,10 +361,9 @@ public:
} }
// Digests a string and prints the result. // Digests a string and prints the result.
const char* digestString(const char *string ) const char* digestString(const char *string ) {
{
if (string == NULL) if (string == NULL)
return NULL; return NULL;
Init() ; Init() ;
Update( (unsigned char*)string, strlen(string) ) ; Update( (unsigned char*)string, strlen(string) ) ;
@ -388,45 +373,39 @@ public:
} }
}; };
inline bool md5String(const char* str, std::string& res) inline bool md5String(const char* str, std::string& res) {
{ if (NULL == str) {
if (NULL == str) res = "";
{ return false;
res = ""; }
return false;
}
MD5 md5; MD5 md5;
const char *pRes = md5.digestString(str); const char *pRes = md5.digestString(str);
if (NULL == pRes) if (NULL == pRes) {
{ res = "";
res = ""; return false;
return false; }
}
res = pRes; res = pRes;
return true; return true;
} }
inline bool md5File(const char* filepath, std::string& res) inline bool md5File(const char* filepath, std::string& res) {
{ if (NULL == filepath || strcmp(filepath, "") == 0) {
if (NULL == filepath || strcmp(filepath, "") == 0) res = "";
{ return false;
res = ""; }
return false;
}
MD5 md5; MD5 md5;
const char *pRes = md5.digestFile(filepath); const char *pRes = md5.digestFile(filepath);
if (NULL == pRes) if (NULL == pRes) {
{ res = "";
res = ""; return false;
return false; }
}
res = pRes; res = pRes;
return true; return true;
} }
} }
#endif #endif

View File

@ -5,52 +5,42 @@
#include "NonCopyable.hpp" #include "NonCopyable.hpp"
#include "HandyMacro.hpp" #include "HandyMacro.hpp"
namespace Limonp namespace Limonp {
{ class MutexLock: NonCopyable {
class MutexLock: NonCopyable private:
{ pthread_mutex_t mutex_;
private: public:
pthread_mutex_t mutex_; pthread_mutex_t* getPthreadMutex() {
public: return &mutex_;
pthread_mutex_t* getPthreadMutex() }
{ public:
return &mutex_; MutexLock() {
} LIMONP_CHECK(!pthread_mutex_init(&mutex_, NULL));
public: }
MutexLock() ~MutexLock() {
{ LIMONP_CHECK(!pthread_mutex_destroy(&mutex_));
LIMONP_CHECK(!pthread_mutex_init(&mutex_, NULL)); }
} private:
~MutexLock() void lock() {
{ LIMONP_CHECK(!pthread_mutex_lock(&mutex_));
LIMONP_CHECK(!pthread_mutex_destroy(&mutex_)); }
} void unlock() {
private: LIMONP_CHECK(!pthread_mutex_unlock(&mutex_));
void lock() }
{ friend class MutexLockGuard;
LIMONP_CHECK(!pthread_mutex_lock(&mutex_)); };
} class MutexLockGuard: NonCopyable {
void unlock() public:
{ explicit MutexLockGuard(MutexLock & mutex)
LIMONP_CHECK(!pthread_mutex_unlock(&mutex_)); : mutex_(mutex) {
} mutex_.lock();
friend class MutexLockGuard; }
}; ~MutexLockGuard() {
class MutexLockGuard: NonCopyable mutex_.unlock();
{ }
public: private:
explicit MutexLockGuard(MutexLock & mutex) MutexLock & mutex_;
: mutex_(mutex) };
{
mutex_.lock();
}
~MutexLockGuard()
{
mutex_.unlock();
}
private:
MutexLock & mutex_;
};
#define MutexLockGuard(x) assert(false); #define MutexLockGuard(x) assert(false);
} }

View File

@ -8,118 +8,100 @@
#include "Logger.hpp" #include "Logger.hpp"
#include "InitOnOff.hpp" #include "InitOnOff.hpp"
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; class MysqlClient: public InitOnOff {
class MysqlClient: public InitOnOff public:
{ typedef vector< vector<string> > RowsType;
public: private:
typedef vector< vector<string> > RowsType; const string host_;
private: const size_t port_;
const string host_; const string user_;
const size_t port_; const string passwd_;
const string user_; const string db_;
const string passwd_; const string charset_;
const string db_; public:
const string charset_; 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) {
public: setInitFlag_(init_());
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) }
{ ~MysqlClient() {
setInitFlag_(init_()); if(conn_) {
} mysql_close(conn_);
~MysqlClient() }
{ };
if(conn_) private:
{ bool init_() {
mysql_close(conn_); //cout<<mysql_get_client_info()<<endl;
} if(NULL == (conn_ = mysql_init(NULL))) {
}; LogError("mysql_init faield. %s", mysql_error(conn_));
private: return false;
bool init_() }
{
//cout<<mysql_get_client_info()<<endl;
if(NULL == (conn_ = mysql_init(NULL)))
{
LogError("mysql_init faield. %s", mysql_error(conn_));
return false;
}
if (mysql_real_connect(conn_, host_.c_str(), user_.c_str(), passwd_.c_str(), db_.c_str(), port_, NULL, 0) == NULL) if (mysql_real_connect(conn_, host_.c_str(), user_.c_str(), passwd_.c_str(), db_.c_str(), port_, NULL, 0) == NULL) {
{ LogError("mysql_real_connect failed. %s", mysql_error(conn_));
LogError("mysql_real_connect failed. %s", mysql_error(conn_)); mysql_close(conn_);
mysql_close(conn_); conn_ = NULL;
conn_ = NULL; return false;
return false; }
}
if(mysql_set_character_set(conn_, charset_.c_str())) if(mysql_set_character_set(conn_, charset_.c_str())) {
{ LogError("mysql_set_character_set [%s] failed.", charset_.c_str());
LogError("mysql_set_character_set [%s] failed.", charset_.c_str()); return false;
return false; }
}
//set reconenct //set reconenct
char value = 1; char value = 1;
mysql_options(conn_, MYSQL_OPT_RECONNECT, &value); mysql_options(conn_, MYSQL_OPT_RECONNECT, &value);
LogInfo("MysqlClient {host: %s, database:%s, charset:%s}", host_.c_str(), db_.c_str(), charset_.c_str()); LogInfo("MysqlClient {host: %s, database:%s, charset:%s}", host_.c_str(), db_.c_str(), charset_.c_str());
return true; return true;
} }
public: public:
bool executeSql(const string& sql) bool executeSql(const string& sql) {
{ assert(getInitFlag_());
assert(getInitFlag_()); if(mysql_query(conn_, sql.c_str())) {
if(mysql_query(conn_, sql.c_str())) LogError("mysql_query failed. %s", mysql_error(conn_));
{ return false;
LogError("mysql_query failed. %s", mysql_error(conn_)); }
return false; return true;
} }
return true; size_t insert(const string& tableName, const string& keys, const vector<string>& vals) {
} size_t retn = 0;
size_t insert(const string& tableName, const string& keys, const vector<string>& vals) string sql;
{ for(size_t i = 0; i < vals.size(); i ++) {
size_t retn = 0; sql.clear();
string sql; string_format(sql, "insert into %s (%s) values %s", tableName.c_str(), keys.c_str(), vals[i].c_str());
for(size_t i = 0; i < vals.size(); i ++) retn += executeSql(sql.c_str());
{ }
sql.clear(); return retn;
string_format(sql, "insert into %s (%s) values %s", tableName.c_str(), keys.c_str(), vals[i].c_str()); }
retn += executeSql(sql.c_str()); bool select(const string& sql, RowsType& rows) {
} if(!executeSql(sql)) {
return retn; LogError("executeSql failed. [%s]", sql.c_str());
} return false;
bool select(const string& sql, RowsType& rows) }
{ MYSQL_RES * result = mysql_store_result(conn_);
if(!executeSql(sql)) if(!result) {
{ LogError("mysql_store_result failed.[%d]", mysql_error(conn_));
LogError("executeSql failed. [%s]", sql.c_str()); return false;
return false; }
} size_t num_fields = mysql_num_fields(result);
MYSQL_RES * result = mysql_store_result(conn_); MYSQL_ROW row;
if(!result) while((row = mysql_fetch_row(result))) {
{ vector<string> vec;
LogError("mysql_store_result failed.[%d]", mysql_error(conn_)); for(size_t i = 0; i < num_fields; i ++) {
return false; row[i] ? vec.push_back(row[i]) : vec.push_back("NULL");
} }
size_t num_fields = mysql_num_fields(result); rows.push_back(vec);
MYSQL_ROW row; }
while((row = mysql_fetch_row(result))) mysql_free_result(result);
{ return true;
vector<string> 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: private:
MYSQL * conn_; MYSQL * conn_;
}; };
} }
#endif #endif

View File

@ -6,17 +6,15 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
namespace Limonp namespace Limonp {
{ class NonCopyable {
class NonCopyable protected:
{ NonCopyable() {};
protected: ~NonCopyable() {};
NonCopyable(){}; private:
~NonCopyable(){}; NonCopyable(const NonCopyable& );
private: const NonCopyable& operator=(const NonCopyable& );
NonCopyable(const NonCopyable& ); };
const NonCopyable& operator=(const NonCopyable& );
};
} }
#endif #endif

View File

@ -9,131 +9,131 @@
#else #else
#include <tr1/unordered_map> #include <tr1/unordered_map>
#include <tr1/unordered_set> #include <tr1/unordered_set>
namespace std namespace std {
{ using std::tr1::unordered_map;
using std::tr1::unordered_map; using std::tr1::unordered_set;
using std::tr1::unordered_set;
} }
#endif #endif
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
#include <deque>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
namespace std namespace std {
{
template<typename T>
ostream& operator << (ostream& os, const vector<T>& vec)
{
if(vec.empty())
{
return os << "[]";
}
os<<"[\""<<vec[0];
for(size_t i = 1; i < vec.size(); i++)
{
os<<"\", \""<<vec[i];
}
os<<"\"]";
return os;
}
template<class T1, class T2>
ostream& operator << (ostream& os, const pair<T1, T2>& pr)
{
os << pr.first << ":" << pr.second ;
return os;
}
template<typename T>
template<class T> ostream& operator << (ostream& os, const vector<T>& v) {
string& operator << (string& str, const T& obj) if(v.empty()) {
{ return os << "[]";
stringstream ss; }
ss << obj; // call ostream& operator << (ostream& os, os<<"[\""<<v[0];
return str = ss.str(); for(size_t i = 1; i < v.size(); i++) {
} os<<"\", \""<<v[i];
}
template<class T1, class T2> os<<"\"]";
ostream& operator << (ostream& os, const map<T1, T2>& mp) return os;
{
if(mp.empty())
{
os<<"{}";
return os;
}
os<<'{';
typename map<T1, T2>::const_iterator it = mp.begin();
os<<*it;
it++;
while(it != mp.end())
{
os<<", "<<*it;
it++;
}
os<<'}';
return os;
}
template<class T1, class T2>
ostream& operator << (ostream& os, const std::unordered_map<T1, T2>& mp)
{
if(mp.empty())
{
return os << "{}";
}
os<<'{';
typename std::unordered_map<T1, T2>::const_iterator it = mp.begin();
os<<*it;
it++;
while(it != mp.end())
{
os<<", "<<*it++;
}
return os<<'}';
}
template<class T>
ostream& operator << (ostream& os, const set<T>& st)
{
if(st.empty())
{
os << "{}";
return os;
}
os<<'{';
typename set<T>::const_iterator it = st.begin();
os<<*it;
it++;
while(it != st.end())
{
os<<", "<<*it;
it++;
}
os<<'}';
return os;
}
template<class KeyType, class ContainType>
bool isIn(const ContainType& contain, const KeyType& key)
{
return contain.end() != contain.find(key);
}
template<class T>
basic_string<T> & operator << (basic_string<T> & s, ifstream & ifs)
{
return s.assign((istreambuf_iterator<T>(ifs)), istreambuf_iterator<T>());
}
template<class T>
ofstream & operator << (ofstream & ofs, const basic_string<T>& s)
{
ostreambuf_iterator<T> itr (ofs);
copy(s.begin(), s.end(), itr);
return ofs;
}
} }
template<typename T>
ostream& operator << (ostream& os, const deque<T>& dq) {
if(dq.empty()) {
return os << "[]";
}
os<<"[\""<<dq[0];
for(size_t i = 1; i < dq.size(); i++) {
os<<"\", \""<<dq[i];
}
os<<"\"]";
return os;
}
template<class T1, class T2>
ostream& operator << (ostream& os, const pair<T1, T2>& pr) {
os << pr.first << ":" << pr.second ;
return os;
}
template<class T>
string& operator << (string& str, const T& obj) {
stringstream ss;
ss << obj; // call ostream& operator << (ostream& os,
return str = ss.str();
}
template<class T1, class T2>
ostream& operator << (ostream& os, const map<T1, T2>& mp) {
if(mp.empty()) {
os<<"{}";
return os;
}
os<<'{';
typename map<T1, T2>::const_iterator it = mp.begin();
os<<*it;
it++;
while(it != mp.end()) {
os<<", "<<*it;
it++;
}
os<<'}';
return os;
}
template<class T1, class T2>
ostream& operator << (ostream& os, const std::unordered_map<T1, T2>& mp) {
if(mp.empty()) {
return os << "{}";
}
os<<'{';
typename std::unordered_map<T1, T2>::const_iterator it = mp.begin();
os<<*it;
it++;
while(it != mp.end()) {
os<<", "<<*it++;
}
return os<<'}';
}
template<class T>
ostream& operator << (ostream& os, const set<T>& st) {
if(st.empty()) {
os << "{}";
return os;
}
os<<'{';
typename set<T>::const_iterator it = st.begin();
os<<*it;
it++;
while(it != st.end()) {
os<<", "<<*it;
it++;
}
os<<'}';
return os;
}
template<class KeyType, class ContainType>
bool isIn(const ContainType& contain, const KeyType& key) {
return contain.end() != contain.find(key);
}
template<class T>
basic_string<T> & operator << (basic_string<T> & s, ifstream & ifs) {
return s.assign((istreambuf_iterator<T>(ifs)), istreambuf_iterator<T>());
}
template<class T>
ofstream & operator << (ofstream & ofs, const basic_string<T>& s) {
ostreambuf_iterator<T> itr (ofs);
copy(s.begin(), s.end(), itr);
return ofs;
}
} // namespace std
#endif #endif

View File

@ -23,327 +23,273 @@
#include <algorithm> #include <algorithm>
#include "StdExtension.hpp" #include "StdExtension.hpp"
namespace Limonp namespace Limonp {
{ using namespace std;
using namespace std; inline string string_format(const char* fmt, ...) {
inline string string_format(const char* fmt, ...) int size = 256;
{ std::string str;
int size = 256; va_list ap;
std::string str; while (1) {
va_list ap; str.resize(size);
while (1) { va_start(ap, fmt);
str.resize(size); int n = vsnprintf((char *)str.c_str(), size, fmt, ap);
va_start(ap, fmt); va_end(ap);
int n = vsnprintf((char *)str.c_str(), size, fmt, ap); if (n > -1 && n < size) {
va_end(ap); str.resize(n);
if (n > -1 && n < size) { return str;
str.resize(n);
return str;
}
if (n > -1)
size = n + 1;
else
size *= 2;
}
return str;
} }
if (n > -1)
size = n + 1;
else
size *= 2;
}
return str;
}
template<class T> template<class T>
void join(T begin, T end, string& res, const string& connector) void join(T begin, T end, string& res, const string& connector) {
{ if(begin == end) {
if(begin == end) return;
{ }
return; stringstream ss;
} ss<<*begin;
stringstream ss; begin++;
ss<<*begin; while(begin != end) {
begin++; ss << connector << *begin;
while(begin != end) begin ++;
{ }
ss << connector << *begin; res = ss.str();
begin ++; }
}
res = ss.str();
}
template<class T> template<class T>
string join(T begin, T end, const string& connector) string join(T begin, T end, const string& connector) {
{ string res;
string res; join(begin ,end, res, connector);
join(begin ,end, res, connector); return res;
return res; }
}
inline bool split(const string& src, vector<string>& res, const string& pattern, size_t offset = 0, size_t len = string::npos) inline bool split(const string& src, vector<string>& res, const string& pattern, size_t offset = 0, size_t len = string::npos) {
{ if(src.empty()) {
if(src.empty()) return false;
{ }
return false; res.clear();
}
res.clear();
size_t start = 0; size_t start = 0;
size_t end = 0; size_t end = 0;
size_t cnt = 0; size_t cnt = 0;
while(start < src.size() && res.size() < len) while(start < src.size() && res.size() < len) {
{ end = src.find_first_of(pattern, start);
end = src.find_first_of(pattern, start); if(string::npos == end) {
if(string::npos == end) if(cnt >= offset) {
{ res.push_back(src.substr(start));
if(cnt >= offset) }
{ return true;
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;
} }
//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) inline string& upper(string& str) {
{ transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper);
transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper); return str;
return str; }
}
inline string& lower(string& str) inline string& lower(string& str) {
{ transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower);
transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower); return str;
return str; }
}
inline std::string &ltrim(std::string &s) inline std::string &ltrim(std::string &s) {
{ s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); return s;
return s; }
}
inline std::string &rtrim(std::string &s) inline std::string &rtrim(std::string &s) {
{ s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end()); return s;
return s; }
}
inline std::string &trim(std::string &s) inline std::string &trim(std::string &s) {
{ return ltrim(rtrim(s));
return ltrim(rtrim(s)); }
}
inline std::string & ltrim(std::string & s, char x) 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<char>(), x))));
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::bind2nd(std::equal_to<char>(), x)))); return s;
return s; }
}
inline std::string & rtrim(std::string & s, char x) 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<char>(), x))).base(), s.end());
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::bind2nd(std::equal_to<char>(), x))).base(), s.end()); return s;
return s; }
}
inline std::string &trim(std::string &s, char x) inline std::string &trim(std::string &s, char x) {
{ return ltrim(rtrim(s, x), x);
return ltrim(rtrim(s, x), x); }
}
inline bool startsWith(const string& str, const string& prefix) inline bool startsWith(const string& str, const string& prefix) {
{ if(prefix.length() > str.length()) {
if(prefix.length() > str.length()) return false;
{ }
return false; return 0 == str.compare(0, prefix.length(), prefix);
} }
return 0 == str.compare(0, prefix.length(), prefix);
}
inline bool endsWith(const string& str, const string& suffix) inline bool endsWith(const string& str, const string& suffix) {
{ if(suffix.length() > str.length()) {
if(suffix.length() > str.length()) return false;
{ }
return false; return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix);
} }
return 0 == str.compare(str.length() - suffix.length(), suffix.length(), suffix);
}
inline bool isInStr(const string& str, char ch) inline bool isInStr(const string& str, char ch) {
{ return str.find(ch) != string::npos;
return str.find(ch) != string::npos; }
}
inline uint16_t twocharToUint16(char high, char low) inline uint16_t twocharToUint16(char high, char low) {
{ return (((uint16_t(high) & 0x00ff ) << 8) | (uint16_t(low) & 0x00ff));
return (((uint16_t(high) & 0x00ff ) << 8) | (uint16_t(low) & 0x00ff)); }
}
template <class Uint16Container> template <class Uint16Container>
bool utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) bool utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) {
{ if(!str) {
if(!str) return false;
{ }
return false; char ch1, ch2;
} uint16_t tmp;
char ch1, ch2; vec.clear();
uint16_t tmp; for(size_t i = 0; i < len;) {
vec.clear(); if(!(str[i] & 0x80)) { // 0xxxxxxx
for(size_t i = 0;i < len;) vec.push_back(str[i]);
{ i++;
if(!(str[i] & 0x80)) // 0xxxxxxx } else if ((uint8_t)str[i] <= 0xdf && i + 1 < len) { // 110xxxxxx
{ ch1 = (str[i] >> 2) & 0x07;
vec.push_back(str[i]); ch2 = (str[i+1] & 0x3f) | ((str[i] & 0x03) << 6 );
i++; tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff));
} vec.push_back(tmp);
else if ((uint8_t)str[i] <= 0xdf && i + 1 < len) // 110xxxxxx i += 2;
{ } else if((uint8_t)str[i] <= 0xef && i + 2 < len) {
ch1 = (str[i] >> 2) & 0x07; ch1 = ((uint8_t)str[i] << 4) | ((str[i+1] >> 2) & 0x0f );
ch2 = (str[i+1] & 0x3f) | ((str[i] & 0x03) << 6 ); ch2 = (((uint8_t)str[i+1]<<6) & 0xc0) | (str[i+2] & 0x3f);
tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff)); tmp = (((uint16_t(ch1) & 0x00ff ) << 8) | (uint16_t(ch2) & 0x00ff));
vec.push_back(tmp); vec.push_back(tmp);
i += 2; i += 3;
} } else {
else if((uint8_t)str[i] <= 0xef && i + 2 < len) return false;
{
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 <class Uint16Container>
bool utf8ToUnicode(const string& str, Uint16Container& vec)
{
return utf8ToUnicode(str.c_str(), str.size(), vec);
} }
}
return true;
}
template <class Uint16Container>
bool utf8ToUnicode(const string& str, Uint16Container& vec) {
return utf8ToUnicode(str.c_str(), str.size(), vec);
}
template <class Uint16ContainerConIter> template <class Uint16ContainerConIter>
bool unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) bool unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
{ if(begin >= end) {
if(begin >= end) return false;
{ }
return false; res.clear();
} uint16_t ui;
res.clear(); while(begin != end) {
uint16_t ui; ui = *begin;
while(begin != end) if(ui <= 0x7f) {
{ res += char(ui);
ui = *begin; } else if(ui <= 0x7ff) {
if(ui <= 0x7f) res += char(((ui>>6) & 0x1f) | 0xc0);
{ res += char((ui & 0x3f) | 0x80);
res += char(ui); } else {
} res += char(((ui >> 12) & 0x0f )| 0xe0);
else if(ui <= 0x7ff) res += char(((ui>>6) & 0x3f )| 0x80 );
{ res += char((ui & 0x3f) | 0x80);
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;
} }
begin ++;
}
return true;
}
template <class Uint16Container> template <class Uint16Container>
bool gbkTrans(const char* const str, size_t len, Uint16Container& vec) bool gbkTrans(const char* const str, size_t len, Uint16Container& vec) {
{ vec.clear();
vec.clear(); if(!str) {
if(!str) return false;
{ }
return false; size_t i = 0;
} while(i < len) {
size_t i = 0; if(0 == (str[i] & 0x80)) {
while(i < len) vec.push_back(uint16_t(str[i]));
{ i++;
if(0 == (str[i] & 0x80)) } else {
{ if(i + 1 < len) { //&& (str[i+1] & 0x80))
vec.push_back(uint16_t(str[i])); uint16_t tmp = (((uint16_t(str[i]) & 0x00ff ) << 8) | (uint16_t(str[i+1]) & 0x00ff));
i++; vec.push_back(tmp);
} i += 2;
else } else {
{ return false;
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;
} }
}
return true;
}
template <class Uint16Container> template <class Uint16Container>
bool gbkTrans(const string& str, Uint16Container& vec) bool gbkTrans(const string& str, Uint16Container& vec) {
{ return gbkTrans(str.c_str(), str.size(), vec);
return gbkTrans(str.c_str(), str.size(), vec); }
}
template <class Uint16ContainerConIter> template <class Uint16ContainerConIter>
bool gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) bool gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
{ if(begin >= end) {
if(begin >= end) return false;
{ }
return false; res.clear();
} //pair<char, char> pa;
res.clear(); char first, second;
//pair<char, char> pa; while(begin != end) {
char first, second; //pa = uint16ToChar2(*begin);
while(begin != end) first = ((*begin)>>8) & 0x00ff;
{ second = (*begin) & 0x00ff;
//pa = uint16ToChar2(*begin); if(first & 0x80) {
first = ((*begin)>>8) & 0x00ff; res += first;
second = (*begin) & 0x00ff; res += second;
if(first & 0x80) } else {
{ res += second;
res += first;
res += second;
}
else
{
res += second;
}
begin++;
}
return true;
} }
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;
}
/*
* 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);
}
} }
#endif #endif

View File

@ -4,47 +4,39 @@
#include "HandyMacro.hpp" #include "HandyMacro.hpp"
#include "NonCopyable.hpp" #include "NonCopyable.hpp"
namespace Limonp namespace Limonp {
{ class IThread: NonCopyable {
class IThread: NonCopyable private:
{ pthread_t thread_;
private: bool isStarted;
pthread_t thread_; bool isJoined;
bool isStarted; public:
bool isJoined; IThread(): isStarted(false), isJoined(false) {
public: }
IThread(): isStarted(false), isJoined(false) virtual ~IThread() {
{ if(isStarted && !isJoined) {
} LIMONP_CHECK(!pthread_detach(thread_));
virtual ~IThread() }
{ };
if(isStarted && !isJoined) public:
{ virtual void run() = 0;
LIMONP_CHECK(!pthread_detach(thread_)); void start() {
} LIMONP_CHECK(!isStarted);
}; LIMONP_CHECK(!pthread_create(&thread_, NULL, worker_, this));
public: isStarted = true;
virtual void run() = 0; }
void start() void join() {
{ LIMONP_CHECK(!isJoined);
assert(!isStarted); LIMONP_CHECK(!pthread_join(thread_, NULL));
LIMONP_CHECK(!pthread_create(&thread_, NULL, worker_, this)); isJoined = true;
isStarted = true; }
} private:
void join() static void * worker_(void * data) {
{ IThread * ptr = (IThread* ) data;
assert(!isJoined); ptr->run();
LIMONP_CHECK(!pthread_join(thread_, NULL)); return NULL;
isJoined = true; }
} };
private:
static void * worker_(void * data)
{
IThread * ptr = (IThread* ) data;
ptr->run();
return NULL;
}
};
} }
#endif #endif

View File

@ -4,102 +4,87 @@
#include "Thread.hpp" #include "Thread.hpp"
#include "BlockingQueue.hpp" #include "BlockingQueue.hpp"
namespace Limonp namespace Limonp {
{ class ITask {
class ITask public:
{ virtual void run() = 0;
public: virtual ~ITask() {}
virtual void run() = 0; };
virtual ~ITask() {}
};
template <class TaskType, class ArgType> template <class TaskType, class ArgType>
ITask* CreateTask(ArgType arg) ITask* CreateTask(ArgType arg) {
{ return new TaskType(arg);
return new TaskType(arg); }
} template <class TaskType, class ArgType0, class ArgType1>
template <class TaskType, class ArgType0, class ArgType1> ITask* CreateTask(ArgType0 arg0, ArgType1 arg1) {
ITask* CreateTask(ArgType0 arg0, ArgType1 arg1) return new TaskType(arg0, arg1);
{ }
return new TaskType(arg0, arg1); template <class TaskType, class ArgType0, class ArgType1, class ArgType2>
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<IThread*> threads_;
BoundedBlockingQueue<ITask*> 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; public:
class ThreadPool: NonCopyable void start() {
{ for(size_t i = 0; i < threads_.size(); i++) {
private: threads_[i]->start();
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<IThread*> threads_;
BoundedBlockingQueue<ITask*> 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 add(ITask* task) {
void start() assert(task);
{ queue_.push(task);
for(size_t i = 0; i < threads_.size(); i++) }
{ };
threads_[i]->start();
}
}
void add(ITask* task)
{
assert(task);
queue_.push(task);
}
};
} }
#endif #endif

View File

@ -5,6 +5,7 @@
#include "../src/HMMSegment.hpp" #include "../src/HMMSegment.hpp"
#include "../src/MixSegment.hpp" #include "../src/MixSegment.hpp"
#include "../src/KeywordExtractor.hpp" #include "../src/KeywordExtractor.hpp"
#include "../src/Limonp/Colors.hpp"
using namespace CppJieba; using namespace CppJieba;
@ -24,8 +25,9 @@ void cut(size_t times = 50)
res.clear(); res.clear();
seg.cut(doc, res); seg.cut(doc, res);
} }
printf("\n");
long endTime = clock(); 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) void extract(size_t times = 400)
@ -44,8 +46,9 @@ void extract(size_t times = 400)
words.clear(); words.clear();
extractor.extract(doc, words, 5); extractor.extract(doc, words, 5);
} }
printf("\n");
long endTime = clock(); 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) int main(int argc, char ** argv)