MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NdbTypesUtil.hpp
1 /*
2  Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef NDB_TYPES_UTIL_HPP
19 #define NDB_TYPES_UTIL_HPP
20 
21 #include <assert.h>
22 #include <string.h>
23 
24 #include "my_global.h"
25 
26 #include "ndb_constants.h"
27 #include "ndb_types.h"
28 
29 /*
30  * Traits and Helper classes for NDB data types.
31  */
32 
33 // ---------------------------------------------------------------------------
34 // Traits classes providing information on NDB (column) data types
35 // ---------------------------------------------------------------------------
36 
37 /*
38  * These Traits classes support code genericity by parametrizing over
39  * NDB (column) data types. They provide compile-time information on
40  * - array types: [long][var](binary|char)
41  * - numeric types: [U]Int8..[U]Int64|float|double
42  *
43  * For instance, Traits functions
44  * - isFixedSized() for array types
45  * - lowest(), highest() for numeric types
46  * allow for the generic handling of arrays or numeric limits.
47  *
48  * Notes: the Traits classes
49  * - provide uniform access to type meta-data
50  * - are used as a type argument to a class or function template
51  * - have pure compile-time scope, lack instantiation at runtime
52  * - have _no_ link or library dependencies upon C++ stdlib code
53  * (compare to the bounds definitions in std::numeric_limits)
54  * - are defined below as inline template specializations.
55  */
56 
60 template< int TID > // the NDB type id as defined in ndb_constants.h
62  // whether this array type is a binary or character type
63  static bool isBinary();
64 
65  // whether this array type is fixed-or variable-sized
66  static bool isFixedSized();
67 
68  // the size of the length prefix in bytes, or zero if a fixed-sized array
69  static Uint32 lengthPrefixSize();
70 };
71 
72 // aliases for array type traits
79 
80 // internal helper class
81 template< typename T >
82 struct NumTypeMap {};
83 
94 template< typename T >
95 struct NumTypeTraits {
96  // the domain type T
97  typedef typename NumTypeMap< T >::DomainT DomainT;
98 
99  // if T is integral, the signed type of same width; otherwise T
100  typedef typename NumTypeMap< T >::SignedT SignedT;
101 
102  // if T is integral, the unsigned type of same width; otherwise T
103  typedef typename NumTypeMap< T >::UnsignedT UnsignedT;
104 
105  // whether the domain type is an integer type
106  static bool isIntegral() { return NumTypeMap< T >::isIntegral(); };
107 
108  // whether the domain type is signed or unsigned
109  static bool isSigned() { return NumTypeMap< T >::isSigned(); };
110 
111  // the width of the type in bytes
112  static Uint32 size();
113 
114  // the minimum finite value
115  static T lowest();
116 
117  // the maximum finite value
118  static T highest();
119 
120  // the minimum positive normalized value, or 0 for integral types
121  static T smallest();
122 };
123 
124 // aliases for standard numeric type traits
133 // not implemented yet: float, double
134 // ansi C type 'long double' is not a supported numeric NDB type
135 
144 template< typename T >
146  // the minimum finite value
147  static T lowest();
148 
149  // the maximum finite value
150  static T highest();
151 };
152 
153 // aliases for standard numeric type traits
156 
157 // ---------------------------------------------------------------------------
158 // Helper classes providing common functions on NDB (column) data
159 // ---------------------------------------------------------------------------
160 
161 /*
162  * These Helper classes provide basic utility functions on NDB types.
163  *
164  * For example, Helper functions
165  * - read/writeLengthPrefix() for array types
166  * - load(), store() for numeric types
167  * allow to abstract from the details of writing an array's length prefix
168  * or from reading/writing a numeric value from/to an unaligned buffer.
169  *
170  * Notes: the Helper classes
171  * - extend Traits classes for convenience
172  * - only add basic utility functions that
173  * - have _no_ link or library dependencies upon MySQL code
174  * (in contrast to other SQL utility code like ./NdbSqlUtil)
175  * - are defined below as inline template specializations.
176  */
177 
181 template< int ID >
183  // read the length prefix (not available if a fixed-sized array)
184  static Uint32 readLengthPrefix(const void * a);
185 
186  // write the length prefix (not available if a fixed-sized array)
187  // the non-length-prefix bytes of 'l' must be zero
188  static void writeLengthPrefix(void * a, Uint32 l);
189 };
190 
191 // aliases for array type helpers
198 
207 template< typename T >
209  // convenience aliases
210  typedef typename NumTypeTraits< T >::SignedT SignedT;
211  typedef typename NumTypeTraits< T >::UnsignedT UnsignedT;
212 
213  // casts a value to the signed numerical type of same width
214  static SignedT asSigned(T t) { return static_cast< SignedT >(t); }
215 
216  // casts a value to the unsigned numerical type of same width
217  static UnsignedT asUnsigned(T t) { return static_cast< UnsignedT >(t); }
218 
219  // read a single value from an unaligned buffer; s, t must not overlap
220  static void load(T * t, const char * s);
221 
222  // write a single value to an unaligned buffer; s, t must not overlap
223  static void store(char * t, const T * s);
224 };
225 
226 // aliases for numeric type helpers
235 // not implemented yet: float, double
236 // ansi C type 'long double' is not a supported numeric NDB type
237 
247 template< typename T >
249  // convenience alias
250  typedef typename NonStdNumTypeTraits< T >::SignedT SignedT;
251  typedef typename NonStdNumTypeTraits< T >::UnsignedT UnsignedT;
252 
253  // casts a value to the signed numerical type of same width
254  static SignedT asSigned(T t) { return static_cast< SignedT >(t); }
255 
256  // casts a value to the unsigned numerical type of same width
257  static UnsignedT asUnsigned(T t) { return static_cast< UnsignedT >(t); }
258 
259  // read a single value from an unaligned buffer; s, t must not overlap
260  static void load(T * t, const char * s);
261 
262  // write a single value to an unaligned buffer; s, t must not overlap
263  static void store(char * t, const T * s);
264 };
265 
266 // aliases for non-standard numeric type helpers
269 
270 // ---------------------------------------------------------------------------
271 // Definitions/Specializations of Traits classes
272 // ---------------------------------------------------------------------------
273 
274 // specialize the Traits template members for array types
275 #define NDB_SPECIALIZE_ARRAY_TYPE_TRAITS( TR, B, FS, LPS ) \
276  template<> inline bool TR::isBinary() { return B; } \
277  template<> inline bool TR::isFixedSized() { return FS; } \
278  template<> inline Uint32 TR::lengthPrefixSize() { return LPS; }
279 
280 // coincidentally, we could use ndb constants
281 // NDB_ARRAYTYPE_FIXED, NDB_ARRAYTYPE_SHORT_VAR, NDB_ARRAYTYPE_MEDIUM_VAR
282 // instead of literals, but let's not confuse ordinal/cardinal numbers
283 NDB_SPECIALIZE_ARRAY_TYPE_TRAITS(Tchar, false, true, 0)
284 NDB_SPECIALIZE_ARRAY_TYPE_TRAITS(Tbinary, true, true, 0)
285 NDB_SPECIALIZE_ARRAY_TYPE_TRAITS(Tvarchar, false, false, 1)
286 NDB_SPECIALIZE_ARRAY_TYPE_TRAITS(Tvarbinary, true, false, 1)
287 NDB_SPECIALIZE_ARRAY_TYPE_TRAITS(Tlongvarchar, false, false, 2)
288 NDB_SPECIALIZE_ARRAY_TYPE_TRAITS(Tlongvarbinary, true, false, 2)
289 #undef NDB_SPECIALIZE_ARRAY_TYPE_TRAITS
290 
291 // specialize the TypeMap template for numeric types
292 #define NDB_SPECIALIZE_NUM_TYPE_MAP( DT, ST, UT, I, S ) \
293  template<> struct NumTypeMap< DT > { \
294  typedef DT DomainT; \
295  typedef ST SignedT; \
296  typedef UT UnsignedT; \
297  static bool isIntegral() { return S; }; \
298  static bool isSigned() { return S; }; \
299  };
300 
301 NDB_SPECIALIZE_NUM_TYPE_MAP(Int8, Int8, Uint8, true, true)
302 NDB_SPECIALIZE_NUM_TYPE_MAP(Uint8, Int8, Uint8, true, false)
303 NDB_SPECIALIZE_NUM_TYPE_MAP(Int16, Int16, Uint16, true, true)
304 NDB_SPECIALIZE_NUM_TYPE_MAP(Uint16, Int16, Uint16, true, false)
305 NDB_SPECIALIZE_NUM_TYPE_MAP(Int32, Int32, Uint32, true, true)
306 NDB_SPECIALIZE_NUM_TYPE_MAP(Uint32, Int32, Uint32, true, false)
307 NDB_SPECIALIZE_NUM_TYPE_MAP(Int64, Int64, Uint64, true, true)
308 NDB_SPECIALIZE_NUM_TYPE_MAP(Uint64, Int64, Uint64, true, false)
309 
310 NDB_SPECIALIZE_NUM_TYPE_MAP(float, float, float, false, true)
311 NDB_SPECIALIZE_NUM_TYPE_MAP(double, double, double, false, true)
312 #undef NDB_SPECIALIZE_NUM_TYPE_MAP
313 
314 // specialize the Traits template members for numeric types
315 #define NDB_SPECIALIZE_NUM_TYPE_TRAITS( TR, T, SZ, LO, HI, SM ) \
316  template<> inline Uint32 TR::size() { return SZ; } \
317  template<> inline T TR::lowest() { return LO; } \
318  template<> inline T TR::highest() { return HI; } \
319  template<> inline T TR::smallest() { return SM; }
320 
321 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tint8, Int8, 1, INT_MIN8, INT_MAX8, 0)
322 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tint16, Int16, 2, INT_MIN16, INT_MAX16, 0)
323 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tint32, Int32, 4, INT_MIN32, INT_MAX32, 0)
324 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tint64, Int64, 8, INT_MIN64, INT_MAX64, 0)
325 
326 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tuint8, Uint8, 1, 0, UINT_MAX8, 0)
327 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tuint16, Uint16, 2, 0, UINT_MAX16, 0)
328 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tuint32, Uint32, 4, 0, UINT_MAX32, 0)
329 NDB_SPECIALIZE_NUM_TYPE_TRAITS(Tuint64, Uint64, 8, 0, UINT_MAX64, 0)
330 // not implemented yet: float, double
331 #undef NDB_SPECIALIZE_NUM_TYPE_TRAITS
332 
333 // specialize the Traits template members for non-standard numeric types
334 #define NDB_SPECIALIZE_NON_STD_NUM_TYPE_TRAITS( TR, T, LO, HI ) \
335  template<> inline T TR::lowest() { return LO; } \
336  template<> inline T TR::highest() { return HI; }
337 
338 NDB_SPECIALIZE_NON_STD_NUM_TYPE_TRAITS(Tint24, Int32, INT_MIN24, INT_MAX24)
339 NDB_SPECIALIZE_NON_STD_NUM_TYPE_TRAITS(Tuint24, Uint32, 0, UINT_MAX24)
340 #undef NDB_SPECIALIZE_NON_STD_NUM_TYPE_TRAITS
341 
342 // ---------------------------------------------------------------------------
343 // Definitions/Specializations of Helper classes
344 // ---------------------------------------------------------------------------
345 
346 // specialize the Helper template members for fixed-sized arrays
347 #define NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS0( H ) \
348  template<> inline Uint32 H::readLengthPrefix(const void * a) { \
349  assert(false); \
350  (void)a; \
351  return 0; \
352  }; \
353  template<> inline void H::writeLengthPrefix(void * a, Uint32 l) { \
354  assert(false); \
355  (void)a; (void)l; \
356  }
357 
358 NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS0(Hchar)
359 NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS0(Hbinary)
360 #undef NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS0
361 
362 // specialize the Helper template members for short-var arrays
363 #define NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS1( H ) \
364  template<> inline Uint32 H::readLengthPrefix(const void * a) { \
365  assert(a); \
366  const Uint8 * s = static_cast<const Uint8 *>(a); \
367  return s[0]; \
368  }; \
369  template<> inline void H::writeLengthPrefix(void * a, Uint32 l) { \
370  assert(a); \
371  assert(l >> (lengthPrefixSize() * 8) == 0); \
372  Uint8 * t = static_cast<Uint8 *>(a); \
373  t[0] = l & 0x000000FF; \
374  }
375 
376 NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS1(Hvarchar)
377 NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS1(Hvarbinary)
378 #undef NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS1
379 
380 // specialize the Helper template members for medium-var arrays
381 #define NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS2( H ) \
382  template<> inline Uint32 H::readLengthPrefix(const void * a) { \
383  assert(a); \
384  const Uint8 * s = static_cast<const Uint8 *>(a); \
385  return static_cast<Uint32>(s[0] + (s[1] << 8)); \
386  }; \
387  template<> inline void H::writeLengthPrefix(void * a, Uint32 l) { \
388  assert(a); \
389  assert(l >> (lengthPrefixSize() * 8) == 0); \
390  Uint8 * t = static_cast<Uint8 *>(a); \
391  t[0] = static_cast<Uint8>(l & 0x000000FF); \
392  t[1] = static_cast<Uint8>((l & 0x0000FF00) >> 8); \
393  }
394 
395 NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS2(Hlongvarchar)
396 NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS2(Hlongvarbinary)
397 #undef NDB_SPECIALIZE_ARRAY_TYPE_HELPER_LPS2
398 
399 // specialize the Helper template members for single-byte types
400 #define NDB_SPECIALIZE_NUM_TYPE_HELPER_BYTE( H, T ) \
401  template<> inline void H::load(T * t, const char * s) { \
402  assert(t); assert(s); assert(t != (const T *)s); \
403  *t = static_cast<T>(*s); \
404  } \
405  template<> inline void H::store(char * t, const T * s) { \
406  H::load(reinterpret_cast<T *>(t), \
407  reinterpret_cast<const char *>(s)); \
408  }
409 
410 NDB_SPECIALIZE_NUM_TYPE_HELPER_BYTE(Hint8, Int8);
411 NDB_SPECIALIZE_NUM_TYPE_HELPER_BYTE(Huint8, Uint8);
412 #undef NDB_SPECIALIZE_NUM_TYPE_HELPER_BYTE
413 
414 // specialize the Helper template members for numeric types
415 #define NDB_SPECIALIZE_NUM_TYPE_HELPER( H, T ) \
416  template<> inline void H::load(T * t, const char * s) { \
417  assert(t); assert(s); assert(t != (const T *)s); \
418  memcpy(t, s, H::size()); \
419  } \
420  template<> inline void H::store(char * t, const T * s) { \
421  H::load(reinterpret_cast<T *>(t), \
422  reinterpret_cast<const char *>(s)); \
423  }
424 
425 NDB_SPECIALIZE_NUM_TYPE_HELPER(Hint16, Int16);
426 NDB_SPECIALIZE_NUM_TYPE_HELPER(Hint32, Int32);
427 NDB_SPECIALIZE_NUM_TYPE_HELPER(Hint64, Int64);
428 
429 NDB_SPECIALIZE_NUM_TYPE_HELPER(Huint16, Uint16);
430 NDB_SPECIALIZE_NUM_TYPE_HELPER(Huint32, Uint32);
431 NDB_SPECIALIZE_NUM_TYPE_HELPER(Huint64, Uint64);
432 // not implemented yet: float, double
433 #undef NDB_SPECIALIZE_NUM_TYPE_HELPER
434 
435 // specialize the Helper template members for non-standard numeric types
436 #define NDB_SPECIALIZE_NON_STD_NUM_TYPE_HELPER( H, T, INT3KORR ) \
437  template<> inline void H::load(T * t, const char * s) { \
438  assert(t); assert(s); assert(t != (const T *)s); \
439  *t = (INT3KORR(s)); \
440  } \
441  template<> inline void H::store(char * t, const T * s) { \
442  assert(t); assert(s); assert((const T *)t != s); \
443  int3store(t, (*s)); \
444  }
445 
446 NDB_SPECIALIZE_NON_STD_NUM_TYPE_HELPER(Hint24, Int32, sint3korr)
447 NDB_SPECIALIZE_NON_STD_NUM_TYPE_HELPER(Huint24, Uint32, uint3korr)
448 #undef NDB_SPECIALIZE_NON_STD_NUM_TYPE_HELPER
449 
450 #endif /* !NDB_TYPES_UTIL_HPP */