benchmark silo added
[c11concurrency-benchmarks.git] / silo / record / inline_str.h
diff --git a/silo/record/inline_str.h b/silo/record/inline_str.h
new file mode 100644 (file)
index 0000000..c44cb5f
--- /dev/null
@@ -0,0 +1,352 @@
+#ifndef _NDB_BENCH_INLINE_STR_H_
+#define _NDB_BENCH_INLINE_STR_H_
+
+#include <stdint.h>
+#include <string.h>
+
+#include <string>
+#include <ostream>
+
+#include "../macros.h"
+#include "serializer.h"
+
+// equivalent to VARCHAR(N)
+
+template <typename IntSizeType, unsigned int N>
+class inline_str_base {
+  // XXX: argh...
+  template <typename T, bool DoCompress> friend class serializer;
+public:
+
+  inline_str_base() : sz(0) {}
+
+  inline_str_base(const char *s)
+  {
+    assign(s);
+  }
+
+  inline_str_base(const char *s, size_t n)
+  {
+    assign(s, n);
+  }
+
+  inline_str_base(const std::string &s)
+  {
+    assign(s);
+  }
+
+  inline_str_base(const inline_str_base &that)
+    : sz(that.sz)
+  {
+    NDB_MEMCPY(&buf[0], &that.buf[0], sz);
+  }
+
+  inline_str_base &
+  operator=(const inline_str_base &that)
+  {
+    if (this == &that)
+      return *this;
+    sz = that.sz;
+    NDB_MEMCPY(&buf[0], &that.buf[0], sz);
+    return *this;
+  }
+
+  inline size_t
+  max_size() const
+  {
+    return N;
+  }
+
+  inline const char *
+  c_str() const
+  {
+    buf[sz] = 0;
+    return &buf[0];
+  }
+
+  inline std::string
+  str(bool zeropad = false) const
+  {
+               if (zeropad) {
+                       INVARIANT(N >= sz);
+                       std::string r(N, 0);
+                       NDB_MEMCPY((char *) r.data(), &buf[0], sz);
+                       return r;
+               } else {
+                       return std::string(&buf[0], sz);
+               }
+  }
+
+  inline ALWAYS_INLINE const char *
+  data() const
+  {
+    return &buf[0];
+  }
+
+  inline ALWAYS_INLINE size_t
+  size() const
+  {
+    return sz;
+  }
+
+  inline ALWAYS_INLINE void
+  assign(const char *s)
+  {
+    assign(s, strlen(s));
+  }
+
+  inline void
+  assign(const char *s, size_t n)
+  {
+    INVARIANT(n <= N);
+    NDB_MEMCPY(&buf[0], s, n);
+    sz = n;
+  }
+
+  inline ALWAYS_INLINE void
+  assign(const std::string &s)
+  {
+    assign(s.data(), s.size());
+  }
+
+  inline void
+  resize(size_t n, char c = 0)
+  {
+    INVARIANT(n <= N);
+    if (n > sz)
+      NDB_MEMSET(&buf[sz], c, n - sz);
+    sz = n;
+  }
+
+  inline void
+  resize_junk(size_t n)
+  {
+    INVARIANT(n <= N);
+    sz = n;
+  }
+
+  inline bool
+  operator==(const inline_str_base &other) const
+  {
+    return memcmp(buf, other.buf, sz) == 0;
+  }
+
+  inline bool
+  operator!=(const inline_str_base &other) const
+  {
+    return !operator==(other);
+  }
+
+private:
+  IntSizeType sz;
+  mutable char buf[N + 1];
+} PACKED;
+
+template <typename IntSizeType, unsigned int N>
+inline std::ostream &
+operator<<(std::ostream &o, const inline_str_base<IntSizeType, N> &s)
+{
+  o << std::string(s.data(), s.size());
+  return o;
+}
+
+template <unsigned int N>
+class inline_str_8 : public inline_str_base<uint8_t, N> {
+  typedef inline_str_base<uint8_t, N> super_type;
+public:
+  inline_str_8() : super_type() {}
+  inline_str_8(const char *s) : super_type(s) {}
+  inline_str_8(const char *s, size_t n) : super_type(s, n) {}
+  inline_str_8(const std::string &s) : super_type(s) {}
+} PACKED;
+
+template <unsigned int N>
+class inline_str_16 : public inline_str_base<uint16_t, N> {
+  typedef inline_str_base<uint16_t, N> super_type;
+public:
+  inline_str_16() : super_type() {}
+  inline_str_16(const char *s) : super_type(s) {}
+  inline_str_16(const char *s, size_t n) : super_type(s, n) {}
+  inline_str_16(const std::string &s) : super_type(s) {}
+} PACKED;
+
+// equiavlent to CHAR(N)
+template <unsigned int N, char FillChar = ' '>
+class inline_str_fixed {
+  // XXX: argh...
+  template <typename T, bool DoCompress> friend class serializer;
+public:
+  inline_str_fixed()
+  {
+    NDB_MEMSET(&buf[0], FillChar, N);
+  }
+
+  inline_str_fixed(const char *s)
+  {
+    assign(s, strlen(s));
+  }
+
+  inline_str_fixed(const char *s, size_t n)
+  {
+    assign(s, n);
+  }
+
+  inline_str_fixed(const std::string &s)
+  {
+    assign(s.data(), s.size());
+  }
+
+  inline_str_fixed(const inline_str_fixed &that)
+  {
+    NDB_MEMCPY(&buf[0], &that.buf[0], N);
+  }
+
+  inline_str_fixed &
+  operator=(const inline_str_fixed &that)
+  {
+    if (this == &that)
+      return *this;
+    NDB_MEMCPY(&buf[0], &that.buf[0], N);
+    return *this;
+  }
+
+  inline ALWAYS_INLINE std::string
+  str() const
+  {
+    return std::string(&buf[0], N);
+  }
+
+  inline ALWAYS_INLINE const char *
+  data() const
+  {
+    return &buf[0];
+  }
+
+  inline ALWAYS_INLINE size_t
+  size() const
+  {
+    return N;
+  }
+
+  inline ALWAYS_INLINE void
+  assign(const char *s)
+  {
+    assign(s, strlen(s));
+  }
+
+  inline void
+  assign(const char *s, size_t n)
+  {
+    INVARIANT(n <= N);
+    NDB_MEMCPY(&buf[0], s, n);
+    if ((N - n) > 0) // to suppress compiler warning
+      NDB_MEMSET(&buf[n], FillChar, N - n); // pad with spaces
+  }
+
+  inline ALWAYS_INLINE void
+  assign(const std::string &s)
+  {
+    assign(s.data(), s.size());
+  }
+
+  inline bool
+  operator==(const inline_str_fixed &other) const
+  {
+    return memcmp(buf, other.buf, N) == 0;
+  }
+
+  inline bool
+  operator!=(const inline_str_fixed &other) const
+  {
+    return !operator==(other);
+  }
+
+private:
+  char buf[N];
+} PACKED;
+
+template <unsigned int N, char FillChar>
+inline std::ostream &
+operator<<(std::ostream &o, const inline_str_fixed<N, FillChar> &s)
+{
+  o << std::string(s.data(), s.size());
+  return o;
+}
+
+// serializer<T> specialization
+template <typename IntSizeType, unsigned int N, bool Compress>
+struct serializer< inline_str_base<IntSizeType, N>, Compress > {
+  typedef inline_str_base<IntSizeType, N> obj_type;
+  static inline uint8_t *
+  write(uint8_t *buf, const obj_type &obj)
+  {
+    buf = serializer<IntSizeType, Compress>::write(buf, &obj.sz);
+    NDB_MEMCPY(buf, &obj.buf[0], obj.sz);
+    return buf + obj.sz;
+  }
+
+  static const uint8_t *
+  read(const uint8_t *buf, obj_type *obj)
+  {
+    buf = serializer<IntSizeType, Compress>::read(buf, &obj->sz);
+    NDB_MEMCPY(&obj->buf[0], buf, obj->sz);
+    return buf + obj->sz;
+  }
+
+  static const uint8_t *
+  failsafe_read(const uint8_t *buf, size_t nbytes, obj_type *obj)
+  {
+    const uint8_t * const hdrbuf =
+      serializer<IntSizeType, Compress>::failsafe_read(buf, nbytes, &obj->sz);
+    if (unlikely(!hdrbuf))
+      return nullptr;
+    nbytes -= (hdrbuf - buf);
+    if (nbytes < obj->sz)
+      return nullptr;
+    buf = hdrbuf;
+    NDB_MEMCPY(&obj->buf[0], buf, obj->sz);
+    return buf + obj->sz;
+  }
+
+  static inline size_t
+  nbytes(const obj_type *obj)
+  {
+    return serializer<IntSizeType, Compress>::nbytes(&obj->sz) + obj->sz;
+  }
+
+  static inline size_t
+  skip(const uint8_t *stream, uint8_t *oldv)
+  {
+    IntSizeType sz = 0;
+    const uint8_t * const body = serializer<IntSizeType, Compress>::read(stream, &sz);
+    const size_t totalsz = (body - stream) + sz;
+    if (oldv)
+      NDB_MEMCPY(oldv, stream, totalsz);
+    return totalsz;
+  }
+
+  static inline size_t
+  failsafe_skip(const uint8_t *stream, size_t nbytes, uint8_t *oldv)
+  {
+    IntSizeType sz = 0;
+    const uint8_t * const body =
+      serializer<IntSizeType, Compress>::failsafe_read(stream, nbytes, &sz);
+    if (unlikely(!body))
+      return 0;
+    nbytes -= (body - stream);
+    if (unlikely(nbytes < sz))
+      return 0;
+    const size_t totalsz = (body - stream) + sz;
+    if (oldv)
+      NDB_MEMCPY(oldv, stream, totalsz);
+    return totalsz;
+  }
+
+  static inline constexpr size_t
+  max_nbytes()
+  {
+    return serializer<IntSizeType, Compress>::max_bytes() + N;
+  }
+};
+
+#endif /* _NDB_BENCH_INLINE_STR_H_ */