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