edit scripts
[c11concurrency-benchmarks.git] / silo / varkey.h
1 #ifndef _NDB_VARKEY_H_
2 #define _NDB_VARKEY_H_
3
4 #include <endian.h>
5 #include <stdint.h>
6 #include <string.h>
7
8 #include <iostream>
9 #include <string>
10 #include <type_traits>
11 #include <limits>
12
13 #include "imstring.h"
14 #include "macros.h"
15 #include "util.h"
16
17 #if NDB_MASSTREE
18 #include "prefetch.h"
19 #include "masstree/config.h"
20 #include "masstree/string_slice.hh"
21 #endif
22
23 class varkey {
24   friend std::ostream &operator<<(std::ostream &o, const varkey &k);
25 public:
26   inline varkey() : p(NULL), l(0) {}
27   inline varkey(const varkey &that) = default;
28   inline varkey(varkey &&that) = default;
29   inline varkey &operator=(const varkey &that) = default;
30
31   inline varkey(const uint8_t *p, size_t l)
32     : p(p), l(l)
33   {
34   }
35
36   explicit inline varkey(const std::string &s)
37     : p((const uint8_t *) s.data()), l(s.size())
38   {
39   }
40
41   explicit inline varkey(const char *s)
42     : p((const uint8_t *) s), l(strlen(s))
43   {
44   }
45
46   explicit inline varkey(const imstring &s)
47     : p(s.data()), l(s.size())
48   {
49   }
50
51   inline bool
52   operator==(const varkey &that) const
53   {
54     if (size() != that.size())
55       return false;
56     return memcmp(data(), that.data(), size()) == 0;
57   }
58
59   inline bool
60   operator!=(const varkey &that) const
61   {
62     return !operator==(that);
63   }
64
65   inline bool
66   operator<(const varkey &that) const
67   {
68     int r = memcmp(data(), that.data(), std::min(size(), that.size()));
69     return r < 0 || (r == 0 && size() < that.size());
70   }
71
72   inline bool
73   operator>=(const varkey &that) const
74   {
75     return !operator<(that);
76   }
77
78   inline bool
79   operator<=(const varkey &that) const
80   {
81     int r = memcmp(data(), that.data(), std::min(size(), that.size()));
82     return r < 0 || (r == 0 && size() <= that.size());
83   }
84
85   inline bool
86   operator>(const varkey &that) const
87   {
88     return !operator<=(that);
89   }
90
91   inline uint64_t
92   slice() const
93   {
94     uint64_t ret = 0;
95     uint8_t *rp = (uint8_t *) &ret;
96     for (size_t i = 0; i < std::min(l, size_t(8)); i++)
97       rp[i] = p[i];
98     return util::host_endian_trfm<uint64_t>()(ret);
99   }
100
101 #if NDB_MASSTREE
102   inline uint64_t slice_at(int pos) const {
103     return string_slice<uint64_t>::make_comparable((const char*) p + pos, std::min(int(l - pos), 8));
104   }
105 #endif
106
107   inline varkey
108   shift() const
109   {
110     INVARIANT(l >= 8);
111     return varkey(p + 8, l - 8);
112   }
113
114   inline varkey
115   shift_many(size_t n) const
116   {
117     INVARIANT(l >= 8 * n);
118     return varkey(p + 8 * n, l - 8 * n);
119   }
120
121   inline size_t
122   size() const
123   {
124     return l;
125   }
126
127   inline int length() const {
128     return l;
129   }
130
131   inline const uint8_t *
132   data() const
133   {
134     return p;
135   }
136
137   inline
138   std::string str() const
139   {
140     return std::string((const char *) p, l);
141   }
142
143   inline std::string &
144   str(std::string &buf) const
145   {
146     buf.assign((const char *) p, l);
147     return buf;
148   }
149
150 #if NDB_MASSTREE
151   inline operator lcdf::Str() const {
152     return lcdf::Str(p, l);
153   }
154 #endif
155
156 private:
157   const uint8_t *p;
158   size_t l;
159 };
160
161 inline std::ostream &
162 operator<<(std::ostream &o, const varkey &k)
163 {
164   o << util::hexify(k.str());
165   return o;
166 }
167
168 template <bool is_signed, typename T>
169 struct signed_aware_trfm {};
170
171 template <typename T>
172 struct signed_aware_trfm<false, T> {
173   inline ALWAYS_INLINE T operator()(T t) const { return t; }
174 };
175
176 template <typename T>
177 struct signed_aware_trfm<true, T> {
178   typedef T signed_type;
179   typedef
180     typename std::enable_if<std::is_signed<T>::value, typename std::make_unsigned<T>::type>::type
181     unsigned_type;
182   inline ALWAYS_INLINE unsigned_type
183   operator()(signed_type s) const
184   {
185     const unsigned_type offset = -std::numeric_limits<signed_type>::min();
186     const unsigned_type converted = static_cast<unsigned_type>(s) + offset;
187     return converted;
188   }
189 };
190
191 template <typename T,
192           typename EncodingTrfm = signed_aware_trfm<std::is_signed<T>::value, T>,
193           typename ByteTrfm = util::big_endian_trfm<T> >
194 class obj_varkey : public varkey {
195 public:
196
197   typedef
198     typename std::enable_if<std::is_integral<T>::value, T>::type
199     integral_type;
200
201   inline obj_varkey() : varkey(), obj() {}
202
203   inline obj_varkey(integral_type t)
204     : varkey((const uint8_t *) &obj, sizeof(integral_type)),
205       obj(ByteTrfm()(EncodingTrfm()(t)))
206   {
207   }
208
209 private:
210   integral_type obj;
211 };
212
213 typedef obj_varkey<uint8_t>  u8_varkey;
214 typedef obj_varkey<int8_t>   s8_varkey;
215 typedef obj_varkey<uint16_t> u16_varkey;
216 typedef obj_varkey<int16_t>  s16_varkey;
217 typedef obj_varkey<uint32_t> u32_varkey;
218 typedef obj_varkey<int32_t>  s32_varkey;
219 typedef obj_varkey<uint64_t> u64_varkey;
220 typedef obj_varkey<int64_t>  s64_varkey;
221
222 #endif /* _NDB_VARKEY_H_ */