#ifndef PMEMOBJ_POOL_HPP
#define PMEMOBJ_POOL_HPP
#include <stddef.h>
#include <string>
#include <sys/stat.h>
#include "libpmemobj++/detail/pexceptions.hpp"
#include "libpmemobj++/p.hpp"
#include "libpmemobj/pool_base.h"
namespace pmem
{
namespace obj
{
template <typename T>
class persistent_ptr;
class pool_base {
public:
pool_base() noexcept : pop(nullptr)
{
}
explicit pool_base(pmemobjpool *cpop) noexcept : pop(cpop)
{
}
pool_base(const pool_base &) noexcept = default;
pool_base(pool_base &&) noexcept = default;
pool_base &operator=(const pool_base &) noexcept = default;
pool_base &operator=(pool_base &&) noexcept = default;
virtual ~pool_base() noexcept = default;
static pool_base
open(const std::string &path, const std::string &layout)
{
#ifdef _WIN32
pmemobjpool *pop = pmemobj_openU(path.c_str(), layout.c_str());
#else
pmemobjpool *pop = pmemobj_open(path.c_str(), layout.c_str());
#endif
if (pop == nullptr)
throw pool_error("Failed opening pool");
return pool_base(pop);
}
static pool_base
create(const std::string &path, const std::string &layout,
std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
{
#ifdef _WIN32
pmemobjpool *pop = pmemobj_createU(path.c_str(), layout.c_str(),
size, mode);
#else
pmemobjpool *pop = pmemobj_create(path.c_str(), layout.c_str(),
size, mode);
#endif
if (pop == nullptr)
throw pool_error("Failed creating pool");
return pool_base(pop);
}
static int
check(const std::string &path, const std::string &layout) noexcept
{
#ifdef _WIN32
return pmemobj_checkU(path.c_str(), layout.c_str());
#else
return pmemobj_check(path.c_str(), layout.c_str());
#endif
}
#ifdef _WIN32
static pool_base
open(const std::wstring &path, const std::wstring &layout)
{
pmemobjpool *pop = pmemobj_openW(path.c_str(), layout.c_str());
if (pop == nullptr)
throw pool_error("Failed opening pool");
return pool_base(pop);
}
static pool_base
create(const std::wstring &path, const std::wstring &layout,
std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
{
pmemobjpool *pop = pmemobj_createW(path.c_str(), layout.c_str(),
size, mode);
if (pop == nullptr)
throw pool_error("Failed creating pool");
return pool_base(pop);
}
static int
check(const std::wstring &path, const std::wstring &layout) noexcept
{
return pmemobj_checkW(path.c_str(), layout.c_str());
}
#endif
void
close()
{
if (this->pop == nullptr)
throw std::logic_error("Pool already closed");
pmemobj_close(this->pop);
this->pop = nullptr;
}
void
persist(const void *addr, size_t len) noexcept
{
pmemobj_persist(this->pop, addr, len);
}
template <typename Y>
void
persist(const p<Y> &prop) noexcept
{
pmemobj_persist(this->pop, &prop, sizeof(Y));
}
template <typename Y>
void
persist(const persistent_ptr<Y> &ptr) noexcept
{
pmemobj_persist(this->pop, &ptr, sizeof(ptr));
}
void
flush(const void *addr, size_t len) noexcept
{
pmemobj_flush(this->pop, addr, len);
}
template <typename Y>
void
flush(const p<Y> &prop) noexcept
{
pmemobj_flush(this->pop, &prop, sizeof(Y));
}
template <typename Y>
void
flush(const persistent_ptr<Y> &ptr) noexcept
{
pmemobj_flush(this->pop, &ptr, sizeof(ptr));
}
void
drain(void) noexcept
{
pmemobj_drain(this->pop);
}
void *
memcpy_persist(void *dest, const void *src, size_t len) noexcept
{
return pmemobj_memcpy_persist(this->pop, dest, src, len);
}
void *
memset_persist(void *dest, int c, size_t len) noexcept
{
return pmemobj_memset_persist(this->pop, dest, c, len);
}
PMEMobjpool *
get_handle() noexcept
{
return this->pop;
}
protected:
PMEMobjpool *pop;
#ifndef _WIN32
static const int DEFAULT_MODE = S_IWUSR | S_IRUSR;
#else
static const int DEFAULT_MODE = S_IWRITE | S_IREAD;
#endif
};
template <typename T>
class pool : public pool_base {
public:
pool() noexcept = default;
pool(const pool &) noexcept = default;
pool(pool &&) noexcept = default;
pool &operator=(const pool &) noexcept = default;
pool &operator=(pool &&) noexcept = default;
~pool() noexcept = default;
explicit pool(const pool_base &pb) noexcept : pool_base(pb)
{
}
explicit pool(pool_base &&pb) noexcept : pool_base(pb)
{
}
persistent_ptr<T>
get_root()
{
if (pop == nullptr)
throw pool_error("Invalid pool handle");
persistent_ptr<T> root = pmemobj_root(this->pop, sizeof(T));
return root;
}
static pool<T>
open(const std::string &path, const std::string &layout)
{
return pool<T>(pool_base::open(path, layout));
}
static pool<T>
create(const std::string &path, const std::string &layout,
std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
{
return pool<T>(pool_base::create(path, layout, size, mode));
}
static int
check(const std::string &path, const std::string &layout)
{
return pool_base::check(path, layout);
}
#ifdef _WIN32
static pool<T>
open(const std::wstring &path, const std::wstring &layout)
{
return pool<T>(pool_base::open(path, layout));
}
static pool<T>
create(const std::wstring &path, const std::wstring &layout,
std::size_t size = PMEMOBJ_MIN_POOL, mode_t mode = DEFAULT_MODE)
{
return pool<T>(pool_base::create(path, layout, size, mode));
}
static int
check(const std::wstring &path, const std::wstring &layout)
{
return pool_base::check(path, layout);
}
#endif
};
}
}
#endif