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 | |