fix compile
[c11concurrency-benchmarks.git] / silo / record / inline_str.h
1 #ifndef _NDB_BENCH_INLINE_STR_H_
2 #define _NDB_BENCH_INLINE_STR_H_
3
4 #include <stdint.h>
5 #include <string.h>
6
7 #include <string>
8 #include <ostream>
9
10 #include "../macros.h"
11 #include "serializer.h"
12
13 // equivalent to VARCHAR(N)
14
15 template <typename IntSizeType, unsigned int N>
16 class inline_str_base {
17   // XXX: argh...
18   template <typename T, bool DoCompress> friend struct serializer;
19 public:
20
21   inline_str_base() : sz(0) {}
22
23   inline_str_base(const char *s)
24   {
25     assign(s);
26   }
27
28   inline_str_base(const char *s, size_t n)
29   {
30     assign(s, n);
31   }
32
33   inline_str_base(const std::string &s)
34   {
35     assign(s);
36   }
37
38   inline_str_base(const inline_str_base &that)
39     : sz(that.sz)
40   {
41     NDB_MEMCPY(&buf[0], &that.buf[0], sz);
42   }
43
44   inline_str_base &
45   operator=(const inline_str_base &that)
46   {
47     if (this == &that)
48       return *this;
49     sz = that.sz;
50     NDB_MEMCPY(&buf[0], &that.buf[0], sz);
51     return *this;
52   }
53
54   inline size_t
55   max_size() const
56   {
57     return N;
58   }
59
60   inline const char *
61   c_str() const
62   {
63     buf[sz] = 0;
64     return &buf[0];
65   }
66
67   inline std::string
68   str(bool zeropad = false) const
69   {
70                 if (zeropad) {
71                         INVARIANT(N >= sz);
72                         std::string r(N, 0);
73                         NDB_MEMCPY((char *) r.data(), &buf[0], sz);
74                         return r;
75                 } else {
76                         return std::string(&buf[0], sz);
77                 }
78   }
79
80   inline ALWAYS_INLINE const char *
81   data() const
82   {
83     return &buf[0];
84   }
85
86   inline ALWAYS_INLINE size_t
87   size() const
88   {
89     return sz;
90   }
91
92   inline ALWAYS_INLINE void
93   assign(const char *s)
94   {
95     assign(s, strlen(s));
96   }
97
98   inline void
99   assign(const char *s, size_t n)
100   {
101     INVARIANT(n <= N);
102     NDB_MEMCPY(&buf[0], s, n);
103     sz = n;
104   }
105
106   inline ALWAYS_INLINE void
107   assign(const std::string &s)
108   {
109     assign(s.data(), s.size());
110   }
111
112   inline void
113   resize(size_t n, char c = 0)
114   {
115     INVARIANT(n <= N);
116     if (n > sz)
117       NDB_MEMSET(&buf[sz], c, n - sz);
118     sz = n;
119   }
120
121   inline void
122   resize_junk(size_t n)
123   {
124     INVARIANT(n <= N);
125     sz = n;
126   }
127
128   inline bool
129   operator==(const inline_str_base &other) const
130   {
131     return memcmp(buf, other.buf, sz) == 0;
132   }
133
134   inline bool
135   operator!=(const inline_str_base &other) const
136   {
137     return !operator==(other);
138   }
139
140 private:
141   IntSizeType sz;
142   mutable char buf[N + 1];
143 } PACKED;
144
145 template <typename IntSizeType, unsigned int N>
146 inline std::ostream &
147 operator<<(std::ostream &o, const inline_str_base<IntSizeType, N> &s)
148 {
149   o << std::string(s.data(), s.size());
150   return o;
151 }
152
153 template <unsigned int N>
154 class inline_str_8 : public inline_str_base<uint8_t, N> {
155   typedef inline_str_base<uint8_t, N> super_type;
156 public:
157   inline_str_8() : super_type() {}
158   inline_str_8(const char *s) : super_type(s) {}
159   inline_str_8(const char *s, size_t n) : super_type(s, n) {}
160   inline_str_8(const std::string &s) : super_type(s) {}
161 } PACKED;
162
163 template <unsigned int N>
164 class inline_str_16 : public inline_str_base<uint16_t, N> {
165   typedef inline_str_base<uint16_t, N> super_type;
166 public:
167   inline_str_16() : super_type() {}
168   inline_str_16(const char *s) : super_type(s) {}
169   inline_str_16(const char *s, size_t n) : super_type(s, n) {}
170   inline_str_16(const std::string &s) : super_type(s) {}
171 } PACKED;
172
173 // equiavlent to CHAR(N)
174 template <unsigned int N, char FillChar = ' '>
175 class inline_str_fixed {
176   // XXX: argh...
177   template <typename T, bool DoCompress> friend struct serializer;
178 public:
179   inline_str_fixed()
180   {
181     NDB_MEMSET(&buf[0], FillChar, N);
182   }
183
184   inline_str_fixed(const char *s)
185   {
186     assign(s, strlen(s));
187   }
188
189   inline_str_fixed(const char *s, size_t n)
190   {
191     assign(s, n);
192   }
193
194   inline_str_fixed(const std::string &s)
195   {
196     assign(s.data(), s.size());
197   }
198
199   inline_str_fixed(const inline_str_fixed &that)
200   {
201     NDB_MEMCPY(&buf[0], &that.buf[0], N);
202   }
203
204   inline_str_fixed &
205   operator=(const inline_str_fixed &that)
206   {
207     if (this == &that)
208       return *this;
209     NDB_MEMCPY(&buf[0], &that.buf[0], N);
210     return *this;
211   }
212
213   inline ALWAYS_INLINE std::string
214   str() const
215   {
216     return std::string(&buf[0], N);
217   }
218
219   inline ALWAYS_INLINE const char *
220   data() const
221   {
222     return &buf[0];
223   }
224
225   inline ALWAYS_INLINE size_t
226   size() const
227   {
228     return N;
229   }
230
231   inline ALWAYS_INLINE void
232   assign(const char *s)
233   {
234     assign(s, strlen(s));
235   }
236
237   inline void
238   assign(const char *s, size_t n)
239   {
240     INVARIANT(n <= N);
241     NDB_MEMCPY(&buf[0], s, n);
242     if ((N - n) > 0) // to suppress compiler warning
243       NDB_MEMSET(&buf[n], FillChar, N - n); // pad with spaces
244   }
245
246   inline ALWAYS_INLINE void
247   assign(const std::string &s)
248   {
249     assign(s.data(), s.size());
250   }
251
252   inline bool
253   operator==(const inline_str_fixed &other) const
254   {
255     return memcmp(buf, other.buf, N) == 0;
256   }
257
258   inline bool
259   operator!=(const inline_str_fixed &other) const
260   {
261     return !operator==(other);
262   }
263
264 private:
265   char buf[N];
266 } PACKED;
267
268 template <unsigned int N, char FillChar>
269 inline std::ostream &
270 operator<<(std::ostream &o, const inline_str_fixed<N, FillChar> &s)
271 {
272   o << std::string(s.data(), s.size());
273   return o;
274 }
275
276 // serializer<T> specialization
277 template <typename IntSizeType, unsigned int N, bool Compress>
278 struct serializer< inline_str_base<IntSizeType, N>, Compress > {
279   typedef inline_str_base<IntSizeType, N> obj_type;
280   static inline uint8_t *
281   write(uint8_t *buf, const obj_type &obj)
282   {
283     buf = serializer<IntSizeType, Compress>::write(buf, &obj.sz);
284     NDB_MEMCPY(buf, &obj.buf[0], obj.sz);
285     return buf + obj.sz;
286   }
287
288   static const uint8_t *
289   read(const uint8_t *buf, obj_type *obj)
290   {
291     buf = serializer<IntSizeType, Compress>::read(buf, &obj->sz);
292     NDB_MEMCPY(&obj->buf[0], buf, obj->sz);
293     return buf + obj->sz;
294   }
295
296   static const uint8_t *
297   failsafe_read(const uint8_t *buf, size_t nbytes, obj_type *obj)
298   {
299     const uint8_t * const hdrbuf =
300       serializer<IntSizeType, Compress>::failsafe_read(buf, nbytes, &obj->sz);
301     if (unlikely(!hdrbuf))
302       return nullptr;
303     nbytes -= (hdrbuf - buf);
304     if (nbytes < obj->sz)
305       return nullptr;
306     buf = hdrbuf;
307     NDB_MEMCPY(&obj->buf[0], buf, obj->sz);
308     return buf + obj->sz;
309   }
310
311   static inline size_t
312   nbytes(const obj_type *obj)
313   {
314     return serializer<IntSizeType, Compress>::nbytes(&obj->sz) + obj->sz;
315   }
316
317   static inline size_t
318   skip(const uint8_t *stream, uint8_t *oldv)
319   {
320     IntSizeType sz = 0;
321     const uint8_t * const body = serializer<IntSizeType, Compress>::read(stream, &sz);
322     const size_t totalsz = (body - stream) + sz;
323     if (oldv)
324       NDB_MEMCPY(oldv, stream, totalsz);
325     return totalsz;
326   }
327
328   static inline size_t
329   failsafe_skip(const uint8_t *stream, size_t nbytes, uint8_t *oldv)
330   {
331     IntSizeType sz = 0;
332     const uint8_t * const body =
333       serializer<IntSizeType, Compress>::failsafe_read(stream, nbytes, &sz);
334     if (unlikely(!body))
335       return 0;
336     nbytes -= (body - stream);
337     if (unlikely(nbytes < sz))
338       return 0;
339     const size_t totalsz = (body - stream) + sz;
340     if (oldv)
341       NDB_MEMCPY(oldv, stream, totalsz);
342     return totalsz;
343   }
344
345   static inline constexpr size_t
346   max_nbytes()
347   {
348     return serializer<IntSizeType, Compress>::max_bytes() + N;
349   }
350 };
351
352 #endif /* _NDB_BENCH_INLINE_STR_H_ */