From 8f52ebbbf333b4bafb1ce55560d2789c746d8ebc Mon Sep 17 00:00:00 2001 From: Tom Date: Tue, 6 Aug 2024 09:48:34 +0100 Subject: [PATCH] Add new LongConstantString Codec behind feature flag The new codec is enabled for reading but odc will not write data with the new codec unless "ODC_ENABLE_WRITING_LONG_STRING_CODEC" is set in the environment. This is to give some time for installations in the wild to update before files containing the new code are produced by default. --- src/odc/codec/CodecOptimizer.h | 2 ++ src/odc/codec/Constant.cc | 1 + src/odc/codec/Constant.h | 53 ++++++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/odc/codec/CodecOptimizer.h b/src/odc/codec/CodecOptimizer.h index 48ea6c9f..42fb73eb 100644 --- a/src/odc/codec/CodecOptimizer.h +++ b/src/odc/codec/CodecOptimizer.h @@ -96,6 +96,8 @@ int CodecOptimizer::setOptimalCodecs(core::MetaData& columns) n = col.coder().numStrings(); if (n == 1 && col.coder().dataSizeDoubles() == 1) codec = "constant_string"; + else if (n == 1 && std::getenv("ODC_ENABLE_WRITING_LONG_STRING_CODEC") != NULL) + codec = "long_constant_string"; else if(n < 256) codec = "int8_string"; else if(n < 65536) diff --git a/src/odc/codec/Constant.cc b/src/odc/codec/Constant.cc index cbcb1864..8596d0f0 100644 --- a/src/odc/codec/Constant.cc +++ b/src/odc/codec/Constant.cc @@ -23,6 +23,7 @@ namespace codec { namespace { core::IntegerCodecBuilder constantBuilder; core::CodecBuilder constantStringBuilder; + core::CodecBuilder LongConstantStringBuilder; } //---------------------------------------------------------------------------------------------------------------------- diff --git a/src/odc/codec/Constant.h b/src/odc/codec/Constant.h index ffc18348..b655121c 100644 --- a/src/odc/codec/Constant.h +++ b/src/odc/codec/Constant.h @@ -16,6 +16,7 @@ #define odc_core_codec_Constant_H #include "odc/core/Codec.h" +#include "odc/codec/String.h" namespace odc { namespace codec { @@ -74,6 +75,25 @@ class CodecConstantString : public CodecConstant { void save(core::DataStream& ds) override; }; +template +class CodecLongConstantString : public CodecChars { + +public: // methods + constexpr static const char* codec_name() { return "long_constant_string"; } + CodecLongConstantString(api::ColumnType type) : CodecChars(type, codec_name()) {}; + ~CodecLongConstantString() override {} + +private: // methods + unsigned char* encode(unsigned char* p, const double& d) override; + void decode(double* out) override; + void skip() override; + + size_t numStrings() const override { return 1; } + + void load(core::DataStream& ds) override; + void save(core::DataStream& ds) override; +}; + //---------------------------------------------------------------------------------------------------------------------- // Implementation of Constant @@ -151,6 +171,39 @@ void CodecConstantString::print(std::ostream& s) const { //---------------------------------------------------------------------------------------------------------------------- +// Implementation of LongConstantString + +template +unsigned char* CodecLongConstantString::encode(unsigned char* p, const double&) { + return p; +} + +template +void CodecLongConstantString::decode(double* out) { + ::memset(out, 0, this->decodedSizeDoubles_*sizeof(double)); + ::memcpy(reinterpret_cast(out), &this->strings_[0][0], std::min(this->strings_[0].length(), this->decodedSizeDoubles_*sizeof(double))); +} + +template +void CodecLongConstantString::skip() {} + +template +void CodecLongConstantString::load(core::DataStream& ds) { + core::DataStreamCodec::load(ds); + std::string s; + ds.read(s); + this->decodedSizeDoubles_ = ((s.length()-1) / sizeof(double)) +1; + this->strings_.push_back(s); +} + +template +void CodecLongConstantString::save(core::DataStream& ds) { + core::DataStreamCodec::save(ds); + ds.write(this->strings_[0]); +} + +//---------------------------------------------------------------------------------------------------------------------- + } // namespace codec } // namespace odc