taco-db  0.1.0
tdb_base.h
Go to the documentation of this file.
1 #ifndef TDB_BASE_H
2 #define TDB_BASE_H
12 #include "config.h"
13 
14 // Always prefer the C++ new/delete expressions rather than using malloc except
15 // when one needs aligned_alloc(3) because aligned new is not available until
16 // C++17.
17 #ifdef USE_JEMALLOC
18 # include <jemalloc/jemalloc.h>
19 #else
20 # include <cstdlib>
21 
22 using std::free;
23 
24 // aligned_alloc is not in C++11 but should be available as long as
25 // _ISOC11_SOURCE is defined
26 #ifndef _ISOC11_SOURCE
27 #if __cplusplus >= 201703L
28 using std::aligned_alloc;
29 #else // __cplusplus < 201703L
30 #error "need a working aligned_alloc(3)"
31 #endif // __cplusplus
32 #endif // _ISOC11_SOURCE
33 
34 #endif // USE_JEMALLOC
35 
36 #include <memory>
37 #include <iostream>
38 #include <fstream>
39 #include <cstdlib>
40 #include <cstring>
41 #include <cstddef>
42 #include <cstdint>
43 #include <cstdio>
44 #include <cctype>
45 #include <new>
46 #include <string>
47 #include <vector>
48 #include <utility>
49 #include <functional>
50 #include <limits>
51 
52 #include "base/atomics.h"
53 
54 #include <absl/base/macros.h>
55 #include <absl/memory/memory.h>
56 #include <absl/strings/string_view.h>
57 
58 using std::size_t;
59 using std::ptrdiff_t;
60 using std::uint64_t;
61 using std::int64_t;
62 using std::uint32_t;
63 using std::int32_t;
64 using std::uint16_t;
65 using std::int16_t;
66 using std::int8_t;
67 using std::uint8_t;
68 using std::uintptr_t;
69 using std::intptr_t;
70 
71 using std::static_pointer_cast;
72 using std::dynamic_pointer_cast;
73 using std::const_pointer_cast;
74 #if __cplusplus >= 201703L
75 // this is available starting from C++17
77 #else
78 template<class T, class U>
79 static inline std::shared_ptr<T>
80 reinterpret_pointer_cast(const std::shared_ptr<U>& p) {
81  return std::shared_ptr<T>(p, reinterpret_cast<T*>(p.get()));
82 }
83 #endif
84 
85 namespace AlignedAllocImpl {
86 struct FreeMem {
87  void operator()(void *x) {
88  free(x);
89  }
90 };
91 } // AlignedAllocImpl
92 
93 typedef std::unique_ptr<void, AlignedAllocImpl::FreeMem>
95 
100 inline unique_malloced_ptr
101 unique_aligned_alloc(size_t alignment, size_t size) {
102  return unique_malloced_ptr(aligned_alloc(alignment, size));
103 }
104 
105 inline unique_malloced_ptr
106 wrap_malloc(void *ptr) {
107  return unique_malloced_ptr(ptr);
108 }
109 
110 inline unique_malloced_ptr
111 unique_malloc(size_t size) {
112  return unique_malloced_ptr(malloc(size));
113 }
114 
115 namespace AlignedAllocImpl {
116 
117 template<size_t alignment, class T>
119  typedef T value_type;
120  typedef size_t size_type;
121  typedef ptrdiff_t difference_type;
122 
123  static T*
124  allocate(size_t n) {
125  return (T*) aligned_alloc(alignment, n * sizeof(T));
126  }
127 
128  static void
129  deallocate(T *p, size_t) {
130  free(p);
131  }
132 
133  constexpr bool
135  return true;
136  }
137 
138  constexpr bool
140  return false;
141  }
142 
143  typedef std::true_type is_always_equal;
144 
145  template<class U>
146  struct rebind {
148  };
149 };
150 
151 
152 } // AlignedAllocImpl
153 
155  std::vector<char, AlignedAllocImpl::aligned_allocator<8, char>>;
156 
157 
158 constexpr const size_t CACHELINE_SIZE = L1_CACHELINE_SIZE;
159 constexpr const size_t PAGE_SIZE = CONFIG_PAGE_SIZE;
160 
161 
162 #include "base/logging.h"
163 #include "utils/misc.h"
164 
165 // ASSERT(condition [, <fmtstring> [, <args>]...])
166 //
167 // Assertion is enabled when NDEBUG is not defined. Here we do not use the
168 // standard C assert() macro. Instead, it throws a fatal error so that our
169 // exception handler can catch it and provide better insight rather than an
170 // abort() call.
171 #if (defined(TDB_IN_TEST) && !defined(NDEBUG))
172 // In-test asserts shouldn't add the file location in the log, as they are
173 // always included in the log message.
174 #define ASSERT(...) \
175  do { \
176  bool __cond = (CAR(__VA_ARGS__)); \
177  if (!__cond) { \
178  LOG(::taco::kFatal, \
179  "assertion \"%s\" failed" \
180  IF_NONEMPTY(CADR(__VA_ARGS__), ": " CADR(__VA_ARGS__)), \
181  STRINGIFY(CAR(__VA_ARGS__)) \
182  IF_NONEMPTY_COMMA(CADDR(__VA_ARGS__), ) \
183  CDR(CDR(__VA_ARGS__)) \
184  ); \
185  } \
186  } while (0)
187 #elif (!defined(TDB_IN_TEST) && !defined(NDEBUG))
188 // Non-test assert failure should be a fatal error and needs to log a file
189 // location for debugging
190 #define ASSERT(...) \
191  do { \
192  bool __cond = (CAR(__VA_ARGS__)); \
193  if (!__cond) { \
194  LOG(::taco::kFatal, "%s:" STRINGIFY(__LINE__) \
195  ": assertion \"%s\" failed" \
196  IF_NONEMPTY(CADR(__VA_ARGS__), ": " CADR(__VA_ARGS__)), \
197  ::taco::StripSourcePath(__FILE__), \
198  STRINGIFY(CAR(__VA_ARGS__)) \
199  IF_NONEMPTY_COMMA(CADDR(__VA_ARGS__),) \
200  CDR(CDR(__VA_ARGS__)) \
201  ); \
202  } \
203  } while (0)
204 #else // assert disabled
205 #define ASSERT(...)
206 #endif
207 
208 namespace taco {
209 
210 typedef uint32_t Oid;
211 typedef int16_t FieldOffset;
212 typedef int16_t FieldId;
213 typedef uint32_t PageNumber;
214 typedef uint64_t BufferId;
215 
221 typedef uint32_t FileId;
222 typedef uint16_t SlotId;
223 
224 constexpr Oid InvalidOid = 0;
225 constexpr FieldId InvalidFieldId = 0x7fff;
226 constexpr FieldId MaxNumRegularFieldId = 0x7fff;
227 constexpr int PageNumberBits = 32;
229 static_assert(FieldOffsetBits <= 15, "page size cannot be larger than 2^15");
231 
235 constexpr PageNumber INVALID_PID = 0;
236 
243 
248  (RESERVED_PID == ((((uint64_t) 1) << PageNumberBits) - 1))
249  ? (RESERVED_PID - 2) : ((((uint64_t) 1) << PageNumberBits) - 1);
250 
254 constexpr SlotId INVALID_SID = 0;
255 
259 constexpr SlotId MinSlotId = 1;
260 
264 constexpr SlotId MaxSlotId = (~(SlotId) 0) - 1;
265 
266 constexpr BufferId INVALID_BUFID = ~(BufferId) 0;
267 
268 #define FIELDOFFSET_FORMAT "%hd"
269 #define FIELDID_FORMAT "%hd"
270 #define OID_FORMAT "%u"
271 #define FILEID_FORMAT "%u"
272 #define PAGENUMBER_FORMAT "0x%08X"
273 #define SLOTID_FORMAT "%hu"
274 #define BUFFERID_FORMAT "%lu"
275 
281 constexpr Oid MaxOid = std::numeric_limits<Oid>::max() - 1;
282 
284 typedef uint8_t IdxType;
285 
287 typedef uint8_t OpType;
288 
295 typedef uint8_t AggType;
296 
317 template<class T>
318 constexpr T
319 TYPEALIGN(uint64_t ALIGNVAL, T LEN) {
320  return (((uint64_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64_t) ((ALIGNVAL) - 1)));
321 }
322 
323 #define SHORTALIGN(LEN) TYPEALIGN(2, (LEN))
324 #define INTALIGN(LEN) TYPEALIGN(4, (LEN))
325 #define LONGALIGN(LEN) TYPEALIGN(8, (LEN))
326 #define DOUBLEALIGN(LEN) TYPEALIGN(8, (LEN))
327 #define MAXALIGN(LEN) TYPEALIGN(8, (LEN))
328 #define CACHELINEALIGN(LEN) TYPEALIGN(CACHELINE_SIZE, (LEN))
329 #define MAXALIGN_OF 8
330 
331 template<class T>
332 constexpr T
333 TYPEALIGN_DOWN(uint64_t ALIGNVAL, T LEN) {
334  return (((uint64_t) (LEN)) & ~((uint64_t) ((ALIGNVAL) - 1)));
335 }
336 
337 #define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(2, (LEN))
338 #define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(4, (LEN))
339 #define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(8, (LEN))
340 #define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(8, (LEN))
341 #define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(8, (LEN))
342 #define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(CACHELINE_SIZE, (LEN))
343 
344 template<class T, class U>
345 bool
346 AddWithCheck(T &left, U right) {
347  if ((left > 0 && (T) right > std::numeric_limits<T>::max() - left) ||
348  (left < 0 && (T) right < left - std::numeric_limits<T>::min())) {
349  return false;
350  }
351  left += (T) right;
352  return true;
353 }
354 
361 #define RETURN_IF(...) \
362  do { \
363  if ((CAR(__VA_ARGS__))) { \
364  return CDR(__VA_ARGS__); \
365  } \
366  } while(0)
367 
368 } // namespace taco
369 
375 #define FLEXIBLE_ARRAY_MEMBER -1
376 
377 #include "base/datum.h"
378 #include "base/fmgr.h"
379 
380 template<class T>
381 typename std::enable_if<!std::is_same<typename std::decay<T>::type,
382  absl::string_view>::value,
383  T&&>::type
385  return std::forward<T>(t);
386 }
387 
388 template<class T>
389 typename std::enable_if<std::is_same<typename std::decay<T>::type,
390  absl::string_view>::value,
391  std::string>::type
393  return std::string(t.data(), t.size());
394 }
395 
396 #endif // TDB_BASE_H
This file includes c++11 atomic library.
#define L1_CACHELINE_SIZE
Definition: config.h:8
#define CONFIG_PAGE_SIZE
Definition: config.h:11
This file contains the definition of the Datum and DatumRef structures for storing and passing C++ ob...
This file contains the definition of the function manager and function-call interface,...
Logging component for TDB.
Definition: tdb_base.h:85
Definition: datum.h:28
constexpr int PageNumberBits
Definition: tdb_base.h:227
constexpr Oid InvalidOid
Definition: tdb_base.h:224
uint8_t OpType
The operator type, see expr/optypes.h.
Definition: tdb_base.h:287
uint32_t Oid
Definition: tdb_base.h:210
bool AddWithCheck(T &left, U right)
Definition: tdb_base.h:346
constexpr FieldOffset MaxFieldOffset
Definition: tdb_base.h:230
constexpr SlotId MaxSlotId
The maximum valid slot ID.
Definition: tdb_base.h:264
uint64_t BufferId
Definition: tdb_base.h:214
uint16_t SlotId
Definition: tdb_base.h:222
constexpr SlotId INVALID_SID
The invalid slot ID.
Definition: tdb_base.h:254
int16_t FieldOffset
Definition: tdb_base.h:211
constexpr Oid MaxOid
The largest valid Oid.
Definition: tdb_base.h:281
uint8_t IdxType
The index type, see index/idxtyps.h.
Definition: tdb_base.h:284
int16_t FieldId
Definition: tdb_base.h:212
uint32_t FileId
The file ID.
Definition: tdb_base.h:221
constexpr PageNumber MaxPageNumber
The maximum valid page number.
Definition: tdb_base.h:247
constexpr T TYPEALIGN(uint64_t ALIGNVAL, T LEN)
These alignment macros are derived from PostgreSQL.
Definition: tdb_base.h:319
constexpr int logn_ceil(uint64_t x)
Returns $\lceil log_2(x) \rceil$ for x > 0, or 0 for x = 0.
Definition: misc.h:151
uint32_t PageNumber
Definition: tdb_base.h:213
constexpr SlotId MinSlotId
The minimum valid slot ID.
Definition: tdb_base.h:259
uint8_t AggType
The aggregation type, see catalog/aggtyp.h.
Definition: tdb_base.h:295
constexpr PageNumber RESERVED_PID
An invalid page number reserved for file manager internal use.
Definition: tdb_base.h:242
constexpr FieldId MaxNumRegularFieldId
Definition: tdb_base.h:226
constexpr int FieldOffsetBits
Definition: tdb_base.h:228
constexpr BufferId INVALID_BUFID
Definition: tdb_base.h:266
constexpr T TYPEALIGN_DOWN(uint64_t ALIGNVAL, T LEN)
Definition: tdb_base.h:333
constexpr FieldId InvalidFieldId
Definition: tdb_base.h:225
constexpr PageNumber INVALID_PID
The invalid page number.
Definition: tdb_base.h:235
Definition: tdb_base.h:86
void operator()(void *x)
Definition: tdb_base.h:87
aligned_allocator< alignment, U > other
Definition: tdb_base.h:147
Definition: tdb_base.h:118
std::true_type is_always_equal
Definition: tdb_base.h:143
ptrdiff_t difference_type
Definition: tdb_base.h:121
T value_type
Definition: tdb_base.h:119
constexpr bool operator==(const aligned_allocator &)
Definition: tdb_base.h:134
static T * allocate(size_t n)
Definition: tdb_base.h:124
size_t size_type
Definition: tdb_base.h:120
constexpr bool operator!=(const aligned_allocator &)
Definition: tdb_base.h:139
static void deallocate(T *p, size_t)
Definition: tdb_base.h:129
std::vector< char, AlignedAllocImpl::aligned_allocator< 8, char > > maxaligned_char_buf
Definition: tdb_base.h:155
unique_malloced_ptr unique_aligned_alloc(size_t alignment, size_t size)
Wraps an aligned_alloced'd memory space in a std::unique_ptr.
Definition: tdb_base.h:101
unique_malloced_ptr unique_malloc(size_t size)
Definition: tdb_base.h:111
constexpr const size_t PAGE_SIZE
Definition: tdb_base.h:159
constexpr const size_t CACHELINE_SIZE
Definition: tdb_base.h:158
static std::shared_ptr< T > reinterpret_pointer_cast(const std::shared_ptr< U > &p)
Definition: tdb_base.h:80
std::enable_if<!std::is_same< typename std::decay< T >::type, absl::string_view >::value, T && >::type cast_as_string(T &&t)
Definition: tdb_base.h:384
unique_malloced_ptr wrap_malloc(void *ptr)
Definition: tdb_base.h:106
std::unique_ptr< void, AlignedAllocImpl::FreeMem > unique_malloced_ptr
Definition: tdb_base.h:94