update limonp to version v0.4.0

This commit is contained in:
yanyiwu 2015-12-12 19:42:30 +08:00
parent c38015d0ee
commit 194550823f
21 changed files with 488 additions and 623 deletions

View File

@ -11,14 +11,15 @@
#include "StringUtil.hpp"
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], "-")) {
if(StartsWith(argv[i], "-")) {
if(i + 1 < argc && !StartsWith(argv[i + 1], "-")) {
mpss_[argv[i]] = argv[i+1];
i++;
} else {
@ -29,8 +30,9 @@ class ArgvContext {
}
}
}
~ArgvContext() {};
public:
~ArgvContext() {
}
friend ostream& operator << (ostream& os, const ArgvContext& args);
string operator [](size_t i) const {
if(i < args_.size()) {
@ -45,23 +47,24 @@ class ArgvContext {
}
return "";
}
public:
bool hasKey(const string& key) const {
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_;
};
}; // class ArgvContext
inline ostream& operator << (ostream& os, const ArgvContext& args) {
return os<<args.args_<<args.mpss_<<args.sset_;
}
}
} // namespace limonp
#endif

View File

@ -1,12 +1,7 @@
/*
https://github.com/chenshuo/muduo/blob/master/muduo/base/BlockingQueue.h
*/
#ifndef LIMONP_BLOCKINGQUEUE_HPP
#define LIMONP_BLOCKINGQUEUE_HPP
#include <queue>
#include "BoundedQueue.hpp"
#include "Condition.hpp"
namespace limonp {
@ -17,17 +12,17 @@ class BlockingQueue: NonCopyable {
: mutex_(), notEmpty_(mutex_), queue_() {
}
void push(const T& x) {
void Push(const T& x) {
MutexLockGuard lock(mutex_);
queue_.push(x);
notEmpty_.notify(); // wait morphing saves us
notEmpty_.Notify(); // Wait morphing saves us
}
T pop() {
T Pop() {
MutexLockGuard lock(mutex_);
// always use a while-loop, due to spurious wakeup
while (queue_.empty()) {
notEmpty_.wait();
notEmpty_.Wait();
}
assert(!queue_.empty());
T front(queue_.front());
@ -35,77 +30,20 @@ class BlockingQueue: NonCopyable {
return front;
}
size_t size() const {
size_t Size() const {
MutexLockGuard lock(mutex_);
return queue_.size();
}
bool empty() const {
return size() == 0;
bool Empty() const {
return Size() == 0;
}
private:
mutable MutexLock mutex_;
Condition notEmpty_;
std::queue<T> queue_;
};
}; // class BlockingQueue
template<typename T>
class BoundedBlockingQueue : NonCopyable {
public:
explicit BoundedBlockingQueue(size_t maxSize)
: mutex_(),
notEmpty_(mutex_),
notFull_(mutex_),
queue_(maxSize) {
}
} // namespace limonp
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;
}
bool empty() const {
MutexLockGuard lock(mutex_);
return queue_.empty();
}
bool full() const {
MutexLockGuard lock(mutex_);
return queue_.full();
}
size_t size() const {
MutexLockGuard lock(mutex_);
return queue_.size();
}
size_t capacity() const {
return queue_.capacity();
}
private:
mutable MutexLock mutex_;
Condition notEmpty_;
Condition notFull_;
BoundedQueue<T> queue_;
};
}
#endif
#endif // LIMONP_BLOCKINGQUEUE_HPP

View File

@ -0,0 +1,67 @@
#ifndef LIMONP_BOUNDED_BLOCKING_QUEUE_HPP
#define LIMONP_BOUNDED_BLOCKING_QUEUE_HPP
#include "BoundedQueue.hpp"
namespace limonp {
template<typename T>
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();
}
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 Full() const {
MutexLockGuard lock(mutex_);
return queue_.Full();
}
size_t size() const {
MutexLockGuard lock(mutex_);
return queue_.size();
}
size_t capacity() const {
return queue_.capacity();
}
private:
mutable MutexLock mutex_;
Condition notEmpty_;
Condition notFull_;
BoundedQueue<T> queue_;
}; // class BoundedBlockingQueue
} // namespace limonp
#endif // LIMONP_BOUNDED_BLOCKING_QUEUE_HPP

View File

@ -9,55 +9,57 @@ namespace limonp {
using namespace std;
template<class T>
class BoundedQueue {
private:
size_t head_;
size_t tail_;
size_t size_;
const size_t capacity_;
vector<T> circular__buffer;
public:
explicit BoundedQueue(size_t capacity): capacity_(capacity), circular__buffer(capacity) {
explicit BoundedQueue(size_t capacity): capacity_(capacity), circular_buffer_(capacity) {
head_ = 0;
tail_ = 0;
size_ = 0;
assert(capacity_);
}
~BoundedQueue() {}
public:
void clear() {
~BoundedQueue() {
}
void Clear() {
head_ = 0;
tail_ = 0;
size_ = 0;
}
bool empty() const {
bool Empty() const {
return !size_;
}
bool full() const {
bool Full() const {
return capacity_ == size_;
}
size_t size() const {
size_t Size() const {
return size_;
}
size_t capacity() const {
size_t Capacity() const {
return capacity_;
}
void push(const T& t) {
assert(!full());
circular__buffer[tail_] = t;
void Push(const T& t) {
assert(!Full());
circular_buffer_[tail_] = t;
tail_ = (tail_ + 1) % capacity_;
size_ ++;
}
T pop() {
assert(!empty());
T Pop() {
assert(!Empty());
size_t oldPos = head_;
head_ = (head_ + 1) % capacity_;
size_ --;
return circular__buffer[oldPos];
return circular_buffer_[oldPos];
}
};
}
private:
size_t head_;
size_t tail_;
size_t size_;
const size_t capacity_;
vector<T> circular_buffer_;
}; // class BoundedQueue
} // namespace limonp
#endif

View File

@ -1,82 +0,0 @@
#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;
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;
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 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;
}
return code;
}
inline float shortBitsToFloat(short s) {
/*
* 31001 0(13)
*/
int sign = ((int) (s & sign_16)) << 16;
int exponent = ((int) (s & exponent_16)) << 13;
// 指数符号位为0234位补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

32
src/limonp/Closure.hpp Normal file
View File

@ -0,0 +1,32 @@
#ifndef LIMONP_CLOSURE_HPP
#define LIMONP_CLOSURE_HPP
namespace limonp {
class ITask {
public:
virtual ~ITask() {
}
virtual void Run() = 0;
}; // class ITask
template <class TaskType>
ITask* CreateTask() {
return new TaskType();
}
template <class TaskType, class ArgType>
ITask* CreateTask(ArgType arg) {
return new TaskType(arg);
}
template <class TaskType, class ArgType0, class ArgType1>
ITask* CreateTask(ArgType0 arg0, ArgType1 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);
}
} // namespace limonp
#endif // LIMONP_CLOSURE_HPP

View File

@ -5,18 +5,19 @@
#include <stdarg.h>
namespace limonp {
using std::string;
enum COLOR {
enum Color {
BLACK = 30,
RED,
GREEN,
YELLOW,
BLUE,
PURPLE
};
}; // enum Color
static void ColorPrintln(enum COLOR color, const char * fmt, ...) {
static void ColorPrintln(enum Color color, const char * fmt, ...) {
va_list ap;
printf("\033[0;%dm", color);
va_start(ap, fmt);
@ -25,12 +26,6 @@ static void ColorPrintln(enum COLOR color, const char * fmt, ...) {
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
#endif // LIMONP_COLOR_PRINT_HPP

View File

@ -1,41 +1,38 @@
/*
* https://github.com/chenshuo/muduo/blob/master/muduo/base/Condition.h
*/
#ifndef LIMONP_CONDITION_HPP
#define LIMONP_CONDITION_HPP
#include "MutexLock.hpp"
namespace limonp {
class Condition : NonCopyable {
public:
explicit Condition(MutexLock& mutex)
: mutex_(mutex) {
LIMONP_CHECK(!pthread_cond_init(&pcond_, NULL));
CHECK(!pthread_cond_init(&pcond_, NULL));
}
~Condition() {
LIMONP_CHECK(!pthread_cond_destroy(&pcond_));
CHECK(!pthread_cond_destroy(&pcond_));
}
void wait() {
LIMONP_CHECK(!pthread_cond_wait(&pcond_, mutex_.getPthreadMutex()));
void Wait() {
CHECK(!pthread_cond_wait(&pcond_, mutex_.GetPthreadMutex()));
}
void notify() {
LIMONP_CHECK(!pthread_cond_signal(&pcond_));
void Notify() {
CHECK(!pthread_cond_signal(&pcond_));
}
void notifyAll() {
LIMONP_CHECK(!pthread_cond_broadcast(&pcond_));
void NotifyAll() {
CHECK(!pthread_cond_broadcast(&pcond_));
}
private:
MutexLock& mutex_;
pthread_cond_t pcond_;
};
}; // class Condition
}
} // namespace limonp
#endif
#endif // LIMONP_CONDITION_HPP

View File

@ -5,7 +5,6 @@
#ifndef LIMONP_CONFIG_H
#define LIMONP_CONFIG_H
#include <map>
#include <fstream>
#include <iostream>
@ -13,58 +12,28 @@
#include "StringUtil.hpp"
namespace limonp {
using namespace std;
class Config {
public:
explicit Config(const string& filePath) {
loadFile_(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<string> vecBuf;
size_t lineno = 0;
while(getline(ifs, line)) {
lineno ++;
trim(line);
if(line.empty() || startsWith(line, "#")) {
continue;
}
vecBuf.clear();
split(line, vecBuf, "=");
if(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:
string get(const string& key, const string& defaultvalue) const {
string Get(const string& key, const string& defaultvalue) const {
map<string, string>::const_iterator it = map_.find(key);
if(map_.end() != it) {
return it->second;
}
return defaultvalue;
}
int get(const string& key, int defaultvalue) const {
string str = get(key, "");
int Get(const string& key, int defaultvalue) const {
string str = Get(key, "");
if("" == str) {
return defaultvalue;
}
@ -80,21 +49,55 @@ class Config {
}
return NULL;
}
public:
string getConfigInfo() const {
string GetConfigInfo() const {
string res;
res << *this;
return res;
}
private:
map<string, string> map_;
private:
void LoadFile(const string& filePath) {
ifstream ifs(filePath.c_str());
assert(ifs);
string line;
vector<string> vecBuf;
size_t lineno = 0;
while(getline(ifs, line)) {
lineno ++;
Trim(line);
if(line.empty() || StartsWith(line, "#")) {
continue;
}
vecBuf.clear();
Split(line, vecBuf, "=");
if(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();
}
friend ostream& operator << (ostream& os, const Config& config);
};
map<string, string> map_;
}; // class Config
inline ostream& operator << (ostream& os, const Config& config) {
return os << config.map_;
}
}
#endif
} // namespace limonp
#endif // LIMONP_CONFIG_H

74
src/limonp/FileLock.hpp Normal file
View File

@ -0,0 +1,74 @@
#ifndef LIMONP_FILELOCK_HPP
#define LIMONP_FILELOCK_HPP
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string>
#include <string.h>
#include <assert.h>
namespace limonp {
using std::string;
class FileLock {
public:
FileLock() : fd_(-1), ok_(true) {
}
~FileLock() {
if(fd_ > 0) {
Close();
}
}
void Open(const string& fname) {
assert(fd_ == -1);
fd_ = open(fname.c_str(), O_RDWR | O_CREAT, 0644);
if(fd_ < 0) {
ok_ = false;
err_ = strerror(errno);
}
}
void Close() {
::close(fd_);
}
void Lock() {
if(LockOrUnlock(fd_, true) < 0) {
ok_ = false;
err_ = strerror(errno);
}
}
void UnLock() {
if(LockOrUnlock(fd_, false) < 0) {
ok_ = false;
err_ = strerror(errno);
}
}
bool Ok() const {
return ok_;
}
string Error() const {
return err_;
}
private:
static int LockOrUnlock(int fd, bool lock) {
errno = 0;
struct flock f;
memset(&f, 0, sizeof(f));
f.l_type = (lock ? F_WRLCK : F_UNLCK);
f.l_whence = SEEK_SET;
f.l_start = 0;
f.l_len = 0; // Lock/unlock entire file
return fcntl(fd, F_SETLK, &f);
}
int fd_;
bool ok_;
string err_;
}; // class FileLock
}// namespace limonp
#endif // LIMONP_FILELOCK_HPP

View File

@ -1,31 +0,0 @@
#ifndef LIMONP_HANDY_MACRO_HPP
#define LIMONP_HANDY_MACRO_HPP
#include <cstdio>
#include <cstdlib>
#define LIMONP_CHECK(exp) \
if(!(exp)){fprintf(stderr, "File:%s, Line:%d Exp:[" #exp "] is true, abort.\n", __FILE__, __LINE__); abort();}
#define print(x) cout << x << endl
/*
#define XX_GET_SET(varType, varName, funName)\
private: varType varName;\
public: inline varType get##funName(void) const {return varName;}\
public: inline void set##funName(varType var) {varName = var;}
#define XX_GET(varType, varName, funName)\
private: varType varName;\
public: inline varType get##funName(void) const {return varName;}
#define XX_SET(varType, varName, funName)\
private: varType varName;\
public: inline void set##funName(varType var) {varName = var;}
#define XX_GET_SET_BY_REF(varType, varName, funName)\
private: varType varName;\
public: inline const varType& get##funName(void) const {return varName;}\
public: inline void set##funName(const varType& var){varName = var;}
*/
#endif

View File

@ -1,25 +0,0 @@
#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_();
};
};
}
#endif

View File

@ -1,68 +0,0 @@
/************************************
* file enc : utf8
* author : wuyanyi09@gmail.com
************************************/
#ifndef LIMONP_LOGGER_H
#define LIMONP_LOGGER_H
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <stdio.h>
#include <cstdlib>
#include <stdarg.h>
#include <time.h>
#include <cassert>
#define LogDebug(fmt, ...) limonp::Logger::LoggingF(limonp::LL_DEBUG, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
#define LogInfo(fmt, ...) limonp::Logger::LoggingF(limonp::LL_INFO, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
#define LogWarn(fmt, ...) limonp::Logger::LoggingF(limonp::LL_WARN, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
#define LogError(fmt, ...) limonp::Logger::LoggingF(limonp::LL_ERROR, __FILE__, __LINE__, fmt, ## __VA_ARGS__)
#define LogFatal(fmt, ...) {limonp::Logger::LoggingF(limonp::LL_FATAL, __FILE__, __LINE__, fmt, ## __VA_ARGS__); abort();}
namespace limonp {
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};
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_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
class Logger {
public:
static void Logging(size_t level, const string& msg, const char* fileName, int lineno) {
assert(level <= LL_FATAL);
char buf[CSTR_BUFFER_SIZE];
time_t timeNow;
time(&timeNow);
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, ...) {
#ifdef LOGGER_LEVEL
if(level < LOGGER_LEVEL) return;
#endif
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

75
src/limonp/Logging.hpp Normal file
View File

@ -0,0 +1,75 @@
#ifndef LIMONP_LOGGING_HPP
#define LIMONP_LOGGING_HPP
#include <sstream>
#include <iostream>
#include <cassert>
#include <cstdlib>
#ifdef LOG
#error "LOG has been defined already"
#endif // LOG
#ifdef CHECK
#error "CHECK has been defined already"
#endif // CHECK
#define LOG(level) limonp::Logger(limonp::level, __FILE__, __LINE__).Stream()
#define CHECK(exp) {if(!(exp)) LOG(FATAL) << #exp << " is false, abort."; }
namespace limonp {
enum {
DEBUG = 0,
INFO = 1,
WARNING = 2,
ERROR = 3,
FATAL = 4,
}; // enum
static const char * LOG_LEVEL_ARRAY[] = {"DEBUG","INFO","WARN","ERROR","FATAL"};
static const char * LOG_TIME_FORMAT = "%Y-%m-%d %H:%M:%S";
class Logger {
public:
Logger(size_t level, const char* filename, int lineno)
: level_(level) {
#ifdef LOGGING_LEVEL
if (level_ < LOGGING_LEVEL) {
return;
}
#endif
assert(level_ <= sizeof(LOG_LEVEL_ARRAY)/sizeof(*LOG_LEVEL_ARRAY));
char buf[32];
time_t now;
time(&now);
strftime(buf, sizeof(buf), LOG_TIME_FORMAT, localtime(&now));
stream_ << buf
<< " " << filename
<< ":" << lineno
<< " " << LOG_LEVEL_ARRAY[level_]
<< " ";
}
~Logger() {
#ifdef LOGGING_LEVEL
if (level_ < LOGGING_LEVEL) {
return;
}
#endif
std::cerr << stream_.str() << std::endl;
if (level_ == FATAL) {
abort();
}
}
std::ostream& Stream() {
return stream_;
}
private:
std::ostringstream stream_;
size_t level_;
}; // class Logger
} // namespace limonp
#endif // LIMONP_LOGGING_HPP

View File

@ -3,45 +3,49 @@
#include <pthread.h>
#include "NonCopyable.hpp"
#include "HandyMacro.hpp"
#include "Logging.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));
CHECK(!pthread_mutex_init(&mutex_, NULL));
}
~MutexLock() {
LIMONP_CHECK(!pthread_mutex_destroy(&mutex_));
CHECK(!pthread_mutex_destroy(&mutex_));
}
pthread_mutex_t* GetPthreadMutex() {
return &mutex_;
}
private:
void lock() {
LIMONP_CHECK(!pthread_mutex_lock(&mutex_));
void Lock() {
CHECK(!pthread_mutex_lock(&mutex_));
}
void unlock() {
LIMONP_CHECK(!pthread_mutex_unlock(&mutex_));
void Unlock() {
CHECK(!pthread_mutex_unlock(&mutex_));
}
friend class MutexLockGuard;
};
pthread_mutex_t mutex_;
}; // class MutexLock
class MutexLockGuard: NonCopyable {
public:
explicit MutexLockGuard(MutexLock & mutex)
: mutex_(mutex) {
mutex_.lock();
mutex_.Lock();
}
~MutexLockGuard() {
mutex_.unlock();
mutex_.Unlock();
}
private:
MutexLock & mutex_;
};
#define MutexLockGuard(x) assert(false);
}
}; // class MutexLockGuard
#endif
#define MutexLockGuard(x) CHECK(false);
} // namespace limonp
#endif // LIMONP_MUTEX_LOCK_HPP

View File

@ -1,106 +0,0 @@
#ifndef LIMONP_MYSQLCLIENT_H
#define LIMONP_MYSQLCLIENT_H
#include <mysql.h>
#include <iostream>
#include <vector>
#include <string>
#include "Logger.hpp"
#include "InitOnOff.hpp"
#include "StringUtil.hpp"
namespace limonp {
using namespace std;
class MysqlClient: public InitOnOff {
public:
typedef vector< vector<string> > 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<<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) {
LogError("mysql_real_connect failed. %s", mysql_error(conn_));
mysql_close(conn_);
conn_ = NULL;
return false;
}
if(mysql_set_character_set(conn_, charset_.c_str())) {
LogError("mysql_set_character_set [%s] failed.", charset_.c_str());
return false;
}
//set reconenct
char value = 1;
mysql_options(conn_, MYSQL_OPT_RECONNECT, &value);
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<string>& vals) {
size_t retn = 0;
for(size_t i = 0; i < vals.size(); i ++) {
string sql = string_format("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<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:
MYSQL * conn_;
};
}
#endif

View File

@ -3,18 +3,19 @@
#ifndef LIMONP_NONCOPYABLE_H
#define LIMONP_NONCOPYABLE_H
#include <iostream>
#include <string>
namespace limonp {
class NonCopyable {
protected:
NonCopyable() {};
~NonCopyable() {};
NonCopyable() {
}
~NonCopyable() {
}
private:
NonCopyable(const NonCopyable& );
const NonCopyable& operator=(const NonCopyable& );
};
}
}; // class NonCopyable
#endif
} // namespace limonp
#endif // LIMONP_NONCOPYABLE_H

View File

@ -29,6 +29,7 @@ using std::tr1::unordered_set;
#include <fstream>
#include <sstream>
#define print(x) std::cout << x << std::endl
namespace std {
@ -124,7 +125,7 @@ ostream& operator << (ostream& os, const set<T>& st) {
}
template<class KeyType, class ContainType>
bool isIn(const ContainType& contain, const KeyType& key) {
bool IsIn(const ContainType& contain, const KeyType& key) {
return contain.end() != contain.find(key);
}

View File

@ -25,7 +25,7 @@
namespace limonp {
using namespace std;
inline string string_format(const char* fmt, ...) {
inline string StringFormat(const char* fmt, ...) {
int size = 256;
std::string str;
va_list ap;
@ -47,7 +47,7 @@ inline string string_format(const char* fmt, ...) {
}
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) {
return;
}
@ -62,101 +62,101 @@ void join(T begin, T end, string& res, const string& connector) {
}
template<class T>
string join(T begin, T end, const string& connector) {
string Join(T begin, T end, const string& connector) {
string res;
join(begin ,end, res, connector);
Join(begin ,end, res, connector);
return res;
}
inline string& upper(string& str) {
inline string& Upper(string& str) {
transform(str.begin(), str.end(), str.begin(), (int (*)(int))toupper);
return str;
}
inline string& lower(string& str) {
inline string& Lower(string& str) {
transform(str.begin(), str.end(), str.begin(), (int (*)(int))tolower);
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))));
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());
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) {
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))));
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());
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 void split(const string& src, vector<string>& res, const string& pattern, size_t maxsplit = string::npos) {
inline void Split(const string& src, vector<string>& res, const string& pattern, size_t maxsplit = string::npos) {
res.clear();
size_t start = 0;
size_t Start = 0;
size_t end = 0;
string sub;
while(start < src.size()) {
end = src.find_first_of(pattern, start);
while(Start < src.size()) {
end = src.find_first_of(pattern, Start);
if(string::npos == end || res.size() >= maxsplit) {
sub = src.substr(start);
trim(sub);
sub = src.substr(Start);
Trim(sub);
res.push_back(sub);
return;
}
sub = src.substr(start, end - start);
trim(sub);
sub = src.substr(Start, end - Start);
Trim(sub);
res.push_back(sub);
start = end + 1;
Start = end + 1;
}
return;
}
inline vector<string> split(const string& src, const string& pattern, size_t maxsplit = string::npos) {
inline vector<string> Split(const string& src, const string& pattern, size_t maxsplit = string::npos) {
vector<string> res;
split(src, res, pattern, maxsplit);
Split(src, res, pattern, maxsplit);
return res;
}
inline bool startsWith(const string& str, const string& 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) {
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) {
inline bool IsInStr(const string& str, char ch) {
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));
}
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) {
return false;
}
@ -186,12 +186,12 @@ bool utf8ToUnicode(const char * const str, size_t len, Uint16Container& vec) {
return true;
}
template <class Uint16Container>
bool utf8ToUnicode(const string& str, Uint16Container& vec) {
return utf8ToUnicode(str.c_str(), str.size(), vec);
bool Utf8ToUnicode(const string& str, Uint16Container& vec) {
return Utf8ToUnicode(str.c_str(), str.size(), vec);
}
template <class Uint16ContainerConIter>
void unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
void UnicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
res.clear();
uint16_t ui;
while(begin != end) {
@ -212,7 +212,7 @@ void unicodeToUtf8(Uint16ContainerConIter begin, Uint16ContainerConIter end, str
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();
if(!str) {
return true;
@ -236,12 +236,12 @@ bool gbkTrans(const char* const str, size_t len, Uint16Container& vec) {
}
template <class Uint16Container>
bool gbkTrans(const string& str, Uint16Container& vec) {
return gbkTrans(str.c_str(), str.size(), vec);
bool GBKTrans(const string& str, Uint16Container& vec) {
return GBKTrans(str.c_str(), str.size(), vec);
}
template <class Uint16ContainerConIter>
void gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
void GBKTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string& res) {
res.clear();
//pair<char, char> pa;
char first, second;
@ -262,7 +262,7 @@ void gbkTrans(Uint16ContainerConIter begin, Uint16ContainerConIter end, string&
/*
* format example: "%Y-%m-%d %H:%M:%S"
*/
inline void getTime(const string& format, string& timeStr) {
inline void GetTime(const string& format, string& timeStr) {
time_t timeNow;
time(&timeNow);
timeStr.resize(64);
@ -270,8 +270,8 @@ inline void getTime(const string& format, string& timeStr) {
timeStr.resize(len);
}
inline string pathJoin(const string& path1, const string& path2) {
if(endsWith(path1, "/")) {
inline string PathJoin(const string& path1, const string& path2) {
if(EndsWith(path1, "/")) {
return path1 + path2;
}
return path1 + "/" + path2;

View File

@ -1,42 +1,44 @@
#ifndef LIMONP_THREAD_HPP
#define LIMONP_THREAD_HPP
#include "HandyMacro.hpp"
#include "Logging.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_));
CHECK(!pthread_detach(thread_));
}
};
public:
virtual void run() = 0;
void start() {
LIMONP_CHECK(!isStarted);
LIMONP_CHECK(!pthread_create(&thread_, NULL, worker_, this));
virtual void Run() = 0;
void Start() {
CHECK(!isStarted);
CHECK(!pthread_create(&thread_, NULL, Worker, this));
isStarted = true;
}
void join() {
LIMONP_CHECK(!isJoined);
LIMONP_CHECK(!pthread_join(thread_, NULL));
void Join() {
CHECK(!isJoined);
CHECK(!pthread_join(thread_, NULL));
isJoined = true;
}
private:
static void * worker_(void * data) {
static void * Worker(void * data) {
IThread * ptr = (IThread* ) data;
ptr->run();
ptr->Run();
return NULL;
}
};
}
#endif
pthread_t thread_;
bool isStarted;
bool isJoined;
}; // class IThread
} // namespace limonp
#endif // LIMONP_THREAD_HPP

View File

@ -3,52 +3,32 @@
#include "Thread.hpp"
#include "BlockingQueue.hpp"
#include "BoundedBlockingQueue.hpp"
#include "Closure.hpp"
namespace limonp {
class ITask {
public:
virtual void run() = 0;
virtual ~ITask() {}
};
template <class TaskType>
ITask* CreateTask() {
return new TaskType();
}
template <class TaskType, class ArgType>
ITask* CreateTask(ArgType arg) {
return new TaskType(arg);
}
template <class TaskType, class ArgType0, class ArgType1>
ITask* CreateTask(ArgType0 arg0, ArgType1 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);
}
using namespace std;
//class ThreadPool;
class ThreadPool: NonCopyable {
private:
public:
class Worker: public IThread {
private:
ThreadPool * ptThreadPool_;
public:
Worker(ThreadPool* pool): ptThreadPool_(pool) {
assert(ptThreadPool_);
}
virtual ~Worker() {
}
public:
virtual void run() {
virtual void Run() {
while(true) {
ITask * task = ptThreadPool_->queue_.pop();
ITask * task = ptThreadPool_->queue_.Pop();
if(task == NULL) {
break;
}
try {
task->run();
task->Run();
} catch(std::exception& e) {
cerr << "file:" << __FILE__
<< ", line:" << __LINE__
@ -61,16 +41,13 @@ class ThreadPool: NonCopyable {
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_)
ThreadPool * ptThreadPool_;
}; // class Worker
ThreadPool(size_t threadNum, size_t queueMaxSize)
: threads_(threadNum),
queue_(queueMaxSize) {
assert(threadNum);
assert(queueMaxSize);
for(size_t i = 0; i < threads_.size(); i ++) {
@ -79,26 +56,32 @@ class ThreadPool: NonCopyable {
}
~ThreadPool() {
for(size_t i = 0; i < threads_.size(); i ++) {
queue_.push(NULL);
queue_.Push(NULL);
}
for(size_t i = 0; i < threads_.size(); i ++) {
threads_[i]->join();
threads_[i]->Join();
delete threads_[i];
}
}
public:
void start() {
void Start() {
for(size_t i = 0; i < threads_.size(); i++) {
threads_[i]->start();
threads_[i]->Start();
}
}
void add(ITask* task) {
void Add(ITask* task) {
assert(task);
queue_.push(task);
queue_.Push(task);
}
};
}
#endif
private:
friend class Worker;
vector<IThread*> threads_;
BoundedBlockingQueue<ITask*> queue_;
}; // class ThreadPool
} // namespace limonp
#endif // LIMONP_THREAD_POOL_HPP