| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * License); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #ifndef ENCODING_PLAIN_DECODER_H |
| #define ENCODING_PLAIN_DECODER_H |
| |
| #include <algorithm> |
| #include <cstring> |
| |
| #include "encoding/decoder.h" |
| |
| namespace storage { |
| |
| class PlainDecoder : public Decoder { |
| public: |
| ~PlainDecoder() override = default; |
| FORCE_INLINE void reset() override { /* do nothing */ |
| } |
| FORCE_INLINE bool has_remaining(const common::ByteStream& buffer) override { |
| return buffer.has_remaining(); |
| } |
| FORCE_INLINE int read_boolean(bool& ret_bool, |
| common::ByteStream& in) override { |
| return common::SerializationUtil::read_ui8((uint8_t&)ret_bool, in); |
| } |
| |
| FORCE_INLINE int read_int32(int32_t& ret_int32, |
| common::ByteStream& in) override { |
| return common::SerializationUtil::read_var_int(ret_int32, in); |
| } |
| |
| FORCE_INLINE int read_int64(int64_t& ret_int64, |
| common::ByteStream& in) override { |
| return common::SerializationUtil::read_i64(ret_int64, in); |
| } |
| |
| FORCE_INLINE int read_float(float& ret_float, |
| common::ByteStream& in) override { |
| return common::SerializationUtil::read_float(ret_float, in); |
| } |
| |
| FORCE_INLINE int read_double(double& ret_double, |
| common::ByteStream& in) override { |
| return common::SerializationUtil::read_double(ret_double, in); |
| } |
| |
| FORCE_INLINE int read_String(common::String& ret_String, |
| common::PageArena& pa, |
| common::ByteStream& in) override { |
| return common::SerializationUtil::read_mystring(ret_String, &pa, in); |
| } |
| |
| // ── Batch overrides ────────────────────────────────────────────────────── |
| // |
| // INT32: PLAIN encoding uses varint (variable stride). Override to avoid |
| // virtual dispatch per element; actual decode is still per-value. |
| int read_batch_int32(int32_t* out, int capacity, int& actual, |
| common::ByteStream& in) override { |
| actual = 0; |
| while (actual < capacity && in.has_remaining()) { |
| int ret = common::SerializationUtil::read_var_int(out[actual], in); |
| if (ret != common::E_OK) return ret; |
| ++actual; |
| } |
| return common::E_OK; |
| } |
| |
| int skip_int32(int count, int& skipped, common::ByteStream& in) override { |
| skipped = 0; |
| int32_t dummy; |
| while (skipped < count && in.has_remaining()) { |
| int ret = common::SerializationUtil::read_var_int(dummy, in); |
| if (ret != common::E_OK) return ret; |
| ++skipped; |
| } |
| return common::E_OK; |
| } |
| |
| // INT64: fixed 8-byte big-endian. Direct pointer access for wrapped |
| // ByteStream, __builtin_bswap64 for byte-swap (single REV on ARM64). |
| int read_batch_int64(int64_t* out, int capacity, int& actual, |
| common::ByteStream& in) override { |
| actual = 0; |
| int n = static_cast<int>( |
| std::min<uint32_t>(in.remaining_size() / 8, |
| static_cast<uint32_t>(capacity))); |
| if (n <= 0) return common::E_OK; |
| |
| const uint8_t* src = |
| (const uint8_t*)in.get_wrapped_buf() + in.read_pos(); |
| in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(n) * 8); |
| actual = n; |
| for (int i = 0; i < n; ++i) { |
| uint64_t v; |
| memcpy(&v, src + i * 8, 8); |
| out[i] = static_cast<int64_t>(__builtin_bswap64(v)); |
| } |
| return common::E_OK; |
| } |
| |
| int skip_int64(int count, int& skipped, common::ByteStream& in) override { |
| skipped = static_cast<int>( |
| std::min<uint32_t>(in.remaining_size() / 8, |
| static_cast<uint32_t>(count))); |
| if (skipped <= 0) { skipped = 0; return common::E_OK; } |
| in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(skipped) * 8); |
| return common::E_OK; |
| } |
| |
| int skip_float(int count, int& skipped, common::ByteStream& in) override { |
| skipped = static_cast<int>( |
| std::min<uint32_t>(in.remaining_size() / 4, |
| static_cast<uint32_t>(count))); |
| if (skipped <= 0) { skipped = 0; return common::E_OK; } |
| in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(skipped) * 4); |
| return common::E_OK; |
| } |
| |
| int skip_double(int count, int& skipped, common::ByteStream& in) override { |
| skipped = static_cast<int>( |
| std::min<uint32_t>(in.remaining_size() / 8, |
| static_cast<uint32_t>(count))); |
| if (skipped <= 0) { skipped = 0; return common::E_OK; } |
| in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(skipped) * 8); |
| return common::E_OK; |
| } |
| |
| // FLOAT: fixed 4-byte big-endian IEEE 754. |
| int read_batch_float(float* out, int capacity, int& actual, |
| common::ByteStream& in) override { |
| actual = 0; |
| int n = static_cast<int>( |
| std::min<uint32_t>(in.remaining_size() / 4, |
| static_cast<uint32_t>(capacity))); |
| if (n <= 0) return common::E_OK; |
| |
| const uint8_t* src = |
| (const uint8_t*)in.get_wrapped_buf() + in.read_pos(); |
| in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(n) * 4); |
| actual = n; |
| for (int i = 0; i < n; ++i) { |
| uint32_t v; |
| memcpy(&v, src + i * 4, 4); |
| v = __builtin_bswap32(v); |
| memcpy(&out[i], &v, 4); |
| } |
| return common::E_OK; |
| } |
| |
| // DOUBLE: fixed 8-byte big-endian IEEE 754. |
| int read_batch_double(double* out, int capacity, int& actual, |
| common::ByteStream& in) override { |
| actual = 0; |
| int n = static_cast<int>( |
| std::min<uint32_t>(in.remaining_size() / 8, |
| static_cast<uint32_t>(capacity))); |
| if (n <= 0) return common::E_OK; |
| |
| const uint8_t* src = |
| (const uint8_t*)in.get_wrapped_buf() + in.read_pos(); |
| in.wrapped_buf_advance_read_pos(static_cast<uint32_t>(n) * 8); |
| actual = n; |
| for (int i = 0; i < n; ++i) { |
| uint64_t v; |
| memcpy(&v, src + i * 8, 8); |
| v = __builtin_bswap64(v); |
| memcpy(&out[i], &v, 8); |
| } |
| return common::E_OK; |
| } |
| }; |
| |
| } // end namespace storage |
| #endif // ENCODING_PLAIN_DECODER_H |