| 159 | |
| 160 | template<std::floating_point T> |
| 161 | CompressionMetadata createFloatMetadata(CompressionType compressionType, |
| 162 | PhysicalTypeID physicalType, std::span<const T> src, alp::state& alpMetadata, StorageValue min, |
| 163 | StorageValue max) { |
| 164 | using EncodedType = typename FloatCompression<T>::EncodedType; |
| 165 | |
| 166 | offset_vec_t unsuccessfulEncodeIdxes; |
| 167 | std::vector<EncodedType> floatEncodedValues(src.size()); |
| 168 | std::optional<EncodedType> firstSuccessfulEncode; |
| 169 | size_t exceptionCount = 0; |
| 170 | for (offset_t i = 0; i < src.size(); ++i) { |
| 171 | const T& val = src[i]; |
| 172 | const auto encoded_value = |
| 173 | alp::AlpEncode<T>::encode_value(val, alpMetadata.fac, alpMetadata.exp); |
| 174 | const auto decoded_value = |
| 175 | alp::AlpDecode<T>::decode_value(encoded_value, alpMetadata.fac, alpMetadata.exp); |
| 176 | |
| 177 | if (val == decoded_value) { |
| 178 | floatEncodedValues[i] = encoded_value; |
| 179 | if (!firstSuccessfulEncode.has_value()) { |
| 180 | firstSuccessfulEncode = encoded_value; |
| 181 | } |
| 182 | } else { |
| 183 | unsuccessfulEncodeIdxes.push_back(i); |
| 184 | ++exceptionCount; |
| 185 | } |
| 186 | } |
| 187 | alpMetadata.exceptions_count = exceptionCount; |
| 188 | |
| 189 | if (firstSuccessfulEncode.has_value()) { |
| 190 | for (auto unsuccessfulEncodeIdx : unsuccessfulEncodeIdxes) { |
| 191 | floatEncodedValues[unsuccessfulEncodeIdx] = firstSuccessfulEncode.value(); |
| 192 | } |
| 193 | } |
| 194 | |
| 195 | const auto& [minEncoded, maxEncoded] = |
| 196 | std::minmax_element(floatEncodedValues.begin(), floatEncodedValues.end()); |
| 197 | |
| 198 | return CompressionMetadata(min, max, compressionType, alpMetadata, StorageValue{*minEncoded}, |
| 199 | StorageValue{*maxEncoded}, physicalType); |
| 200 | } |
| 201 | } // namespace |
| 202 | |
| 203 | template<std::floating_point T> |
no test coverage detected