| // 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. |
| |
| #pragma once |
| |
| #include <glog/logging.h> |
| #include <pdqsort.h> |
| |
| #include <cstddef> |
| |
| #include "runtime/define_primitive_type.h" |
| #include "runtime/primitive_type.h" |
| #include "vec/columns/column.h" |
| #include "vec/common/arena.h" |
| #include "vec/common/assert_cast.h" |
| #include "vec/common/string_view.h" |
| |
| namespace doris::vectorized { |
| #include "common/compile_check_begin.h" |
| class ColumnVarbinary final : public COWHelper<IColumn, ColumnVarbinary> { |
| private: |
| using Self = ColumnVarbinary; |
| friend class COWHelper<IColumn, ColumnVarbinary>; |
| template <bool positive> |
| struct less; |
| |
| public: |
| using value_type = typename PrimitiveTypeTraits<TYPE_VARBINARY>::ColumnItemType; |
| using Container = PaddedPODArray<doris::StringView>; |
| |
| private: |
| ColumnVarbinary() = default; |
| ColumnVarbinary(const size_t n) : _data(n) {} |
| ColumnVarbinary(const ColumnVarbinary& src) : _data(src._data.begin(), src._data.end()) {} |
| |
| public: |
| std::string get_name() const override { return "ColumnVarbinary"; } |
| |
| size_t size() const override { return _data.size(); } |
| |
| const Container& get_data() const { return _data; } |
| |
| Container& get_data() { return _data; } |
| |
| // Notice: after this buffer maybe have some useless data |
| void resize(size_t n) override { _data.resize(n); } |
| |
| void clear() override { |
| _data.clear(); |
| _arena.clear(); |
| } |
| |
| Field operator[](size_t n) const override { |
| return Field::create_field<TYPE_VARBINARY>(_data[n]); |
| } |
| |
| void get(size_t n, Field& res) const override { |
| res = Field::create_field<TYPE_VARBINARY>(_data[n]); |
| } |
| |
| StringRef get_data_at(size_t n) const override { return _data[n].to_string_ref(); } |
| |
| char* alloc(size_t length) { return _arena.alloc(length); } |
| |
| void insert(const Field& x) override { |
| const auto& value = vectorized::get<const StringViewField&>(x); |
| insert_data(value.data(), value.size()); |
| } |
| |
| void insert_from(const IColumn& src, size_t n) override { |
| const auto& src_col = assert_cast<const ColumnVarbinary&>(src); |
| auto value = src_col.get_data_at(n); |
| insert_data(value.data, value.size); |
| } |
| |
| void insert_data(const char* pos, size_t length) override { |
| if (length <= doris::StringView::kInlineSize) { |
| insert_inline_data(pos, length); |
| } else { |
| insert_to_buffer(pos, length); |
| } |
| } |
| |
| void insert_inline_data(const char* pos, size_t length) { |
| DCHECK(length <= doris::StringView::kInlineSize); |
| _data.push_back(doris::StringView(pos, cast_set<uint32_t>(length))); |
| } |
| |
| void insert_to_buffer(const char* pos, size_t length) { |
| const char* dst = _arena.insert(pos, length); |
| _data.push_back(doris::StringView(dst, cast_set<uint32_t>(length))); |
| } |
| |
| void insert_default() override { _data.push_back(doris::StringView()); } |
| |
| int compare_at(size_t n, size_t m, const IColumn& rhs_, |
| int /*nan_direction_hint*/) const override { |
| const auto& rhs = assert_cast<const ColumnVarbinary&>(rhs_); |
| return this->_data[n].compare(rhs.get_data()[m]); |
| } |
| |
| void get_permutation(bool reverse, size_t limit, int /*nan_direction_hint*/, |
| IColumn::Permutation& res) const override; |
| |
| size_t get_max_row_byte_size() const override; |
| |
| void deserialize(StringRef* keys, const size_t num_rows) override; |
| |
| void serialize(StringRef* keys, const size_t num_rows) const override; |
| |
| void pop_back(size_t n) override { resize(size() - n); } |
| |
| StringRef serialize_value_into_arena(size_t n, Arena& arena, |
| char const*& begin) const override { |
| char* pos = arena.alloc_continue(serialize_size_at(n), begin); |
| return {pos, serialize_impl(pos, n)}; |
| } |
| |
| const char* deserialize_and_insert_from_arena(const char* pos) override { |
| return pos + deserialize_impl(pos); |
| } |
| |
| void insert_range_from(const IColumn& src, size_t start, size_t length) override; |
| |
| MutableColumnPtr clone_resized(size_t size) const override; |
| |
| void insert_indices_from(const IColumn& src, const uint32_t* indices_begin, |
| const uint32_t* indices_end) override; |
| |
| size_t allocated_bytes() const override { return _data.allocated_bytes() + _arena.size(); } |
| |
| size_t byte_size() const override { |
| size_t bytes = _data.size() * sizeof(doris::StringView); |
| return bytes + _arena.used_size(); |
| } |
| |
| bool has_enough_capacity(const IColumn& src) const override { |
| const auto& src_col = assert_cast<const ColumnVarbinary&>(src); |
| return _data.capacity() - _data.size() > src_col.size(); |
| } |
| |
| ColumnPtr filter(const IColumn::Filter& filt, ssize_t result_size_hint) const override; |
| |
| size_t filter(const IColumn::Filter& filter) override; |
| |
| MutableColumnPtr permute(const IColumn::Permutation& perm, size_t limit) const override; |
| |
| void replace_column_data(const IColumn& rhs, size_t row, size_t self_row = 0) override; |
| |
| size_t deserialize_impl(const char* pos) override { |
| const auto value_size = unaligned_load<uint32_t>(pos); |
| pos += sizeof(value_size); |
| insert_data(pos, value_size); |
| return value_size + sizeof(value_size); |
| } |
| |
| size_t serialize_impl(char* pos, const size_t row) const override { |
| const auto* value_data = _data[row].data(); |
| uint32_t value_size = _data[row].size(); |
| memcpy_fixed<uint32_t>(pos, (char*)(&value_size)); |
| memcpy(pos + sizeof(uint32_t), value_data, value_size); |
| return value_size + sizeof(uint32_t); |
| } |
| |
| size_t serialize_size_at(size_t row) const override { |
| return _data[row].size() + sizeof(uint32_t); |
| } |
| |
| void insert_many_strings(const StringRef* strings, size_t num) override; |
| |
| void insert_many_strings_overflow(const StringRef* strings, size_t num, |
| size_t max_length) override; |
| |
| void sort_column(const ColumnSorter* sorter, EqualFlags& flags, IColumn::Permutation& perms, |
| EqualRange& range, bool last_column) const override; |
| |
| private: |
| Container _data; |
| Arena _arena; |
| }; |
| #include "common/compile_check_end.h" |
| } // namespace doris::vectorized |