| 1 | #include "duckdb/storage/table/column_segment.hpp" | 
|---|
| 2 | #include <cstring> | 
|---|
| 3 |  | 
|---|
| 4 | using namespace duckdb; | 
|---|
| 5 | using namespace std; | 
|---|
| 6 |  | 
|---|
| 7 | ColumnSegment::ColumnSegment(TypeId type, ColumnSegmentType segment_type, idx_t start, idx_t count) | 
|---|
| 8 | : SegmentBase(start, count), type(type), type_size(GetTypeIdSize(type)), segment_type(segment_type), | 
|---|
| 9 | stats(type, type_size) { | 
|---|
| 10 | } | 
|---|
| 11 |  | 
|---|
| 12 | ColumnSegment::ColumnSegment(TypeId type, ColumnSegmentType segment_type, idx_t start, idx_t count, data_t stats_min[], | 
|---|
| 13 | data_t stats_max[]) | 
|---|
| 14 | : SegmentBase(start, count), type(type), type_size(GetTypeIdSize(type)), segment_type(segment_type), | 
|---|
| 15 | stats(type, type_size, stats_min, stats_max) { | 
|---|
| 16 | } | 
|---|
| 17 |  | 
|---|
| 18 | SegmentStatistics::SegmentStatistics(TypeId type, idx_t type_size) : type(type), type_size(type_size) { | 
|---|
| 19 | Reset(); | 
|---|
| 20 | } | 
|---|
| 21 |  | 
|---|
| 22 | template <class T> | 
|---|
| 23 | static void set_min_max(data_t min_value_p[], data_t max_value_p[], data_ptr_t min_p, data_ptr_t max_p) { | 
|---|
| 24 | memcpy(min_p, min_value_p, sizeof(T)); | 
|---|
| 25 | memcpy(max_p, max_value_p, sizeof(T)); | 
|---|
| 26 | } | 
|---|
| 27 |  | 
|---|
| 28 | SegmentStatistics::SegmentStatistics(TypeId type, idx_t type_size, data_t stats_min[], data_t stats_max[]) | 
|---|
| 29 | : type(type), type_size(type_size) { | 
|---|
| 30 | Reset(); | 
|---|
| 31 | switch (type) { | 
|---|
| 32 | case TypeId::INT8: { | 
|---|
| 33 | set_min_max<int8_t>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 34 | break; | 
|---|
| 35 | } | 
|---|
| 36 | case TypeId::INT16: { | 
|---|
| 37 | set_min_max<int16_t>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 38 | break; | 
|---|
| 39 | } | 
|---|
| 40 | case TypeId::INT32: { | 
|---|
| 41 | set_min_max<int32_t>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 42 | break; | 
|---|
| 43 | } | 
|---|
| 44 | case TypeId::INT64: { | 
|---|
| 45 | set_min_max<int64_t>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 46 | break; | 
|---|
| 47 | } | 
|---|
| 48 | case TypeId::FLOAT: { | 
|---|
| 49 | set_min_max<float>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 50 | break; | 
|---|
| 51 | } | 
|---|
| 52 | case TypeId::DOUBLE: { | 
|---|
| 53 | set_min_max<double>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 54 | break; | 
|---|
| 55 | } | 
|---|
| 56 | case TypeId::VARCHAR: { | 
|---|
| 57 | set_min_max<char[8]>(stats_min, stats_max, minimum.get(), maximum.get()); | 
|---|
| 58 | break; | 
|---|
| 59 | } | 
|---|
| 60 |  | 
|---|
| 61 | default: | 
|---|
| 62 | break; | 
|---|
| 63 | } | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | template <class T> void initialize_max_min(data_ptr_t min, data_ptr_t max) { | 
|---|
| 67 | *((T *)min) = std::numeric_limits<T>::max(); | 
|---|
| 68 | *((T *)max) = std::numeric_limits<T>::min(); | 
|---|
| 69 | } | 
|---|
| 70 |  | 
|---|
| 71 | void SegmentStatistics::Reset() { | 
|---|
| 72 | idx_t min_max_size = type_size > 8 ? 8 : type_size; | 
|---|
| 73 | minimum = unique_ptr<data_t[]>(new data_t[min_max_size]); | 
|---|
| 74 | maximum = unique_ptr<data_t[]>(new data_t[min_max_size]); | 
|---|
| 75 | has_null = false; | 
|---|
| 76 | max_string_length = 0; | 
|---|
| 77 | has_overflow_strings = false; | 
|---|
| 78 | char padding = '\0'; | 
|---|
| 79 | switch (type) { | 
|---|
| 80 | case TypeId::INT8: | 
|---|
| 81 | initialize_max_min<int8_t>(minimum.get(), maximum.get()); | 
|---|
| 82 | break; | 
|---|
| 83 | case TypeId::INT16: | 
|---|
| 84 | initialize_max_min<int16_t>(minimum.get(), maximum.get()); | 
|---|
| 85 | break; | 
|---|
| 86 | case TypeId::INT32: | 
|---|
| 87 | initialize_max_min<int32_t>(minimum.get(), maximum.get()); | 
|---|
| 88 | break; | 
|---|
| 89 | case TypeId::INT64: | 
|---|
| 90 | initialize_max_min<int64_t>(minimum.get(), maximum.get()); | 
|---|
| 91 | break; | 
|---|
| 92 | case TypeId::FLOAT: | 
|---|
| 93 | initialize_max_min<float>(minimum.get(), maximum.get()); | 
|---|
| 94 | break; | 
|---|
| 95 | case TypeId::DOUBLE: | 
|---|
| 96 | initialize_max_min<double>(minimum.get(), maximum.get()); | 
|---|
| 97 | break; | 
|---|
| 98 | case TypeId::VARCHAR: { | 
|---|
| 99 | //! This marks the min/max was not initialized | 
|---|
| 100 | char marker = '1'; | 
|---|
| 101 | memset(minimum.get(), padding, min_max_size); | 
|---|
| 102 | memset(maximum.get(), padding, min_max_size); | 
|---|
| 103 | minimum.get()[1] = marker; | 
|---|
| 104 | maximum.get()[1] = marker; | 
|---|
| 105 | break; | 
|---|
| 106 | } | 
|---|
| 107 | default: | 
|---|
| 108 | break; | 
|---|
| 109 | } | 
|---|
| 110 | } | 
|---|
| 111 |  | 
|---|