11 #ifndef HSTORE_H_INCLUDED 12 #define HSTORE_H_INCLUDED 28 #include <sys/types.h> 32 #include <sys/socket.h> 33 #include <sys/ioctl.h> 34 #include <netinet/in.h> 40 #if defined(__APPLE__) && defined(__MACH__) 41 namespace hobbes {
namespace storage {
42 static inline void waitForUpdate(
volatile uint32_t* p,
int eqV) {
44 for (
size_t c = 0; c < 4096; ++c) {
52 static inline void wakeN(
volatile uint32_t* p,
int c) {
57 #include <linux/futex.h> 58 #include <sys/syscall.h> 60 namespace hobbes {
namespace storage {
61 static inline long sys_futex(
volatile uint32_t* p,
int op,
int v,
struct timespec* timeout,
void* p2,
int v2) {
62 return syscall(SYS_futex, p, op, v, timeout, p2, v2);
67 static inline void wakeN(
volatile uint32_t* p,
int c) {
73 namespace hobbes {
namespace storage {
75 #define HSTORE_VERSION ((uint32_t)0x00010000) 77 typedef std::vector<uint8_t>
bytes;
80 #define _HSTORE_LIKELY(x) __builtin_expect((x),1) 81 #define _HSTORE_UNLIKELY(x) __builtin_expect((x),0) 85 if (m == 0 || (x % m) == 0) {
88 return (1 + (x / m)) *
m;
92 static inline void uxchg(
volatile uint32_t* px, uint32_t nx) {
100 #define xchg __sync_lock_test_and_set 103 inline void mqwrite(
int fd,
const uint8_t* x,
size_t len) {
106 ssize_t c =
write(fd, x + i, len - i);
108 if (errno != EINTR) {
109 throw std::runtime_error(
"Couldn't write to socket: " + std::string(strerror(errno)));
118 int r = socket(AF_UNIX, SOCK_STREAM, 0);
120 throw std::runtime_error(
"Unable to allocate socket: " + std::string(strerror(errno)));
124 memset(&addr, 0,
sizeof(addr));
125 addr.sun_family = AF_UNIX;
126 snprintf(addr.sun_path,
sizeof(addr.sun_path),
"%s", fileName.c_str());
128 sockaddr* saddr = (sockaddr*)&addr;
129 size_t len =
sizeof(addr);
130 if (connect(r, saddr, len) == -1) {
131 std::string emsg =
"Unable to connect socket: " + std::string(strerror(errno));
133 throw std::runtime_error(emsg);
139 if (
select(r + 1, 0, &wd, 0, 0) == -1) {
140 std::string emsg =
"Failed to connect socket while waiting for writeability: " + std::string(strerror(errno));
142 throw std::runtime_error(emsg);
146 mqwrite(r, (
const uint8_t*)&version,
sizeof(version));
151 int s = socket(AF_UNIX, SOCK_STREAM, 0);
153 throw std::runtime_error(
"Unable to allocate socket: " + std::string(strerror(errno)));
157 memset(&addr, 0,
sizeof(addr));
158 addr.sun_family = AF_UNIX;
159 unlink(fileName.c_str());
160 snprintf(addr.sun_path,
sizeof(addr.sun_path),
"%s", fileName.c_str());
162 if (bind(s, (sockaddr*)&addr,
sizeof(addr)) == -1) {
163 std::string emsg =
"Unable to bind socket to file: " + fileName +
" (" + std::string(strerror(errno)) +
")";
165 throw std::runtime_error(emsg);
169 if (listen(s, SOMAXCONN) == -1) {
170 std::string emsg =
"Unable to listen socket on file: " + fileName +
" (" + std::string(strerror(errno)) +
")";
172 throw std::runtime_error(emsg);
180 if ((td = ::getenv(
"TMPDIR"))) {
181 if (::strlen(td) > 0 && ::access(td, W_OK) == 0) {
182 return std::string(td);
185 if ((td = ::getenv(
"TMP"))) {
186 if (::strlen(td) > 0 && ::access(td, W_OK) == 0) {
187 return std::string(td);
190 if (::access(
"/var/tmp", W_OK) == 0) {
209 r.first = (uint64_t)getpid();
210 #if defined(__APPLE__) && defined(__MACH__) 211 pthread_threadid_np(0, &r.second);
213 r.second = (uint64_t)syscall(SYS_gettid);
219 inline std::string
sharedMemName(
const std::string& groupName,
const ProcThread& pt) {
220 std::ostringstream ss;
221 ss <<
"/" << groupName <<
"." << pt.first <<
"." << pt.second;
237 memcpy(msg+1, &pt,
sizeof(ProcThread));
238 mqwrite(*mqserver, msg,
sizeof(msg));
245 #define _HSTORE_STATE_UNBLOCKED 0 246 #define _HSTORE_STATE_READER_WAITING 1 247 #define _HSTORE_STATE_WRITER_WAITING 2 251 valuesz(0), count(0), wstate(0), readerIndex(0), writerIndex(0), data(0) {
254 pqueue_config(
size_t valuesz,
size_t count, uint32_t* wstate, uint32_t* ri, uint32_t* wi, uint8_t* data) :
255 valuesz(valuesz), count(count), wstate(wstate), readerIndex(ri), writerIndex(wi), data(data)
293 inline uint32_t
nextIndex(
volatile uint32_t* i)
const {
return (*i + 1) % this->cfg.
count; }
295 writer(
const bytes& meta,
const std::string& shmname,
size_t qvalsz,
size_t count) {
296 shm_unlink(shmname.c_str());
299 long pagesz = sysconf(_SC_PAGESIZE);
301 throw std::runtime_error(
"Failed to query system page size for '" + shmname +
"': " + strerror(errno));
305 int shfd = shm_open(shmname.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
307 throw std::runtime_error(
"Failed to allocate shared memory for '" + shmname +
"': " + strerror(errno));
312 size_t metaLen = align<size_t>(
sizeof(
ShQueueHeader) + meta.size(), pagesz);
313 size_t dataLen = align<size_t>(
sizeof(
ShQueueData) + qvalsz*count, pagesz);
314 size_t memLen = metaLen + dataLen;
317 if (ftruncate(shfd, memLen) == -1) {
318 throw std::runtime_error(
"Failed to truncate shared memory for '" + shmname +
"': " + strerror(errno));
321 uint8_t* mem = (uint8_t*)mmap(0, memLen, PROT_READ | PROT_WRITE, MAP_SHARED, shfd, 0);
322 if (mem == MAP_FAILED) {
323 throw std::runtime_error(
"Failed to map bytes out of shared memory for '" + shmname +
"': " + strerror(errno));
330 hdr->
metasz = meta.size();
339 this->shmname = shmname;
342 this->cfg.
count = count;
350 shm_unlink(this->shmname.c_str());
356 uint32_t nwi = nextIndex(writeIndex());
365 if (*readIndex() == nwi) {
373 wakeN(waitState(), 1);
377 return value(*writeIndex());
384 return value(*writeIndex());
389 uxchg(writeIndex(), nextIndex(writeIndex()));
393 wakeN(waitState(), 1);
403 #define _HSTORE_PAGE_STATE_TENTATIVE ((uint8_t)0) 404 #define _HSTORE_PAGE_STATE_CONT ((uint8_t)1) 405 #define _HSTORE_PAGE_STATE_COMMIT ((uint8_t)2) 406 #define _HSTORE_PAGE_STATE_ROLLBACK ((uint8_t)3) 424 *((uint32_t*)(this->page + this->pagesz)) = (((uint32_t)c) << 24) | this->
offset;
436 this->page = this->wq->
next();
442 uint8_t* npage = this->wq->
pollNext();
453 throw std::runtime_error(
"queue page size too small for use as shared memory pipe");
463 this->page = reliable() ? this->wq->
next() : this->wq->
pollNext();
468 return this->page && sz < (this->pagesz - this->
offset);
472 bool write(
const uint8_t* src,
size_t sz) {
478 size_t remsz = this->pagesz - this->
offset;
482 memcpy(this->page + this->offset, src, sz);
491 memcpy(this->page + this->offset, src, remsz);
492 this->offset += remsz;
495 while (stepPage() && sz - so >= this->pagesz) {
496 memcpy(this->page, src + so, this->pagesz);
503 this->offset = sz - so;
504 memcpy(this->page, src + so, this->offset);
520 long pagesz = sysconf(_SC_PAGESIZE);
522 throw std::runtime_error(
"Failed to query system page size for '" + shmname +
"': " + strerror(errno));
526 int shfd = shm_open(shmname.c_str(), O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
528 throw std::runtime_error(
"Failed to open shared memory for '" + shmname +
"': " + strerror(errno));
533 if (fstat(shfd, &msb) < 0) {
535 throw std::runtime_error(
"Failed to stat shared memory for '" + shmname +
"': " + strerror(errno));
537 if (msb.st_size <= 0) {
539 throw std::runtime_error(
"Shared memory for '" + shmname +
"' is not ready");
543 uint8_t* mem = (uint8_t*)mmap(0, msb.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, shfd, 0);
544 if (mem == MAP_FAILED) {
546 throw std::runtime_error(
"Failed to map bytes out of shared memory for '" + shmname +
"': " + strerror(errno));
550 munmap(mem, msb.st_size);
552 throw std::runtime_error(
"Not ready to consume shared memory for '" + shmname +
"'");
556 shm_unlink(shmname.c_str());
561 c.datasz = msb.st_size;
582 inline uint32_t
nextIndex(
volatile uint32_t* i)
const {
return (*i + 1) % this->cfg.
count; }
592 this->metasz = hdr->
metasz;
608 typedef std::pair<const uint8_t*, size_t>
MetaData;
610 return MetaData(this->metad, this->metasz);
615 uint32_t ri = *readIndex();
624 if (*writeIndex() == ri) {
632 wakeN(waitState(), 1);
636 return value(*readIndex());
644 return value(*readIndex());
650 uxchg(readIndex(), nextIndex(readIndex()));
654 wakeN(waitState(), 1);
667 rpipe(
reader* rq) : rq(rq), page(0), pagesz(rq->
config().valuesz - sizeof(uint32_t)), offset(0) {
669 throw std::runtime_error(
"queue page size too small for use as shared memory pipe");
676 this->page = this->rq->
next();
681 while (sz != 0 && this->page) {
683 volatile uint32_t* pend = (uint32_t*)(this->page + this->pagesz);
684 size_t rpagesz = *pend & ~(0xFF << 24);
685 size_t availPage = rpagesz - this->
offset;
686 size_t csz = (sz < availPage) ? sz : availPage;
689 memcpy(dst + doff, this->page + this->offset, csz);
697 if (this->offset == rpagesz) {
700 uint8_t ps = *pend >> 24;
701 if (state) *state = ps;
716 #define _HSTORE_TYCTOR_PRIM ((int)0) 717 #define _HSTORE_TYCTOR_TVAR ((int)2) 718 #define _HSTORE_TYCTOR_FIXEDARR ((int)4) 719 #define _HSTORE_TYCTOR_ARR ((int)5) 720 #define _HSTORE_TYCTOR_VARIANT ((int)6) 721 #define _HSTORE_TYCTOR_STRUCT ((int)7) 722 #define _HSTORE_TYCTOR_SIZE ((int)11) 723 #define _HSTORE_TYCTOR_RECURSIVE ((int)13) 725 template <
typename T,
typename P =
void>
728 template <
typename T>
729 void w(
const T& x, bytes*
out) {
730 out->insert(out->end(), (uint8_t*)&x, ((uint8_t*)&x) +
sizeof(x));
732 inline void ws(
const char* x, bytes*
out) {
733 size_t n = strlen(x);
735 out->insert(out->end(), x, x + n);
737 inline void ws(
const std::string& x, bytes*
out) {
738 w((
size_t)x.size(),
out);
739 out->insert(out->end(), x.begin(), x.end());
741 inline void ws(
const bytes& x, bytes*
out) {
742 w((
size_t)x.size(),
out);
743 out->insert(out->end(), x.begin(), x.end());
751 #define _HSTORE_DEFINE_PRIMTYS(T, n) \ 754 typedef void can_memcpy; \ 755 static void encode(bytes* out) { encode_primty(n, out); } \ 756 static std::string describe() { return n; } \ 757 static size_t size(const T&) { return sizeof(T); } \ 758 static bool write(wpipe& p, const T& x) { return p.write((const uint8_t*)&x, sizeof(x)); } \ 776 template <
typename T,
typename P =
void>
780 template <
typename T>
784 template <
typename ... Ts>
786 static const size_t count = 0;
789 static size_t size(
const Ts&...) {
return 0; }
792 template <
typename T,
typename ... Ts>
798 snprintf(fn,
sizeof(fn),
".f%lld", (
unsigned long long)f);
808 static size_t size(
const T& x,
const Ts&... xs) {
815 template <
size_t i,
size_t e,
typename ... Ts>
817 static size_t size(
const std::tuple<Ts...>& t) {
818 return store<
typename std::tuple_element<i,
std::tuple<Ts...>>::type>::size(std::get<i>(t)) +
826 template <
size_t e,
typename ... Ts>
828 static size_t size(
const std::tuple<Ts...>&) {
835 template <
typename ... Ts>
840 size_t localArity = arity;
842 if (localArity > 0) {
852 return (x.size() > 1) ? x.substr(0,x.size()-1) : x;
854 static size_t size(
const std::tuple<Ts...>& t) {
863 #define _HSTORE_FIRST(a, ...) a 864 #define _HSTORE_SECOND(a, b, ...) b 865 #define _HSTORE_JOIN(a,b) a ## b 866 #define _HSTORE_IS_NEGATE(...) _HSTORE_SECOND(__VA_ARGS__, 0) 867 #define _HSTORE_NOT(x) _HSTORE_IS_NEGATE(_HSTORE_JOIN(_HSTORE__NOT_, x)) 868 #define _HSTORE__NOT_0 NEGATE, 1 869 #define _HSTORE_BOOL(x) _HSTORE_NOT(_HSTORE_NOT(x)) 870 #define _HSTORE_IF_ELSE(condition) _HSTORE__IF_ELSE(_HSTORE_BOOL(condition)) 871 #define _HSTORE__IF_ELSE(condition) _HSTORE_JOIN(_HSTORE__IF_, condition) 872 #define _HSTORE__IF_1(...) __VA_ARGS__ _HSTORE__IF_1_ELSE 873 #define _HSTORE__IF_0(...) _HSTORE__IF_0_ELSE 874 #define _HSTORE__IF_1_ELSE(...) 875 #define _HSTORE__IF_0_ELSE(...) __VA_ARGS__ 876 #define _HSTORE_EMPTY() 877 #define _HSTORE_EVAL(...) _HSTORE_EVAL256(__VA_ARGS__) 878 #define _HSTORE_EVAL256(...) _HSTORE_EVAL128(_HSTORE_EVAL128(__VA_ARGS__)) 879 #define _HSTORE_EVAL128(...) _HSTORE_EVAL64(_HSTORE_EVAL64(__VA_ARGS__)) 880 #define _HSTORE_EVAL64(...) _HSTORE_EVAL32(_HSTORE_EVAL32(__VA_ARGS__)) 881 #define _HSTORE_EVAL32(...) _HSTORE_EVAL16(_HSTORE_EVAL16(__VA_ARGS__)) 882 #define _HSTORE_EVAL16(...) _HSTORE_EVAL8(_HSTORE_EVAL8(__VA_ARGS__)) 883 #define _HSTORE_EVAL8(...) _HSTORE_EVAL4(_HSTORE_EVAL4(__VA_ARGS__)) 884 #define _HSTORE_EVAL4(...) _HSTORE_EVAL2(_HSTORE_EVAL2(__VA_ARGS__)) 885 #define _HSTORE_EVAL2(...) _HSTORE_EVAL1(_HSTORE_EVAL1(__VA_ARGS__)) 886 #define _HSTORE_EVAL1(...) __VA_ARGS__ 887 #define _HSTORE_DEFER2(m) m _HSTORE_EMPTY _HSTORE_EMPTY()() 888 #define _HSTORE_HAS_PARGS(...) _HSTORE_BOOL(_HSTORE_FIRST(_HSTORE__EOAP_ __VA_ARGS__)()) 889 #define _HSTORE__EOAP_(...) _HSTORE_BOOL(_HSTORE_FIRST(_HSTORE__EOA_ __VA_ARGS__)()) 890 #define _HSTORE__EOA_() 0 891 #define _HSTORE_MAP(f, VS...) _HSTORE_EVAL(_HSTORE_MAPP(f, VS)) 892 #define _HSTORE_MAPP(f, H, T...) \ 894 _HSTORE_IF_ELSE(_HSTORE_HAS_PARGS(T))( \ 895 _HSTORE_DEFER2(_HSTORE__MAPP)()(f, T) \ 898 #define _HSTORE__MAPP() _HSTORE_MAPP 901 #define HSTORE_FIELDC_SUCC(t,n) +1 902 #define HSTORE_FIELD_COUNT(FIELDS...) (0 _HSTORE_MAP(HSTORE_FIELDC_SUCC, FIELDS)) 904 #define HSTORE_FIELDS_SUCC(t,n) +::hobbes::storage::store< t >::size(this-> n) 905 #define HSTORE_FIELD_SIZE(FIELDS...) (0 _HSTORE_MAP(HSTORE_FIELDS_SUCC, FIELDS)) 907 #define HSTORE_FIELDW_SUCC(t,n) &&::hobbes::storage::store< t >::write(p, this-> n) 908 #define HSTORE_FIELD_WRITES(FIELDS...) (true _HSTORE_MAP(HSTORE_FIELDW_SUCC, FIELDS)) 910 #define HSTORE_STRUCT_FIELD(t, n) t n; 911 #define HSTORE_STRUCT_FIELD_ENC(t, n) ::hobbes::storage::ws(#n, out); ::hobbes::storage::w((int)-1, out); ::hobbes::storage::store< t >::encode(out); 912 #define HSTORE_STRUCT_FIELD_DESC(t, n) + (", " #n " : " + ::hobbes::storage::store< t >::describe()) 914 #define DEFINE_PACKED_HSTORE_STRUCT(T, FIELDS...) \ 916 _HSTORE_MAP(HSTORE_STRUCT_FIELD, FIELDS) \ 917 typedef void is_packed_hstore_struct; \ 918 static void encode(::hobbes::storage::bytes* out) { \ 919 size_t localArity = HSTORE_FIELD_COUNT(FIELDS); \ 920 if (localArity > 0) { \ 921 ::hobbes::storage::w(_HSTORE_TYCTOR_STRUCT, out); \ 922 ::hobbes::storage::w(localArity, out); \ 923 _HSTORE_MAP(HSTORE_STRUCT_FIELD_ENC, FIELDS) \ 925 ::hobbes::storage::encode_primty("unit", out); \ 928 static std::string describe() { \ 929 return "{" + ( std::string("") _HSTORE_MAP(HSTORE_STRUCT_FIELD_DESC, FIELDS) ).substr(2) + "}"; \ 931 } __attribute__((packed)) 933 template <
typename T>
934 struct store<T, typename T::is_packed_hstore_struct> {
937 static std::string
describe() {
return T::describe(); }
938 static size_t size(
const T&) {
return sizeof(T); }
939 static bool write(
wpipe& p,
const T& x) {
return p.
write((
const uint8_t*)&x,
sizeof(x)); }
943 #define DEFINE_HSTORE_STRUCT(T, FIELDS...) \ 945 _HSTORE_MAP(HSTORE_STRUCT_FIELD, FIELDS) \ 946 typedef void is_hstore_struct; \ 947 static void encode(::hobbes::storage::bytes* out) { \ 948 size_t localArity = HSTORE_FIELD_COUNT(FIELDS); \ 949 if (localArity > 0) { \ 950 ::hobbes::storage::w(_HSTORE_TYCTOR_STRUCT, out); \ 951 ::hobbes::storage::w(localArity, out); \ 952 _HSTORE_MAP(HSTORE_STRUCT_FIELD_ENC, FIELDS) \ 954 ::hobbes::storage::encode_primty("unit", out); \ 957 static std::string describe() { \ 958 return "{" + ( std::string("") _HSTORE_MAP(HSTORE_STRUCT_FIELD_DESC, FIELDS) ).substr(2) + "}"; \ 960 size_t size() const { \ 961 return HSTORE_FIELD_SIZE(FIELDS); \ 963 bool write(::hobbes::storage::wpipe& p) const { \ 964 return HSTORE_FIELD_WRITES(FIELDS); \ 968 template <
typename T>
969 struct store<T, typename T::is_hstore_struct> {
971 static std::string
describe() {
return T::describe(); }
972 static size_t size(
const T& x) {
return x.size(); }
973 static bool write(
wpipe& p,
const T& x) {
return x.write(p); }
977 template <
typename U,
typename V>
994 static size_t size(
const std::pair<U, V>& x) {
1003 #define HSTORE_ENUM_CTOR_DEF(n) n , 1004 #define HSTORE_ENUM_CTOR_CTOR(n) static const SelfT n() { return SelfT(SelfT::Enum::n); } 1005 #define HSTORE_ENUM_CTORC_SUCC(n) +1 1006 #define HSTORE_ENUM_CTOR_STR(n) + "|" #n 1007 #define HSTORE_ENUM_CTOR_ENCODE(n) \ 1008 ::hobbes::storage::ws(#n, out); \ 1009 ::hobbes::storage::w((uint32_t)(Enum :: n), out); \ 1010 ::hobbes::storage::encode_primty("unit", out); 1012 #define DEFINE_HSTORE_ENUM(T, CTORS...) \ 1014 typedef void is_hstore_enum; \ 1015 enum class Enum : uint32_t { \ 1016 _HSTORE_MAP(HSTORE_ENUM_CTOR_DEF, CTORS) \ 1021 T(Enum v) : value(v) { } \ 1022 T& operator=(Enum v) { this->value = v; return *this; } \ 1023 operator Enum() { return this->value; } \ 1025 _HSTORE_MAP(HSTORE_ENUM_CTOR_CTOR, CTORS) \ 1026 static void encode(::hobbes::storage::bytes* out) { \ 1027 ::hobbes::storage::w(_HSTORE_TYCTOR_VARIANT, out); \ 1028 ::hobbes::storage::w((size_t)(0 _HSTORE_MAP(HSTORE_ENUM_CTORC_SUCC, CTORS)), out); \ 1029 _HSTORE_MAP(HSTORE_ENUM_CTOR_ENCODE, CTORS); \ 1031 static std::string describe() { \ 1032 return (std::string("") _HSTORE_MAP(HSTORE_ENUM_CTOR_STR, CTORS)).substr(1); \ 1036 template <
typename T>
1037 struct store<T, typename T::is_hstore_enum> {
1040 static std::string
describe() {
return T::describe(); }
1041 static size_t size(
const T&) {
return sizeof(T); }
1042 static bool write(
wpipe& p,
const T& x) {
return p.
write((
const uint8_t*)&x,
sizeof(x)); }
1046 #define DEFINE_HSTORE_VARIANT_GEN(T, VDECL, VCTORS, VCOPY, VDESTROY, CTORCOUNT, VENCODE, VDESC, VSIZE, VWRITE, VVISITCASE, VEQCASE, CTAGS, CDATA) \ 1047 template <typename R> \ 1048 struct T##Visitor { \ 1052 typedef void is_hstore_variant; \ 1054 T() : tag(Enum::COUNT) { } \ 1056 T(const T& rhs) : tag(rhs.tag) { \ 1057 switch (this->tag) { \ 1063 switch (this->tag) { \ 1068 T& operator=(const T& rhs) { \ 1069 if (this == &rhs) return *this; \ 1070 switch (this->tag) { \ 1074 this->tag = rhs.tag; \ 1075 switch (this->tag) { \ 1081 static void encode(::hobbes::storage::bytes* out) { \ 1082 ::hobbes::storage::w(_HSTORE_TYCTOR_VARIANT, out); \ 1083 ::hobbes::storage::w((size_t)(0 CTORCOUNT), out); \ 1086 static std::string describe() { \ 1087 return "|" + (std::string("") VDESC).substr(1) + "|"; \ 1089 size_t wireSize() const { \ 1090 switch (this->tag) { \ 1092 default: return 0; \ 1095 bool write(::hobbes::storage::wpipe& p) const { \ 1096 switch (this->tag) { \ 1098 default: return false; \ 1101 template <typename R> \ 1102 R visit(const T##Visitor<R>& v) const { \ 1103 switch (this->tag) { \ 1105 default: throw std::runtime_error("while deconstructing the " #T " variant, cannot decide payload type because tag is invalid"); \ 1108 bool operator==(const T& rhs) const { \ 1109 if (this->tag != rhs.tag) { \ 1112 switch (this->tag) { \ 1114 default: return false; \ 1119 enum class Enum : uint32_t { \ 1131 #define HSTORE_VARIANT_CTOR(n, t) static SelfT n(const t & x) { SelfT r; r.tag = Enum::tag_##n; new (r.data) t(x); return r; } 1132 #define HSTORE_VARIANT_CTOR_STR(n, t) + "," #n ":" + ::hobbes::storage::store< t >::describe() 1133 #define HSTORE_VARIANT_CTOR_TAG(n, t) tag_##n, 1134 #define HSTORE_VARIANT_SIZE_CASE(n, t) case Enum::tag_##n: return sizeof(int) + ::hobbes::storage::store< t >::size(this->n##_data); 1135 #define HSTORE_VARIANT_WRITE_CASE(n, t) case Enum::tag_##n: return ::hobbes::storage::store<int>::write(p, (int)this->tag) && ::hobbes::storage::store< t >::write(p, this->n##_data); 1136 #define HSTORE_VARIANT_PCOPY(n, t) case Enum::tag_##n: new (this->data) t(rhs.n##_data); break; 1137 #define HSTORE_VARIANT_PDESTROY(n, t) case Enum::tag_##n: { typedef t __DT; ((__DT*)&this->n##_data)->~__DT(); } break; 1138 #define HSTORE_VARIANT_SUCC(n, t) +1 1139 #define HSTORE_VARIANT_CTOR_OPAQUEDATA(n, t) t n##_data; 1140 #define HSTORE_VARIANT_CTOR_ENCODE(n, t) \ 1141 ::hobbes::storage::ws(#n, out); \ 1142 ::hobbes::storage::w((uint32_t)Enum::tag_##n, out); \ 1143 ::hobbes::storage::store< t >::encode(out); 1145 #define HSTORE_VARIANT_VDECL(n, t) virtual R n(const t & x) const = 0; 1146 #define HSTORE_VARIANT_VCASE(n, t) case Enum::tag_##n: return v. n (this->n##_data); 1147 #define HSTORE_VARIANT_EQCASE(n, t) case Enum::tag_##n: return (this->n##_data == rhs.n##_data); 1149 #define DEFINE_HSTORE_VARIANT(T, CTORS...) \ 1150 DEFINE_HSTORE_VARIANT_GEN(T, _HSTORE_MAP(HSTORE_VARIANT_VDECL, CTORS), _HSTORE_MAP(HSTORE_VARIANT_CTOR, CTORS), _HSTORE_MAP(HSTORE_VARIANT_PCOPY, CTORS), _HSTORE_MAP(HSTORE_VARIANT_PDESTROY, CTORS), _HSTORE_MAP(HSTORE_VARIANT_SUCC, CTORS), _HSTORE_MAP(HSTORE_VARIANT_CTOR_ENCODE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_CTOR_STR, CTORS), _HSTORE_MAP(HSTORE_VARIANT_SIZE_CASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_WRITE_CASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_VCASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_EQCASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_CTOR_TAG, CTORS), _HSTORE_MAP(HSTORE_VARIANT_CTOR_OPAQUEDATA, CTORS)) 1153 #define HSTORE_VARIANT_LBL_CTOR(n, lbl, t) static SelfT n(const t & x) { SelfT r; r.tag = Enum::tag_##n; new (r.data) t(x); return r; } 1154 #define HSTORE_VARIANT_LBL_CTOR_STR(n, lbl, t) + "," #n ":" + ::hobbes::storage::store< t >::describe() 1155 #define HSTORE_VARIANT_LBL_CTOR_TAG(n, lbl, t) tag_##n, 1156 #define HSTORE_VARIANT_LBL_SIZE_CASE(n, lbl, t) case Enum::tag_##n: return sizeof(int) + ::hobbes::storage::store< t >::size(this->n##_data); 1157 #define HSTORE_VARIANT_LBL_WRITE_CASE(n, lbl, t) case Enum::tag_##n: return ::hobbes::storage::store<int>::write(p, (int)this->tag) && ::hobbes::storage::store< t >::write(p, this->n##_data); 1158 #define HSTORE_VARIANT_LBL_PCOPY(n, lbl, t) case Enum::tag_##n: new (this->data) t(rhs.n##_data); break; 1159 #define HSTORE_VARIANT_LBL_PDESTROY(n, lbl, t) case Enum::tag_##n: { typedef t __DT; ((__DT*)&this->n##_data)->~__DT(); } break; 1160 #define HSTORE_VARIANT_LBL_SUCC(n, lbl, t) +1 1161 #define HSTORE_VARIANT_LBL_CTOR_OPAQUEDATA(n, lbl, t) t n##_data; 1162 #define HSTORE_VARIANT_LBL_CTOR_ENCODE(n, lbl, t) \ 1163 ::hobbes::storage::ws(#lbl, out); \ 1164 ::hobbes::storage::w((uint32_t)Enum::tag_##n, out); \ 1165 ::hobbes::storage::store< t >::encode(out); 1167 #define HSTORE_VARIANT_LBL_VDECL(n, lbl, t) virtual R n(const t & x) const = 0; 1168 #define HSTORE_VARIANT_LBL_VCASE(n, lbl, t) case Enum::tag_##n: return v. n (this->n##_data); 1169 #define HSTORE_VARIANT_LBL_EQCASE(n, lbl, t) case Enum::tag_##n: return (this->n##_data == rhs.n##_data); 1171 #define DEFINE_HSTORE_VARIANT_WITH_LABELS(T, CTORS...) \ 1172 DEFINE_HSTORE_VARIANT_GEN(T, _HSTORE_MAP(HSTORE_VARIANT_LBL_VDECL, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_CTOR, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_PCOPY, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_PDESTROY, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_SUCC, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_CTOR_ENCODE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_CTOR_STR, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_SIZE_CASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_WRITE_CASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_VCASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_EQCASE, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_CTOR_TAG, CTORS), _HSTORE_MAP(HSTORE_VARIANT_LBL_CTOR_OPAQUEDATA, CTORS)) 1174 template <
typename T>
1175 struct store<T, typename T::is_hstore_variant> {
1177 static std::string
describe() {
return T::describe(); }
1178 static size_t size(
const T& x) {
return x.wireSize(); }
1188 template <
typename T>
1207 thread_local RecSizeF
fn = 0;
1216 thread_local RecWriteF
fn = 0;
1220 return writeF()(p, x);
1224 template <
typename T>
1263 bool operator< (
const unit&)
const {
return false; }
1275 #define DEFINE_HSTORE_TYPE_ALIAS(_ATY, _REPTY) \ 1277 typedef void is_hstore_alias; \ 1278 typedef _REPTY type; \ 1279 static const char* name() { return #_ATY; } \ 1280 inline operator _REPTY() { return this->value; } \ 1282 _ATY() : value() { } \ 1283 _ATY(const _REPTY& x) : value(x) { } \ 1284 _ATY(const _ATY& x) : value(x.value) { } \ 1285 _ATY& operator=(const _ATY& x) { this->value = x.value; return *this; } \ 1288 template <
typename T>
1289 struct store<T, typename T::is_hstore_alias> {
1297 template <
typename T,
size_t N>
1308 snprintf(nf,
sizeof(nf),
"%lld", (
unsigned long long)N);
1313 template <
typename T,
size_t N>
1315 static size_t size(
const T (&v)[N]) {
1319 return p.
write((
const uint8_t*)v,
sizeof(T)*N);
1323 template <
typename T,
size_t N>
1325 static size_t size(
const T (&v)[N]) {
1327 for (
size_t i = 0; i < N; ++i) {
1333 for (
size_t i = 0; i < N; ++i) {
1342 template <
typename T,
size_t N>
1345 template <
typename T,
size_t N>
1349 template <
typename T>
1353 static size_t size(
const std::vector<T>& xs) {
return sizeof(size_t) + (xs.size() *
sizeof(T)); }
1357 template <
typename T>
1361 static size_t size(
const std::vector<T>& xs) {
1362 size_t t =
sizeof(size_t);
1363 for (
const auto& x : xs) {
1369 size_t n = xs.size();
1373 for (
const auto& x : xs) {
1387 static size_t size(
const char* s) {
return sizeof(size_t) + strlen(s); }
1394 static size_t size(
const std::string& s) {
return sizeof(size_t) + s.size(); }
1399 template <
typename ... Ts>
1402 static const size_t count = 0;
1406 template <
typename T,
typename ... Ts>
1412 snprintf(fn,
sizeof(fn),
".f%lld", (
unsigned long long)f);
1422 template <
typename ... Ts>
1428 template <
typename TyList>
1431 size_t localArity = TyList::count;
1434 switch (localArity) {
1450 *d = TyList::describe().substr(1);
1456 constexpr
char at(
size_t i,
const char (&s)[N]) {
1457 return (i < N) ? s[i] :
'\0';
1460 constexpr
size_t at8S(
size_t i,
size_t k,
const char (&s)[N]) {
1461 return (k==8) ? 0 : ((((size_t)
at(i+k,s))<<(8*k))|
at8S(i,k+1,s));
1464 constexpr
size_t at8(
size_t i,
const char (&s)[N]) {
1465 return at8S(i, 0, s);
1467 template <
size_t... pcs>
1470 constexpr
size_t msg[] = {pcs...};
1471 static_assert(msg[(
sizeof(msg)/
sizeof(msg[0]))-1] == 0,
"compile-time string larger than internal max limit (this limit can be bumped in storage.H)");
1472 return std::string((
const char*)msg);
1475 #define _HSTORE_TSTR32(i,s) ::hobbes::storage::at8(i+(8*0),s),::hobbes::storage::at8(i+(8*1),s),::hobbes::storage::at8(i+(8*2),s),::hobbes::storage::at8(i+(8*3),s) 1476 #define _HSTORE_TSTR128(i,s) _HSTORE_TSTR32(i+(32*0),s),_HSTORE_TSTR32(i+(32*1),s),_HSTORE_TSTR32(i+(32*2),s),_HSTORE_TSTR32(i+(32*3),s) 1477 #define _HSTORE_TSTR512(i,s) _HSTORE_TSTR128(i+(128*0),s),_HSTORE_TSTR128(i+(128*1),s),_HSTORE_TSTR128(i+(128*2),s),_HSTORE_TSTR128(i+(128*3),s) 1478 #define _HSTORE_TSTR1024(i,s) _HSTORE_TSTR512(i+(512*0),s),_HSTORE_TSTR512(i+(512*1),s) 1479 #define _HSTORE_TSTR(s) ::hobbes::storage::strpack<_HSTORE_TSTR1024(0,s)> 1481 template <u
int32_t* X>
1483 template <
typename Group, Group* G,
typename File, u
int32_t Line,
typename StmtName,
size_t Flags,
typename FormatStr,
typename ArgTyList>
1488 template <
typename Group, Group* G,
typename File, u
int32_t Line,
typename StmtName,
size_t Flags,
typename FormatStr,
typename ArgTyList>
1489 uint32_t
StorageStatement<Group, G, File, Line, StmtName, Flags, FormatStr, ArgTyList>::id = G->allocateStorageStatement(File::str(), Line, StmtName::str(), Flags, FormatStr::str(), &makeTyDescF<ArgTyList>);
1497 template <
typename Name, CommitMethod cm>
1522 if (!this->statements)
return;
1525 w((
int)this->qos, meta);
1529 w((uint32_t)this->statements->size(), meta);
1530 for (
auto s : *this->statements) {
1532 w (s.second.flags, meta);
1533 ws(s.second.fmtstr, meta);
1534 ws(s.second.file, meta);
1535 w (s.second.line, meta);
1536 w (s.second.id, meta);
1539 s.second.tdesc(&td,0);
1553 size_t pagesz = sysconf(_SC_PAGESIZE);
1554 size_t pagec = 1 + (meta.size() / pagesz) + std::max<size_t>(this->mempages, 10);
1570 if (!this->statements) {
1571 this->statements =
new StorageStatements();
1574 auto s = this->statements->find(name);
1575 if (s != this->statements->end()) {
1579 s->second.tdesc(&ety,0);
1582 std::string etd, xtd;
1583 s->second.tdesc(0,&etd);
1587 <<
"fatal error: incompatible types for store statement '" << name <<
"' between:\n" 1588 <<
" " << s->second.file <<
":" << s->second.line <<
" (" << xtd <<
")\n" 1590 <<
" " << file <<
":" << line <<
" (" << etd <<
")\n" 1596 if (s->second.fmtstr != fmtstr) {
1598 <<
"fatal error: incompatible format strings for store statement '" << name <<
"' between:\n" 1599 <<
" " << s->second.file <<
":" << s->second.line <<
" (" << s->second.fmtstr <<
")\n" 1601 <<
" " << file <<
":" << line <<
" (" << fmtstr <<
")\n" 1607 if (s->second.flags != flags) {
1609 <<
"fatal error: incompatible storage flags for store statement '" << name <<
"' between:\n" 1610 <<
" " << s->second.file <<
":" << s->second.line <<
" (" << s->second.flags <<
")\n" 1612 <<
" " << file <<
":" << line <<
" (" << flags <<
")\n" 1618 return s->second.id;
1628 d.
id = (uint32_t)this->statements->size();
1634 template <
typename Name, CommitMethod cm>
1638 template <
typename ... Ts>
1640 static size_t size(
const Ts&...) {
return 0; }
1643 template <
typename T,
typename ... Ts>
1645 static size_t size(
const T& x,
const Ts&... xs) {
1653 template <
typename GName,
typename ... Ts>
1662 template <
typename GName,
typename ... Ts>
1671 static constexpr
size_t readInt(
const char (&fmt)[N],
size_t i,
size_t e,
size_t n) {
1672 return (i == e) ? n :
readInt(fmt, i+1, e, (n*10)+(fmt[i]-
'0'));
1675 static constexpr
size_t maxV(
size_t x,
size_t y) {
1676 return (x < y) ? y : x;
1680 static constexpr
size_t maxVarRefS(
const char (&fmt)[N],
size_t i,
size_t s,
size_t vri,
size_t maxvr) {
1681 return (i >= N) ? maxvr
1682 :(s == 0) ? ((fmt[i] ==
'\\') ?
maxVarRefS(fmt, i+2, 0, 0, maxvr)
1683 :(fmt[i] ==
'$') ?
maxVarRefS(fmt, i+1, 1, i+1, maxvr)
1685 : ((fmt[i] >=
'0' && fmt[i] <=
'9') ?
1696 #define DECLARE_STORAGE_GROUP(NAME, cm) extern ::hobbes::storage::StorageGroup<_HSTORE_TSTR(#NAME),cm> NAME 1697 #define DEFINE_STORAGE_GROUP(NAME, pagec, qos, cm) ::hobbes::storage::StorageGroup<_HSTORE_TSTR(#NAME),cm> NAME = { 0, qos, pagec, -1 } 1700 #define APPLY_HSTORE_STMT(GROUP, NAME, FLAGS, FMTSTR, ARGS...) \ 1701 ::hobbes::storage::write(&GROUP, ({static_assert(::hobbes::storage::maxVarRef(FMTSTR) <= decltype(::hobbes::storage::makePayloadTypes(ARGS))::count, "Log format string and payload arity mismatch"); ::hobbes::storage::StorageStatement<decltype(GROUP),&GROUP,_HSTORE_TSTR(__FILE__),__LINE__,_HSTORE_TSTR(#NAME),FLAGS,_HSTORE_TSTR(FMTSTR),decltype(::hobbes::storage::makePayloadTypes(ARGS))>::id;}), ## ARGS) 1703 #define HSTORE(GROUP, NAME, ARGS...) APPLY_HSTORE_STMT(GROUP, NAME, 0, "", ## ARGS) 1704 #define HLOG(GROUP, NAME, FMTSTR, ARGS...) APPLY_HSTORE_STMT(GROUP, NAME, 1, FMTSTR, ## ARGS) 1716 inline bool isLog()
const {
return (this->flags & 1) == 1; }
1721 if (o + n <= md.second) {
1722 memcpy(b, md.first + o, n);
1729 template <
typename T>
1731 return rs(md, o,
sizeof(T), (uint8_t*)t);
1738 return rs(md, o, n, (uint8_t*)s->data());
1745 return rs(md, o, n, &(*s)[0]);
1750 Transaction(
const uint8_t* data,
size_t datasz) : data(data), datasz(datasz), i(0) {
1754 return (this->i+x) <= this->datasz;
1758 return this->data + this->i;
1765 template <
typename T>
1767 auto p = (
const T*)ptr();
1773 return this->datasz;
1788 uint32_t hstoreVersion = 0;
1789 size_t o =
r(md, 0, &hstoreVersion);
1791 throw std::runtime_error(
"Can't read storage data from incompatible process");
1804 for (
size_t i = 0; i < n; ++i) {
1810 o =
r (md, o, &s.
line);
1811 o =
r (md, o, &s.
id);
1821 static const size_t blockSize = 1024;
1823 size_t i = txn.size();
1824 txn.resize(txn.size() + blockSize);
1826 uint8_t txnFlag = 0;
1827 txn.resize(txn.size() - (blockSize - p.
read(&txn[i], blockSize, &txnFlag)));
static bool write(wpipe &, const std::tuple< Ts... > &)
Definition: storage.H:831
size_t datasz
Definition: storage.H:514
size_t pagesz
Definition: storage.H:515
recursive(const value_type &x)
Definition: storage.H:1192
uint32_t nextIndex(volatile uint32_t *i) const
Definition: storage.H:293
static void encode(size_t f, bytes *out)
Definition: storage.H:796
static bool write(wpipe &p, const std::pair< U, V > &x)
Definition: storage.H:997
static thread_local wpipe * pipe
Definition: storage.H:1514
#define _HSTORE_TYCTOR_RECURSIVE
Definition: storage.H:723
void type
Definition: storage.H:778
int mqconnect(const std::string &fileName)
Definition: storage.H:117
Definition: storage.H:1298
#define _HSTORE_PAGE_STATE_ROLLBACK
Definition: storage.H:406
volatile uint32_t * waitState() const
Definition: storage.H:289
static size_t size(const recursive< T > &x)
Definition: storage.H:1237
std::string sharedMemName(const std::string &groupName, const ProcThread &pt)
Definition: storage.H:219
std::string file
Definition: storage.H:1711
const uint8_t * page
Definition: storage.H:663
const T * read()
Definition: storage.H:1766
Definition: storage.H:415
uint32_t ri
Definition: storage.H:277
uint32_t wstate
Definition: storage.H:276
void mqwrite(int fd, const uint8_t *x, size_t len)
Definition: storage.H:103
void w(const T &x, bytes *out)
Definition: storage.H:729
static bool write(wpipe &p, const T &x)
Definition: storage.H:1042
uint8_t * next()
Definition: storage.H:355
int shmfd
Definition: storage.H:286
void commit()
Definition: storage.H:1565
static bool write(wpipe &p, const T &x, const Ts &... xs)
Definition: storage.H:1648
QueueConnection consumeGroup(const std::string &gname, const ProcThread &pt)
Definition: storage.H:566
static size_t size(const std::pair< U, V > &x)
Definition: storage.H:994
static long sys_futex(volatile uint32_t *p, int op, int v, struct timespec *timeout, void *p2, int v2)
Definition: storage.H:61
static bool write(wpipe &p, const T &x, const Ts &... xs)
Definition: storage.H:811
uint8_t * value(size_t i) const
Definition: storage.H:581
static size_t size(const T &x)
Definition: storage.H:972
static bool write(wpipe &p, const T(&v)[N])
Definition: storage.H:1318
T head_type
Definition: storage.H:1408
#define _HSTORE_STATE_UNBLOCKED
Definition: storage.H:245
void ws(const char *x, bytes *out)
Definition: storage.H:732
static bool write(wpipe &p, const std::vector< T > &xs)
Definition: storage.H:1368
uint32_t offset
Definition: storage.H:665
void encode(const PrimitivePtr &, std::ostream &)
Definition: expr.C:1674
static std::string describe()
Definition: storage.H:1404
static bool write(wpipe &p, const recursion &x)
Definition: storage.H:1219
static void waitForUpdate(volatile uint32_t *p, int eqV)
Definition: storage.H:64
_HSTORE_DEFINE_PRIMTYS(bool, "bool")
size_t count
Definition: storage.H:260
Definition: storage.H:726
static size_t size(const std::tuple< Ts... > &t)
Definition: storage.H:817
static constexpr size_t maxVarRef(const char(&fmt)[N])
Definition: storage.H:1691
static std::string describe()
Definition: storage.H:1269
int mqlisten(const std::string &fileName)
Definition: storage.H:150
Definition: storage.H:571
bool operator==(const unit &) const
Definition: storage.H:1262
static size_t size(const std::tuple< Ts... > &t)
Definition: storage.H:854
T align(T x, T m)
Definition: storage.H:84
void push()
Definition: storage.H:388
hstore_payload_types< Ts... > makePayloadTypes(const Ts &...)
Definition: storage.H:1423
#define _HSTORE_TYCTOR_SIZE
Definition: storage.H:722
static std::string describe()
Definition: storage.H:1306
uint8_t * value(size_t i) const
Definition: storage.H:292
const pqueue_config & config() const
Definition: storage.H:605
static std::string describe()
Definition: storage.H:850
std::string fmtstr
Definition: storage.H:1502
static void encode(bytes *out)
Definition: storage.H:1268
static void encode(bytes *out)
Definition: storage.H:936
~reader()
Definition: storage.H:601
const uint8_t * data
Definition: storage.H:1776
static std::string describe()
Definition: storage.H:788
static size_t size(const std::tuple< Ts... > &)
Definition: storage.H:828
static void encode(bytes *out)
Definition: storage.H:1351
static size_t size(const std::vector< T > &xs)
Definition: storage.H:1353
ProcThread thisProcThread()
Definition: storage.H:207
uint32_t line
Definition: storage.H:1504
static size_t recSize(const recursion &x)
Definition: storage.H:1234
Definition: pattern.H:281
std::pair< std::string, std::string > pair
Definition: str.H:220
Definition: storage.H:1468
pqueue_config(size_t valuesz, size_t count, uint32_t *wstate, uint32_t *ri, uint32_t *wi, uint8_t *data)
Definition: storage.H:254
size_t size() const
Definition: storage.H:1772
#define _HSTORE_STATE_READER_WAITING
Definition: storage.H:246
value_type value
Definition: storage.H:1191
static void encode(bytes *out)
Definition: storage.H:1359
static void encode(bytes *out)
Definition: storage.H:1226
static size_t size(const T &)
Definition: storage.H:1041
recursion(void *x)
Definition: storage.H:1185
static std::string describe()
Definition: storage.H:1177
std::string tempDir()
Definition: storage.H:178
bool write(StorageGroup< GName, AutoCommit > *g, uint32_t id, const Ts &... xs)
Definition: storage.H:1654
static std::string describe()
Definition: storage.H:937
static void encode(bytes *out)
Definition: storage.H:839
writer * wq
Definition: storage.H:417
volatile uint32_t * wstate
Definition: storage.H:261
static size_t size(const std::string &s)
Definition: storage.H:1394
pqueue_config()
Definition: storage.H:250
static size_t size(const T &x)
Definition: storage.H:1292
StorageStatement()
Definition: storage.H:1486
int mqserver
Definition: storage.H:1512
static RecSizeF & sizeF()
Definition: storage.H:1206
Definition: storage.H:1484
volatile uint32_t * readerIndex
Definition: storage.H:262
Definition: storage.H:410
Definition: storage.H:785
static std::string describe()
Definition: storage.H:1418
Definition: storage.H:1639
static uint32_t id
Definition: storage.H:1485
static bool write(wpipe &p, const recursive< T > &x)
Definition: storage.H:1249
volatile uint32_t * writerIndex
Definition: storage.H:263
static void encode(bytes *out)
Definition: storage.H:1039
static size_t size(const std::vector< T > &xs)
Definition: storage.H:1361
Definition: storage.H:275
llvm::Value * offset(llvm::IRBuilder<> *b, llvm::Value *p, llvm::Value *o0)
Definition: llvm.H:419
#define _HSTORE_PAGE_STATE_TENTATIVE
Definition: storage.H:403
bool isLog() const
Definition: storage.H:1716
bool reliable() const
Definition: storage.H:427
std::string shmname
Definition: storage.H:285
void can_memcpy
Definition: storage.H:935
void prepareMeta(bytes *meta)
Definition: storage.H:1521
bool write(StorageGroup< GName, ManualCommit > *g, uint32_t id, const Ts &... xs)
Definition: storage.H:1663
bool write(const uint8_t *src, size_t sz)
Definition: storage.H:472
std::vector< statement > statements
Definition: storage.H:1718
uint32_t wi
Definition: storage.H:278
static bool write(wpipe &p, const std::tuple< Ts... > &t)
Definition: storage.H:821
static void encode(bytes *out)
Definition: storage.H:970
std::map< std::string, StmtData > StorageStatements
Definition: storage.H:1507
Definition: storage.H:1498
uint32_t forceRegistration()
Definition: storage.H:1482
void markPage(uint8_t c)
Definition: storage.H:423
bytes type
Definition: storage.H:1714
CommitMethod
Definition: storage.H:1492
static size_t size(const T(&v)[N])
Definition: storage.H:1315
uint32_t id
Definition: storage.H:1505
static size_t size(const unit &)
Definition: storage.H:1270
static bool write(wpipe &, const unit &)
Definition: storage.H:1271
static std::string describe()
Definition: storage.H:1291
std::vector< uint8_t > bytes
Definition: storage.H:77
rpipe(reader *rq)
Definition: storage.H:667
size_t datasz
Definition: storage.H:1777
std::string file
Definition: storage.H:1503
tydescfn tdesc
Definition: storage.H:1500
Definition: storage.H:1260
static bool write(wpipe &p, const T &x)
Definition: storage.H:1179
uint32_t allocateStorageStatement(const std::string &file, uint32_t line, const std::string &name, size_t flags, const std::string &fmtstr, tydescfn tdesc)
Definition: storage.H:1569
static constexpr size_t maxV(size_t x, size_t y)
Definition: storage.H:1675
StorageStatements * statements
Definition: storage.H:1509
T select(const std::vector< T > &xs, I i)
Definition: array.H:92
#define _HSTORE_PAGE_STATE_COMMIT
Definition: storage.H:405
static size_t size(const Ts &...)
Definition: storage.H:1640
#define _HSTORE_TYCTOR_STRUCT
Definition: storage.H:721
static constexpr size_t readInt(const char(&fmt)[N], size_t i, size_t e, size_t n)
Definition: storage.H:1671
uint32_t unused
Definition: storage.H:279
writer(const bytes &meta, const std::string &shmname, size_t qvalsz, size_t count)
Definition: storage.H:295
bool stepPage()
Definition: storage.H:431
static bool write(wpipe &p, const T &x)
Definition: storage.H:1293
static size_t size(const T &x, const Ts &... xs)
Definition: storage.H:1645
static bool write(wpipe &p, const T(&v)[N])
Definition: storage.H:1332
Definition: storage.H:1189
Definition: storage.H:283
static void encode(bytes *out)
Definition: storage.H:1290
static size_t size(const recursion &x)
Definition: storage.H:1210
void runReadProcess(const QueueConnection &qc, const std::function< std::function< void(Transaction &)>(PipeQOS, CommitMethod, const statements &)> &initF)
Definition: storage.H:1781
Definition: storage.H:411
#define _HSTORE_TYCTOR_TVAR
Definition: storage.H:717
static bool write(wpipe &, const Ts &...)
Definition: storage.H:790
Definition: storage.H:777
uint32_t line
Definition: storage.H:1712
void commit()
Definition: storage.H:458
static std::string str()
Definition: storage.H:1469
static RecWriteF & writeF()
Definition: storage.H:1215
int connectGroupHost(const std::string &groupName)
Definition: storage.H:196
static bool write(wpipe &p, const std::tuple< Ts... > &t)
Definition: storage.H:857
static size_t size(const T &)
Definition: storage.H:938
static size_t size(const T &x, const Ts &... xs)
Definition: storage.H:808
std::string name
Definition: storage.H:1708
static void encode(bytes *out)
Definition: storage.H:1392
size_t read(uint8_t *dst, size_t sz, uint8_t *state)
Definition: storage.H:674
Transaction(const uint8_t *data, size_t datasz)
Definition: storage.H:1750
static constexpr size_t maxVarRefS(const char(&fmt)[N], size_t i, size_t s, size_t vri, size_t maxvr)
Definition: storage.H:1680
uint8_t * data
Definition: storage.H:513
volatile uint32_t * readIndex() const
Definition: storage.H:290
void init()
Definition: storage.H:1561
volatile uint32_t * readIndex() const
Definition: storage.H:579
pqueue_config cfg
Definition: storage.H:576
#define HSTORE_VERSION
Definition: storage.H:75
constexpr size_t at8(size_t i, const char(&s)[N])
Definition: storage.H:1464
static bool recWrite(wpipe &p, const recursion &x)
Definition: storage.H:1246
uint8_t * next()
Definition: storage.H:614
#define _HSTORE_TYCTOR_ARR
Definition: storage.H:719
Definition: storage.H:1707
uint32_t nextIndex(volatile uint32_t *i) const
Definition: storage.H:582
QueueConnection consumeQueue(const std::string &shmname)
Definition: storage.H:518
volatile uint32_t * waitState() const
Definition: storage.H:578
int shfd
Definition: storage.H:512
void makeTyDescF(bytes *e, std::string *d)
Definition: storage.H:1429
uint8_t * page
Definition: storage.H:418
size_t mempages
Definition: storage.H:1511
Definition: storage.H:1499
const uint8_t * ptr() const
Definition: storage.H:1757
size_t r(const reader::MetaData &md, size_t o, T *t)
Definition: storage.H:1730
~writer()
Definition: storage.H:349
#define _HSTORE_UNLIKELY(x)
Definition: storage.H:81
wpipe & out()
Definition: storage.H:1544
Definition: storage.H:511
void registerSHMAlloc(int *mqserver, const std::string &groupName)
Definition: storage.H:229
size_t pagesz
Definition: storage.H:419
static void encode(size_t, bytes *)
Definition: storage.H:1403
Definition: storage.H:660
RunMode config(int argc, const char **argv)
Definition: main.C:91
PipeQOS qos
Definition: storage.H:1510
uint32_t state
Definition: regex.C:372
static bool write(wpipe &p, const T &x)
Definition: storage.H:939
static void encode(bytes *out)
Definition: storage.H:1197
Definition: storage.H:1494
static void encode(size_t, bytes *)
Definition: storage.H:787
Definition: storage.H:1748
static std::string describe()
Definition: storage.H:1386
constexpr size_t at8S(size_t i, size_t k, const char(&s)[N])
Definition: storage.H:1460
size_t rs(const reader::MetaData &md, size_t o, size_t n, uint8_t *b)
Definition: storage.H:1720
void can_memcpy
Definition: storage.H:1038
ExprPtr fn(const str::seq &vns, const ExprPtr &b, const LexicalAnnotation &la)
Definition: expr.H:837
#define out
Definition: netio.H:19
static bool write(wpipe &p, const std::vector< T > &xs)
Definition: storage.H:1354
static std::string describe()
Definition: storage.H:1040
static void encode(bytes *out)
Definition: storage.H:979
static std::string describe()
Definition: storage.H:991
void skip(size_t d)
Definition: storage.H:1761
MetaData meta() const
Definition: storage.H:609
size_t metasz
Definition: storage.H:575
int makeGroupHost(const std::string &groupName)
Definition: storage.H:200
reader(const QueueConnection &qc)
Definition: storage.H:584
static size_t size(const T(&v)[N])
Definition: storage.H:1325
static size_t size(const Ts &...)
Definition: storage.H:789
static size_t size(const char *s)
Definition: storage.H:1387
Definition: storage.H:1493
uint64_t flags
Definition: storage.H:1501
static void encode(size_t f, bytes *out)
Definition: storage.H:1410
PipeQOS qos
Definition: storage.H:421
static std::string describe()
Definition: storage.H:805
std::pair< uint64_t, uint64_t > ProcThread
Definition: storage.H:205
static void encode(bytes *out)
Definition: storage.H:1385
static std::string describe()
Definition: storage.H:971
static bool write(wpipe &, const Ts &...)
Definition: storage.H:1641
void(* tydescfn)(bytes *, std::string *)
Definition: storage.H:1427
uint64_t flags
Definition: storage.H:1709
Definition: storage.H:816
static bool write(wpipe &p, const T &x)
Definition: storage.H:973
uint32_t offset
Definition: storage.H:420
uint8_t * pollNext()
Definition: storage.H:380
const uint8_t * metad
Definition: storage.H:574
reader * rq
Definition: storage.H:662
static void uxchg(volatile uint32_t *px, uint32_t nx)
Definition: storage.H:92
bool canRead(size_t x) const
Definition: storage.H:1753
T value_type
Definition: storage.H:1190
volatile uint32_t * writeIndex() const
Definition: storage.H:580
constexpr char at(size_t i, const char(&s)[N])
Definition: storage.H:1456
unit()
Definition: storage.H:1261
#define _HSTORE_PAGE_STATE_CONT
Definition: storage.H:404
~StorageGroup()
Definition: storage.H:1516
Definition: storage.H:1324
void head_type
Definition: storage.H:1401
size_t i
Definition: storage.H:1778
size_t valuesz
Definition: storage.H:259
static std::string describe()
Definition: storage.H:1201
int shfd
Definition: storage.H:573
#define xchg
Definition: storage.H:100
static void encode(bytes *out)
Definition: storage.H:1299
static bool write(wpipe &p, const char *s)
Definition: storage.H:1388
static size_t size(const T &x)
Definition: storage.H:1178
void pop()
Definition: storage.H:649
MonoTypePtr tuple(const MonoTypes &mtys=MonoTypes())
Definition: type.H:1068
uint32_t id
Definition: storage.H:1713
#define _HSTORE_TYCTOR_PRIM
Definition: storage.H:716
#define _HSTORE_TYCTOR_FIXEDARR
Definition: storage.H:718
#define _HSTORE_LIKELY(x)
Definition: storage.H:80
std::pair< const uint8_t *, size_t > MetaData
Definition: storage.H:608
LexicalAnnotation m(const YYLTYPE &p)
Definition: hexpr.parse.C:127
size_t pagesz
Definition: storage.H:664
static std::string describe()
Definition: storage.H:1393
void encode_primty(const char *tn, bytes *out)
Definition: storage.H:746
pqueue_config cfg
Definition: storage.H:287
wpipe(writer *wq, PipeQOS qos=Reliable)
Definition: storage.H:451
static void wakeN(volatile uint32_t *p, int c)
Definition: storage.H:67
std::string fmtstr
Definition: storage.H:1710
const pqueue_config & config() const
Definition: storage.H:353
static std::string describe()
Definition: storage.H:1360
static void encode(bytes *out)
Definition: storage.H:1176
volatile uint32_t * writeIndex() const
Definition: storage.H:291
bool hasSpaceFor(size_t sz) const
Definition: storage.H:467
#define _HSTORE_STATE_WRITER_WAITING
Definition: storage.H:247
uint8_t * data
Definition: storage.H:264
uint8_t * pollNext()
Definition: storage.H:640
Definition: storage.H:1400
Definition: storage.H:249
Definition: storage.H:1183
PipeQOS
Definition: storage.H:409
static std::string describe()
Definition: storage.H:1231
static bool write(wpipe &p, const std::string &s)
Definition: storage.H:1395
Definition: storage.H:1314
void * value
Definition: storage.H:1184
static std::string describe()
Definition: storage.H:1352