| 22 | namespace arrow { |
| 23 | |
| 24 | int RequiredValueAlignmentForBuffer(Type::type type_id, int buffer_index) { |
| 25 | if (buffer_index == 2 && type_id == Type::DENSE_UNION) { |
| 26 | // A dense union array is the only array (so far) that requires alignment |
| 27 | // on a buffer with a buffer_index that is not equal to 1 |
| 28 | return 4; |
| 29 | } |
| 30 | if (buffer_index != 1) { |
| 31 | // If the buffer index is 0 then either: |
| 32 | // * The array type has no buffers, thus this shouldn't be called anyways |
| 33 | // * The array has a validity buffer at 0, no alignment needed |
| 34 | // * The array is a union array and has a types buffer at 0, no alignment needed |
| 35 | // If the buffer index is > 1 then, in all current cases, it represents binary |
| 36 | // data and no alignment is needed. The only exception is dense union buffers |
| 37 | // which are checked above. |
| 38 | return 1; |
| 39 | } |
| 40 | DCHECK_NE(type_id, Type::DICTIONARY); |
| 41 | DCHECK_NE(type_id, Type::EXTENSION); |
| 42 | |
| 43 | switch (type_id) { |
| 44 | case Type::NA: // No buffers |
| 45 | case Type::FIXED_SIZE_LIST: // No second buffer (values in child array) |
| 46 | case Type::FIXED_SIZE_BINARY: // Fixed size binary could be dangerous but the |
| 47 | // compute kernels don't type pun this. E.g. if |
| 48 | // an extension type is storing some kind of struct |
| 49 | // here then the user should do their own alignment |
| 50 | // check before casting to an array of structs |
| 51 | case Type::BOOL: // Always treated as uint8_t* |
| 52 | case Type::INT8: // Always treated as uint8_t* |
| 53 | case Type::UINT8: // Always treated as uint8_t* |
| 54 | case Type::DENSE_UNION: // Union arrays have a uint8_t* types buffer here |
| 55 | case Type::SPARSE_UNION: // Union arrays have a uint8_t* types buffer here |
| 56 | case Type::RUN_END_ENCODED: // No buffers |
| 57 | case Type::STRUCT: // No second buffer |
| 58 | return 1; |
| 59 | case Type::INT16: |
| 60 | case Type::UINT16: |
| 61 | case Type::HALF_FLOAT: |
| 62 | return 2; |
| 63 | case Type::INT32: |
| 64 | case Type::UINT32: |
| 65 | case Type::FLOAT: |
| 66 | case Type::STRING: // Offsets may be cast to int32_t* |
| 67 | case Type::BINARY: // Offsets may be cast to int32_t* |
| 68 | case Type::DATE32: |
| 69 | case Type::TIME32: |
| 70 | case Type::LIST: // Offsets may be cast to int32_t* |
| 71 | case Type::LIST_VIEW: // Offsets and sizes may be cast to int32_t* |
| 72 | case Type::MAP: // Same as LIST |
| 73 | case Type::INTERVAL_MONTHS: // Stored as int32_t* |
| 74 | case Type::INTERVAL_DAY_TIME: // Stored as two contiguous 32-bit integers |
| 75 | case Type::DECIMAL32: // May be cast to SmallBasicDecimal* which requires alignment |
| 76 | // of 4 |
| 77 | return 4; |
| 78 | case Type::INT64: |
| 79 | case Type::UINT64: |
| 80 | case Type::DOUBLE: |
| 81 | case Type::DECIMAL64: // May be cast to SmallBasicDecimal* which requires alignment |
no test coverage detected