1#include "duckdb/storage/table/column_segment.hpp"
2#include <cstring>
3
4using namespace duckdb;
5using namespace std;
6
7ColumnSegment::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
12ColumnSegment::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
18SegmentStatistics::SegmentStatistics(TypeId type, idx_t type_size) : type(type), type_size(type_size) {
19 Reset();
20}
21
22template <class T>
23static 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
28SegmentStatistics::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
66template <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
71void 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