acl/lib_acl_cpp/include/acl_cpp/stdlib/dbuf_pool.hpp

595 lines
15 KiB
C++
Raw Normal View History

#pragma once
2017-06-02 14:47:24 +08:00
#include "../acl_cpp_define.hpp"
#include "noncopyable.hpp"
2015-11-09 22:11:21 +08:00
#include <vector>
struct ACL_DBUF_POOL;
namespace acl
{
2015-01-26 19:58:02 +08:00
/**
*
*
* lib_acl ACL_DBUF_POOL
2015-01-26 19:58:02 +08:00
*/
2015-11-09 22:11:21 +08:00
class ACL_CPP_API dbuf_pool // : public noncopyable
{
public:
/**
*
*/
dbuf_pool();
/**
* 使 destroy
*
*/
void destroy();
/**
* new/delete 使 dbuf_pool
* malloc/free
* @param size {size_t} dbuf_pool
* @param nblock {size_t} 4096
*/
2015-11-09 22:11:21 +08:00
void *operator new(size_t size, size_t nblock = 2);
2016-04-30 11:49:41 +08:00
2015-11-09 22:11:21 +08:00
#if defined(_WIN32) || defined(_WIN64)
void operator delete(void* ptr, size_t);
#endif
2016-04-30 11:49:41 +08:00
void operator delete(void* ptr);
/**
* 便使
* @param reserve {size_t} > 0
*
* @return {bool} false
*/
2015-11-09 22:11:21 +08:00
bool dbuf_reset(size_t reserve = 0);
2015-01-26 19:58:02 +08:00
/**
*
* @param len {size_t} (
* block_size) dbuf_pool
* 使 malloc
* @return {void*}
2015-01-26 19:58:02 +08:00
*/
void* dbuf_alloc(size_t len);
2015-01-26 19:58:02 +08:00
/**
*
* @param len {size_t}
* @return {void*}
2015-01-26 19:58:02 +08:00
*/
void* dbuf_calloc(size_t len);
2015-01-26 19:58:02 +08:00
/**
* strdup
* @param s {const char*}
* @return {char*}
2015-01-26 19:58:02 +08:00
*/
char* dbuf_strdup(const char* s);
2015-01-26 19:58:02 +08:00
2015-11-09 22:11:21 +08:00
/**
* strdup
* @param s {const char*}
* @param len {size_t}
* @return {char*}
2015-11-09 22:11:21 +08:00
*/
char* dbuf_strndup(const char* s, size_t len);
2015-01-26 19:58:02 +08:00
/**
*
* @param addr {const void*}
* @param len {size_t}
* @return {void*}
2015-01-26 19:58:02 +08:00
*/
2015-11-09 22:11:21 +08:00
void* dbuf_memdup(const void* addr, size_t len);
/**
*
* @param addr {const void*}
* @return {bool} false
2015-11-09 22:11:21 +08:00
*/
bool dbuf_free(const void* addr);
/**
* dbuf_reset
* @param addr {const void*}
* @return {bool} false
2015-11-09 22:11:21 +08:00
*/
bool dbuf_keep(const void* addr);
/**
* 便 dbuf_reset
* @param addr {const void*}
* @return {bool} false
2015-11-09 22:11:21 +08:00
*/
bool dbuf_unkeep(const void* addr);
/**
* ACL_DBUF_POOL 便 C
2015-11-09 22:11:21 +08:00
* @return {ACL_DBUF_POOL*}
*/
ACL_DBUF_POOL *get_dbuf()
{
return pool_;
}
private:
ACL_DBUF_POOL* pool_;
size_t mysize_;
2015-11-09 22:11:21 +08:00
public:
~dbuf_pool();
};
2015-11-09 22:11:21 +08:00
/**
* sample:
* void test()
* {
* acl::dbuf_pool* dbuf = new acl::dbuf_pool;
* for (int i = 0; i < 1000; i++)
* {
* char* ptr = dbuf->dbuf_strdup("hello world!");
* printf("%s\r\n", p);
* }
* dbuf->destroy();
*
* // 创建 dbuf 对象时,指定了内部分配内存块的位数
2015-11-09 22:11:21 +08:00
* dbuf = new(8) acl::dbuf_pool;
* for (int i = 0; i < 1000; i++)
* {
* ptr = dbuf->dbuf_strdup("hello world!");
* printf("%s\r\n", p);
* }
*
* // 销毁 dbuf 对象
2015-11-09 22:11:21 +08:00
* dbuf->destroy();
* }
*
*/
//////////////////////////////////////////////////////////////////////////////
class dbuf_guard;
/**
*
2015-11-09 22:11:21 +08:00
*/
class ACL_CPP_API dbuf_obj : public noncopyable
2015-11-09 22:11:21 +08:00
{
public:
/**
*
* @param guard {dbuf_guard*}
* dbuf_guard
* dbuf_guard::push_back
2015-11-09 22:11:21 +08:00
*/
dbuf_obj(dbuf_guard* guard = NULL);
virtual ~dbuf_obj() {}
/**
* dbuf_guard
* @return {int} dbuf_guard
* dbuf_guard -1
*/
int pos() const
{
return pos_;
}
/**
* dbuf_guard
* @return {dbuf_guard*}
*/
dbuf_guard* get_guard() const
{
return guard_;
}
private:
friend class dbuf_guard;
// 记录本对象所属的 dbuf_guard 对象
dbuf_guard* guard_;
// 该变量便于 dbuf_guard 对象使用,以增加安全性
int nrefer_;
// 该对象在 dbuf_guard 对象中记录的数组的位置
int pos_;
2015-11-09 22:11:21 +08:00
};
/**
* dbuf_pool
* dbuf_pool
2015-11-09 22:11:21 +08:00
*/
class ACL_CPP_API dbuf_guard // : public noncopyable
2015-11-09 22:11:21 +08:00
{
public:
/**
*
* @param dbuf {dbuf_pool*} dbuf dbuf_guard
* dbuf_pool
* @param capacity {size_t} objs_
*/
2016-04-30 11:49:41 +08:00
dbuf_guard(dbuf_pool* dbuf, size_t capacity = 500);
/**
*
* @param nblock {size_t} dbuf_pool
* (4096)
* @param capacity {size_t} objs_
2015-11-09 22:11:21 +08:00
*/
2016-04-30 11:49:41 +08:00
dbuf_guard(size_t nblock = 2, size_t capacity = 500);
2015-11-09 22:11:21 +08:00
/**
* dbuf_pool
2015-11-09 22:11:21 +08:00
*/
~dbuf_guard();
/**
* dbuf_pool::dbuf_reset
2015-11-09 22:11:21 +08:00
* @param reserve {size_t}
* @return {bool}
*/
bool dbuf_reset(size_t reserve = 0);
2015-11-09 22:11:21 +08:00
/**
* dbuf_pool::dbuf_alloc
2015-11-09 22:11:21 +08:00
* @param len {size_t}
* @return {void*}
*/
void* dbuf_alloc(size_t len)
{
return dbuf_->dbuf_alloc(len);
}
/**
* dbuf_pool::dbuf_calloc
2015-11-09 22:11:21 +08:00
* @param len {size_t}
* @return {void*}
*/
void* dbuf_calloc(size_t len)
{
return dbuf_->dbuf_calloc(len);
}
/**
* dbuf_pool::dbuf_strdup
2015-11-09 22:11:21 +08:00
* @param s {const char*}
* @return {char*}
*/
char* dbuf_strdup(const char* s)
{
return dbuf_->dbuf_strdup(s);
}
/**
* dbuf_pool::dbuf_strndup
2015-11-09 22:11:21 +08:00
* @param s {const char*}
* @param len {size_t}
* @return {char*}
*/
char* dbuf_strndup(const char* s, size_t len)
{
return dbuf_->dbuf_strndup(s, len);
}
/**
* dbuf_pool::dbuf_memdup
2015-11-09 22:11:21 +08:00
* @param addr {const void*}
* @param len {size_t}
* @return {void*}
*/
void* dbuf_memdup(const void* addr, size_t len)
{
return dbuf_->dbuf_memdup(addr, len);
}
/**
* dbuf_pool::dbuf_free
2015-11-09 22:11:21 +08:00
* @param addr {const void*}
* @return {bool}
*/
bool dbuf_free(const void* addr)
{
return dbuf_->dbuf_free(addr);
}
/**
* dbuf_pool::dbuf_keep
2015-11-09 22:11:21 +08:00
* @param addr {const void*}
* @return {bool}
*/
bool dbuf_keep(const void* addr)
{
return dbuf_->dbuf_keep(addr);
}
/**
* dbuf_pool::dbuf_unkeep
2015-11-09 22:11:21 +08:00
* @param addr {const void*}
* @return {bool}
*/
bool dbuf_unkeep(const void* addr)
{
return dbuf_->dbuf_unkeep(addr);
}
/**
* dbuf_pool
2015-11-09 22:11:21 +08:00
* @return {acl::dbuf_pool&}
*/
acl::dbuf_pool& get_dbuf() const
{
return *dbuf_;
}
/**
* dbuf_pool dbuf_obj
* dbuf_guard dbuf_obj
* dbuf_guard
2015-11-09 22:11:21 +08:00
* @param obj {dbuf_obj*}
* @return {int} obj dbuf_obj
* dbuf_guard dbuf_obj
* dbuf_obj dbuf_guard
2015-11-09 22:11:21 +08:00
*/
int push_back(dbuf_obj* obj);
/**
*
2015-11-09 22:11:21 +08:00
* @return {size_t}
*/
size_t size() const
{
return size_;
2015-11-09 22:11:21 +08:00
}
/**
*
* @param pos {size_t}
* @return {dbuf_obj*} NULL
2015-11-09 22:11:21 +08:00
*/
dbuf_obj* operator[](size_t pos) const;
/**
*
* @param pos {size_t}
* @return {dbuf_obj*} NULL
*/
dbuf_obj* get(size_t pos) const;
/**
* objs_ 100
* @param incr {size_t}
*/
void set_increment(size_t incr);
public:
template <typename T>
T* create()
{
T* t = new (dbuf_alloc(sizeof(T))) T();
(void) push_back(t);
return t;
}
template <typename T, typename P1>
T* create(P1 p)
{
T* t = new (dbuf_alloc(sizeof(T))) T(p);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2>
T* create(P1 p1, P2 p2)
{
T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3>
T* create(P1 p1, P2 p2, P3 p3)
{
T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4>
T* create(P1 p1, P2 p2, P3 p3, P4 p4)
{
T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4, typename P5>
T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
{
T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4, typename P5, typename P6>
T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
{
T* t = new (dbuf_alloc(sizeof(T))) T(p1, p2, p3, p4, p5, p6);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4, typename P5, typename P6, typename P7>
T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
{
T* t = new (dbuf_alloc(sizeof(T)))
T(p1, p2, p3, p4, p5, p6, p7);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4, typename P5, typename P6, typename P7,
typename P8>
T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
{
T* t = new (dbuf_alloc(sizeof(T)))
T(p1, p2, p3, p4, p5, p6, p7, p8);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4, typename P5, typename P6, typename P7,
typename P8,typename P9>
T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7,
P8 p8, P9 p9)
{
T* t = new (dbuf_alloc(sizeof(T)))
T(p1, p2, p3, p4, p5, p6, p7, p8, p9);
(void) push_back(t);
return t;
}
template <typename T, typename P1, typename P2, typename P3,
typename P4, typename P5, typename P6, typename P7,
typename P8, typename P9, typename P10>
T* create(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7,
P8 p8, P9 p9, P10 p10)
{
T* t = new (dbuf_alloc(sizeof(T)))
T(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
(void) push_back(t);
return t;
}
2015-11-09 22:11:21 +08:00
private:
size_t nblock_; // 内部自建 dbuf_pool 内存块的单位个数
size_t incr_; // 增加新的 dbuf_objs_link 时的
// capacity 大小
dbuf_pool* dbuf_; // 内存池对象
// 此处之所以使用自实现的 dbuf_obj 数组对象,而没有使用 std::vector
// 一方面使数组对象也在 dbuf_pool 内存池上创建,另一方面可以避免
// std::vector 内部在扩容时的内存不可控性
2016-04-30 11:49:41 +08:00
struct dbuf_objs_link
{
dbuf_obj** objs; // 存储 dbuf_obj 对象的数组对象
size_t size; // 存储于 objs 中的对象个数
size_t capacity; // objs 数组的大小
2016-04-30 11:49:41 +08:00
struct dbuf_objs_link* next;
};
dbuf_objs_link head_;
dbuf_objs_link* curr_;
size_t size_;
void init(size_t capacity);
// 扩充 objs_ 数组对象的空间
void extend_objs();
2015-11-09 22:11:21 +08:00
};
/**
* sample1:
* // 继承 acl::dbuf_obj 的子类
* class myobj1 : public acl::dbuf_obj
2015-11-09 22:11:21 +08:00
* {
* public:
* // 将 guard 对象传递给基类对象,基类将本对象加入 guard 的对象集合中
* myobj1(acl::dbuf_guard* guard) : dbuf_obj(guard) {}
2015-11-09 22:11:21 +08:00
*
* void doit()
* {
* printf("hello world!\r\n");
* }
*
* private:
* ~myobj1() {}
2015-11-09 22:11:21 +08:00
* };
*
* void test()
* {
* acl::dbuf_guard dbuf;
2015-11-09 22:11:21 +08:00
*
* // 在 dbuf_guard 对象上创建动态 100 个 myobj 对象
2015-11-09 22:11:21 +08:00
* for (int i = 0; i < 100; i++)
* {
* // 在 guard 对象上创建动态 myobj 对象,且将 guard 作为构造参数
* myobj* obj = new (dbuf.dbuf_alloc(sizeof(myobj))) myobj(&dbuf);
2015-11-09 22:11:21 +08:00
* obj->doit();
* }
*
* // 当 dbuf 销毁时,在其上面创建的动态对象自动销毁
* }
*
* // sample2
* class myobj2 : public acl::dbuf_obj
* {
* public:
* myobj2() {}
*
* void doit()
* {
* printf("hello world\r\n");
* }
*
* private:
* ~myobj2() {}
* };
*
* void test2()
* {
* acl::dbuf_guard dbuf;
*
* for (int i = 0; i < 100; i++)
* {
* myobj2* obj = dbuf.create<myobj2>();
* obj->doit();
* }
* }
*
* // sample3
* class myobj2 : public acl::dbuf_obj
* {
* public:
* myobj2(int i) : i_(i) {}
*
* void doit()
* {
* printf("hello world, i: %d\r\n", i_);
* }
*
* private:
* ~myobj2() {}
*
* private:
* int i_;
* };
*
* void test2()
* {
* acl::dbuf_guard dbuf;
*
* for (int i = 0; i < 100; i++)
* {
* myobj2* obj = dbuf.create<myobj2>(i);
* obj->doit();
* }
2015-11-09 22:11:21 +08:00
* }
*/
} // namespace acl