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 namespace taco {
94 template<class T>
95 constexpr T TYPEALIGN(uint64_t ALIGNVAL, T LEN);
96 }
97 
98 typedef std::unique_ptr<void, AlignedAllocImpl::FreeMem>
100 
105 inline unique_malloced_ptr
106 unique_aligned_alloc(size_t alignment, size_t size) {
107  return unique_malloced_ptr(aligned_alloc(alignment,
108  taco::TYPEALIGN(alignment, size)));
109 }
110 
111 inline unique_malloced_ptr
112 wrap_malloc(void *ptr) {
113  return unique_malloced_ptr(ptr);
114 }
115 
116 inline unique_malloced_ptr
117 unique_malloc(size_t size) {
118  return unique_malloced_ptr(malloc(size));
119 }
120 
121 namespace AlignedAllocImpl {
122 
123 template<size_t alignment, class T>
125  typedef T value_type;
126  typedef size_t size_type;
127  typedef ptrdiff_t difference_type;
128 
129  static T*
130  allocate(size_t n) {
131  return (T*) aligned_alloc(alignment, taco::TYPEALIGN(alignment, n * sizeof(T)));
132  }
133 
134  static void
135  deallocate(T *p, size_t) {
136  free(p);
137  }
138 
139  constexpr bool
141  return true;
142  }
143 
144  constexpr bool
146  return false;
147  }
148 
149  typedef std::true_type is_always_equal;
150 
151  template<class U>
152  struct rebind {
154  };
155 };
156 
157 
158 } // AlignedAllocImpl
159 
161  std::vector<char, AlignedAllocImpl::aligned_allocator<8, char>>;
162 
163 
164 constexpr const size_t CACHELINE_SIZE = L1_CACHELINE_SIZE;
165 constexpr const size_t PAGE_SIZE = CONFIG_PAGE_SIZE;
166 
167 
168 #include "base/logging.h"
169 #include "utils/misc.h"
170 
171 // ASSERT(condition [, <fmtstring> [, <args>]...])
172 //
173 // Assertion is enabled when NDEBUG is not defined. Here we do not use the
174 // standard C assert() macro. Instead, it throws a fatal error so that our
175 // exception handler can catch it and provide better insight rather than an
176 // abort() call.
177 #if (defined(TDB_IN_TEST) && !defined(NDEBUG))
178 // In-test asserts shouldn't add the file location in the log, as they are
179 // always included in the log message.
180 #define ASSERT(...) \
181  do { \
182  bool __cond = (CAR(__VA_ARGS__)); \
183  if (!__cond) { \
184  LOG(::taco::kFatal, \
185  "assertion \"%s\" failed" \
186  IF_NONEMPTY(CADR(__VA_ARGS__), ": " CADR(__VA_ARGS__)), \
187  STRINGIFY(CAR(__VA_ARGS__)) \
188  IF_NONEMPTY_COMMA(CADDR(__VA_ARGS__), ) \
189  CDR(CDR(__VA_ARGS__)) \
190  ); \
191  } \
192  } while (0)
193 #elif (!defined(TDB_IN_TEST) && !defined(NDEBUG))
194 // Non-test assert failure should be a fatal error and needs to log a file
195 // location for debugging
196 #define ASSERT(...) \
197  do { \
198  bool __cond = (CAR(__VA_ARGS__)); \
199  if (!__cond) { \
200  LOG(::taco::kFatal, "%s:" STRINGIFY(__LINE__) \
201  ": assertion \"%s\" failed" \
202  IF_NONEMPTY(CADR(__VA_ARGS__), ": " CADR(__VA_ARGS__)), \
203  ::taco::StripSourcePath(__FILE__), \
204  STRINGIFY(CAR(__VA_ARGS__)) \
205  IF_NONEMPTY_COMMA(CADDR(__VA_ARGS__),) \
206  CDR(CDR(__VA_ARGS__)) \
207  ); \
208  } \
209  } while (0)
210 #else // assert disabled
211 #define ASSERT(...)
212 #endif
213 
214 namespace taco {
215 
216 typedef uint32_t Oid;
217 typedef int16_t FieldOffset;
218 typedef int16_t FieldId;
219 typedef uint32_t PageNumber;
220 typedef uint64_t BufferId;
221 
227 typedef uint32_t FileId;
228 typedef uint16_t SlotId;
229 
230 constexpr Oid InvalidOid = 0;
231 constexpr FieldId InvalidFieldId = 0x7fff;
232 constexpr FieldId MaxNumRegularFieldId = 0x7fff;
233 constexpr int PageNumberBits = 32;
235 static_assert(FieldOffsetBits <= 15, "page size cannot be larger than 2^15");
237 
241 constexpr PageNumber INVALID_PID = 0;
242 
249 
254  (RESERVED_PID == ((((uint64_t) 1) << PageNumberBits) - 1))
255  ? (RESERVED_PID - 2) : ((((uint64_t) 1) << PageNumberBits) - 1);
256 
260 constexpr SlotId INVALID_SID = 0;
261 
265 constexpr SlotId MinSlotId = 1;
266 
270 constexpr SlotId MaxSlotId = (~(SlotId) 0) - 1;
271 
272 constexpr BufferId INVALID_BUFID = ~(BufferId) 0;
273 
274 #define FIELDOFFSET_FORMAT "%hd"
275 #define FIELDID_FORMAT "%hd"
276 #define OID_FORMAT "%u"
277 #define FILEID_FORMAT "%u"
278 #define PAGENUMBER_FORMAT "0x%08X"
279 #define SLOTID_FORMAT "%hu"
280 #define BUFFERID_FORMAT "%lu"
281 
287 constexpr Oid MaxOid = std::numeric_limits<Oid>::max() - 1;
288 
290 typedef uint8_t IdxType;
291 
293 typedef uint8_t OpType;
294 
301 typedef uint8_t AggType;
302 
323 template<class T>
324 constexpr T
325 TYPEALIGN(uint64_t ALIGNVAL, T LEN) {
326  return (((uint64_t) (LEN) + ((ALIGNVAL) - 1)) & ~((uint64_t) ((ALIGNVAL) - 1)));
327 }
328 
329 #define SHORTALIGN(LEN) TYPEALIGN(2, (LEN))
330 #define INTALIGN(LEN) TYPEALIGN(4, (LEN))
331 #define LONGALIGN(LEN) TYPEALIGN(8, (LEN))
332 #define DOUBLEALIGN(LEN) TYPEALIGN(8, (LEN))
333 #define MAXALIGN(LEN) TYPEALIGN(8, (LEN))
334 #define CACHELINEALIGN(LEN) TYPEALIGN(CACHELINE_SIZE, (LEN))
335 #define MAXALIGN_OF 8
336 
337 template<class T>
338 constexpr T
339 TYPEALIGN_DOWN(uint64_t ALIGNVAL, T LEN) {
340  return (((uint64_t) (LEN)) & ~((uint64_t) ((ALIGNVAL) - 1)));
341 }
342 
343 #define SHORTALIGN_DOWN(LEN) TYPEALIGN_DOWN(2, (LEN))
344 #define INTALIGN_DOWN(LEN) TYPEALIGN_DOWN(4, (LEN))
345 #define LONGALIGN_DOWN(LEN) TYPEALIGN_DOWN(8, (LEN))
346 #define DOUBLEALIGN_DOWN(LEN) TYPEALIGN_DOWN(8, (LEN))
347 #define MAXALIGN_DOWN(LEN) TYPEALIGN_DOWN(8, (LEN))
348 #define BUFFERALIGN_DOWN(LEN) TYPEALIGN_DOWN(CACHELINE_SIZE, (LEN))
349 
350 template<class T, class U>
351 bool
352 AddWithCheck(T &left, U right) {
353  if ((left > 0 && (T) right > std::numeric_limits<T>::max() - left) ||
354  (left < 0 && (T) right < left - std::numeric_limits<T>::min())) {
355  return false;
356  }
357  left += (T) right;
358  return true;
359 }
360 
367 #define RETURN_IF(...) \
368  do { \
369  if ((CAR(__VA_ARGS__))) { \
370  return CDR(__VA_ARGS__); \
371  } \
372  } while(0)
373 
374 } // namespace taco
375 
381 #define FLEXIBLE_ARRAY_MEMBER -1
382 
383 #include "base/datum.h"
384 #include "base/fmgr.h"
385 
386 template<class T>
387 typename std::enable_if<!std::is_same<typename std::decay<T>::type,
388  absl::string_view>::value,
389  T&&>::type
391  return std::forward<T>(t);
392 }
393 
394 template<class T>
395 typename std::enable_if<std::is_same<typename std::decay<T>::type,
396  absl::string_view>::value,
397  std::string>::type
399  return std::string(t.data(), t.size());
400 }
401 
402 #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:233
constexpr Oid InvalidOid
Definition: tdb_base.h:230
uint8_t OpType
The operator type, see expr/optypes.h.
Definition: tdb_base.h:293
uint32_t Oid
Definition: tdb_base.h:216
bool AddWithCheck(T &left, U right)
Definition: tdb_base.h:352
constexpr FieldOffset MaxFieldOffset
Definition: tdb_base.h:236
constexpr SlotId MaxSlotId
The maximum valid slot ID.
Definition: tdb_base.h:270
uint64_t BufferId
Definition: tdb_base.h:220
uint16_t SlotId
Definition: tdb_base.h:228
constexpr SlotId INVALID_SID
The invalid slot ID.
Definition: tdb_base.h:260
int16_t FieldOffset
Definition: tdb_base.h:217
constexpr Oid MaxOid
The largest valid Oid.
Definition: tdb_base.h:287
uint8_t IdxType
The index type, see index/idxtyps.h.
Definition: tdb_base.h:290
int16_t FieldId
Definition: tdb_base.h:218
uint32_t FileId
The file ID.
Definition: tdb_base.h:227
constexpr PageNumber MaxPageNumber
The maximum valid page number.
Definition: tdb_base.h:253
constexpr T TYPEALIGN(uint64_t ALIGNVAL, T LEN)
These alignment macros are derived from PostgreSQL.
Definition: tdb_base.h:325
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:219
constexpr SlotId MinSlotId
The minimum valid slot ID.
Definition: tdb_base.h:265
uint8_t AggType
The aggregation type, see catalog/aggtyp.h.
Definition: tdb_base.h:301
constexpr PageNumber RESERVED_PID
An invalid page number reserved for file manager internal use.
Definition: tdb_base.h:248
constexpr FieldId MaxNumRegularFieldId
Definition: tdb_base.h:232
constexpr int FieldOffsetBits
Definition: tdb_base.h:234
constexpr BufferId INVALID_BUFID
Definition: tdb_base.h:272
constexpr T TYPEALIGN_DOWN(uint64_t ALIGNVAL, T LEN)
Definition: tdb_base.h:339
constexpr FieldId InvalidFieldId
Definition: tdb_base.h:231
constexpr PageNumber INVALID_PID
The invalid page number.
Definition: tdb_base.h:241
Definition: tdb_base.h:86
void operator()(void *x)
Definition: tdb_base.h:87
aligned_allocator< alignment, U > other
Definition: tdb_base.h:153
Definition: tdb_base.h:124
std::true_type is_always_equal
Definition: tdb_base.h:149
ptrdiff_t difference_type
Definition: tdb_base.h:127
T value_type
Definition: tdb_base.h:125
constexpr bool operator==(const aligned_allocator &)
Definition: tdb_base.h:140
static T * allocate(size_t n)
Definition: tdb_base.h:130
size_t size_type
Definition: tdb_base.h:126
constexpr bool operator!=(const aligned_allocator &)
Definition: tdb_base.h:145
static void deallocate(T *p, size_t)
Definition: tdb_base.h:135
std::vector< char, AlignedAllocImpl::aligned_allocator< 8, char > > maxaligned_char_buf
Definition: tdb_base.h:161
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:106
unique_malloced_ptr unique_malloc(size_t size)
Definition: tdb_base.h:117
constexpr const size_t PAGE_SIZE
Definition: tdb_base.h:165
constexpr const size_t CACHELINE_SIZE
Definition: tdb_base.h:164
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:390
unique_malloced_ptr wrap_malloc(void *ptr)
Definition: tdb_base.h:112
std::unique_ptr< void, AlignedAllocImpl::FreeMem > unique_malloced_ptr
Definition: tdb_base.h:99