// 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. #include "contrib/libs/apache/arrow_next/cpp/src/arrow/buffer.h" #include #include #include #include "contrib/libs/apache/arrow_next/cpp/src/arrow/memory_pool_internal.h" #include "contrib/libs/apache/arrow_next/cpp/src/arrow/result.h" #include "contrib/libs/apache/arrow_next/cpp/src/arrow/status.h" #include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/bit_util.h" #include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/logging.h" #include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/slice_util_internal.h" #include "contrib/libs/apache/arrow_next/cpp/src/arrow/util/string.h" namespace arrow20 { Result> Buffer::CopySlice(const int64_t start, const int64_t nbytes, MemoryPool* pool) const { // Sanity checks ARROW_CHECK_LE(start, size_); ARROW_CHECK_LE(nbytes, size_ - start); DCHECK_GE(nbytes, 0); ARROW_ASSIGN_OR_RAISE(auto new_buffer, AllocateResizableBuffer(nbytes, pool)); std::memcpy(new_buffer->mutable_data(), data() + start, static_cast(nbytes)); // R build with openSUSE155 requires an explicit shared_ptr construction return std::shared_ptr(std::move(new_buffer)); } Buffer::Buffer() : Buffer(memory_pool::internal::kZeroSizeArea, 0) {} namespace { Status CheckBufferSlice(const Buffer& buffer, int64_t offset, int64_t length) { return internal::CheckSliceParams(buffer.size(), offset, length, "buffer"); } Status CheckBufferSlice(const Buffer& buffer, int64_t offset) { if (ARROW_PREDICT_FALSE(offset < 0)) { // Avoid UBSAN in subtraction below return Status::IndexError("Negative buffer slice offset"); } return CheckBufferSlice(buffer, offset, buffer.size() - offset); } } // namespace Result> SliceBufferSafe(std::shared_ptr buffer, int64_t offset) { RETURN_NOT_OK(CheckBufferSlice(*buffer, offset)); return SliceBuffer(std::move(buffer), offset); } Result> SliceBufferSafe(std::shared_ptr buffer, int64_t offset, int64_t length) { RETURN_NOT_OK(CheckBufferSlice(*buffer, offset, length)); return SliceBuffer(std::move(buffer), offset, length); } Result> SliceMutableBufferSafe(std::shared_ptr buffer, int64_t offset) { RETURN_NOT_OK(CheckBufferSlice(*buffer, offset)); return SliceMutableBuffer(std::move(buffer), offset); } Result> SliceMutableBufferSafe(std::shared_ptr buffer, int64_t offset, int64_t length) { RETURN_NOT_OK(CheckBufferSlice(*buffer, offset, length)); return SliceMutableBuffer(std::move(buffer), offset, length); } std::string Buffer::ToHexString() { return HexEncode(data(), static_cast(size())); } bool Buffer::Equals(const Buffer& other, const int64_t nbytes) const { return this == &other || (size_ >= nbytes && other.size_ >= nbytes && (data_ == other.data_ || !memcmp(data_, other.data_, static_cast(nbytes)))); } bool Buffer::Equals(const Buffer& other) const { return this == &other || (size_ == other.size_ && (data_ == other.data_ || !memcmp(data_, other.data_, static_cast(size_)))); } std::string Buffer::ToString() const { return std::string(reinterpret_cast(data_), static_cast(size_)); } void Buffer::CheckMutable() const { DCHECK(is_mutable()) << "buffer not mutable"; } void Buffer::CheckCPU() const { DCHECK(is_cpu()) << "not a CPU buffer (device: " << device()->ToString() << ")"; } Result> Buffer::GetReader( std::shared_ptr buf) { return buf->memory_manager_->GetBufferReader(std::move(buf)); } Result> Buffer::GetWriter(std::shared_ptr buf) { if (!buf->is_mutable()) { return Status::Invalid("Expected mutable buffer"); } return buf->memory_manager_->GetBufferWriter(std::move(buf)); } Result> Buffer::Copy(std::shared_ptr source, const std::shared_ptr& to) { return MemoryManager::CopyBuffer(source, to); } Result> Buffer::CopyNonOwned( const Buffer& source, const std::shared_ptr& to) { return MemoryManager::CopyNonOwned(source, to); } Result> Buffer::View(std::shared_ptr source, const std::shared_ptr& to) { return MemoryManager::ViewBuffer(source, to); } Result> Buffer::ViewOrCopy( std::shared_ptr source, const std::shared_ptr& to) { auto maybe_buffer = MemoryManager::ViewBuffer(source, to); if (maybe_buffer.ok()) { return maybe_buffer; } return MemoryManager::CopyBuffer(source, to); } class StlStringBuffer : public Buffer { public: explicit StlStringBuffer(std::string data) : input_(std::move(data)) { if (!input_.empty()) { data_ = reinterpret_cast(input_.c_str()); size_ = static_cast(input_.size()); capacity_ = size_; } } private: std::string input_; }; std::shared_ptr Buffer::FromString(std::string data) { return std::make_shared(std::move(data)); } std::shared_ptr SliceMutableBuffer(std::shared_ptr buffer, const int64_t offset, const int64_t length) { return std::make_shared(std::move(buffer), offset, length); } MutableBuffer::MutableBuffer(const std::shared_ptr& parent, const int64_t offset, const int64_t size) : MutableBuffer(reinterpret_cast(parent->mutable_address()) + offset, size) { DCHECK(parent->is_mutable()) << "Must pass mutable buffer"; parent_ = parent; } Result> AllocateBitmap(int64_t length, MemoryPool* pool) { ARROW_ASSIGN_OR_RAISE(auto buf, AllocateBuffer(bit_util::BytesForBits(length), pool)); // Zero out any trailing bits if (buf->size() > 0) { buf->mutable_data()[buf->size() - 1] = 0; } // R build with openSUSE155 requires an explicit shared_ptr construction return std::shared_ptr(std::move(buf)); } Result> AllocateEmptyBitmap(int64_t length, MemoryPool* pool) { return AllocateEmptyBitmap(length, kDefaultBufferAlignment, pool); } Result> AllocateEmptyBitmap(int64_t length, int64_t alignment, MemoryPool* pool) { ARROW_ASSIGN_OR_RAISE(auto buf, AllocateBuffer(bit_util::BytesForBits(length), alignment, pool)); memset(buf->mutable_data(), 0, static_cast(buf->size())); // R build with openSUSE155 requires an explicit shared_ptr construction return std::shared_ptr(std::move(buf)); } Status AllocateEmptyBitmap(int64_t length, std::shared_ptr* out) { return AllocateEmptyBitmap(length).Value(out); } Result> ConcatenateBuffers( const std::vector>& buffers, MemoryPool* pool) { int64_t out_length = 0; for (const auto& buffer : buffers) { out_length += buffer->size(); } ARROW_ASSIGN_OR_RAISE(auto out, AllocateBuffer(out_length, pool)); auto out_data = out->mutable_data(); for (const auto& buffer : buffers) { // Passing nullptr to std::memcpy is undefined behavior, so skip empty buffers if (buffer->size() != 0) { std::memcpy(out_data, buffer->data(), buffer->size()); out_data += buffer->size(); } } // R build with openSUSE155 requires an explicit shared_ptr construction return std::shared_ptr(std::move(out)); } } // namespace arrow20