| // 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 PARQUET_UTIL_BUFFER_H |
| #define PARQUET_UTIL_BUFFER_H |
| |
| #include <cstdint> |
| #include <cstdlib> |
| #include <cstring> |
| #include <memory> |
| #include <vector> |
| |
| #include "parquet/util/macros.h" |
| #include "parquet/util/mem-allocator.h" |
| #include "parquet/util/visibility.h" |
| |
| namespace parquet { |
| |
| // ---------------------------------------------------------------------- |
| // Buffer classes |
| |
| // Immutable API for a chunk of bytes which may or may not be owned by the |
| // class instance |
| class PARQUET_EXPORT Buffer : public std::enable_shared_from_this<Buffer> { |
| public: |
| Buffer(const uint8_t* data, int64_t size) : data_(data), size_(size) {} |
| |
| // An offset into data that is owned by another buffer, but we want to be |
| // able to retain a valid pointer to it even after other shared_ptr's to the |
| // parent buffer have been destroyed |
| Buffer(const std::shared_ptr<Buffer>& parent, int64_t offset, int64_t size); |
| |
| std::shared_ptr<Buffer> get_shared_ptr() { return shared_from_this(); } |
| |
| // Return true if both buffers are the same size and contain the same bytes |
| // up to the number of compared bytes |
| bool Equals(const Buffer& other, int64_t nbytes) const { |
| return this == &other || (size_ >= nbytes && other.size_ >= nbytes && |
| !memcmp(data_, other.data_, nbytes)); |
| } |
| |
| bool Equals(const Buffer& other) const { |
| return this == &other || (size_ == other.size_ && !memcmp(data_, other.data_, size_)); |
| } |
| |
| const uint8_t* data() const { return data_; } |
| |
| int64_t size() const { return size_; } |
| |
| // Returns true if this Buffer is referencing memory (possibly) owned by some |
| // other buffer |
| bool is_shared() const { return static_cast<bool>(parent_); } |
| |
| const std::shared_ptr<Buffer> parent() const { return parent_; } |
| |
| protected: |
| const uint8_t* data_; |
| int64_t size_; |
| |
| // nullptr by default, but may be set |
| std::shared_ptr<Buffer> parent_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(Buffer); |
| }; |
| |
| // A Buffer whose contents can be mutated. May or may not own its data. |
| class PARQUET_EXPORT MutableBuffer : public Buffer { |
| public: |
| MutableBuffer(uint8_t* data, int64_t size) : Buffer(data, size) { |
| mutable_data_ = data; |
| } |
| |
| uint8_t* mutable_data() { return mutable_data_; } |
| |
| // Get a read-only view of this buffer |
| std::shared_ptr<Buffer> GetImmutableView(); |
| |
| protected: |
| MutableBuffer() : Buffer(nullptr, 0), mutable_data_(nullptr) {} |
| |
| uint8_t* mutable_data_; |
| }; |
| |
| class PARQUET_EXPORT ResizableBuffer : public MutableBuffer { |
| public: |
| virtual void Resize(int64_t new_size) = 0; |
| |
| protected: |
| ResizableBuffer(uint8_t* data, int64_t size) |
| : MutableBuffer(data, size), capacity_(size) {} |
| int64_t capacity_; |
| }; |
| |
| // A ResizableBuffer whose memory is owned by the class instance. For example, |
| // for reading data out of files that you want to deallocate when this class is |
| // garbage-collected |
| class PARQUET_EXPORT OwnedMutableBuffer : public ResizableBuffer { |
| public: |
| explicit OwnedMutableBuffer( |
| int64_t size = 0, MemoryAllocator* allocator = default_allocator()); |
| virtual ~OwnedMutableBuffer(); |
| void Resize(int64_t new_size) override; |
| void Reserve(int64_t new_capacity); |
| uint8_t& operator[](int64_t i); |
| |
| private: |
| // TODO: aligned allocations |
| MemoryAllocator* allocator_; |
| |
| DISALLOW_COPY_AND_ASSIGN(OwnedMutableBuffer); |
| }; |
| |
| template <class T> |
| class Vector { |
| public: |
| explicit Vector(int64_t size, MemoryAllocator* allocator); |
| void Resize(int64_t new_size); |
| void Reserve(int64_t new_capacity); |
| void Assign(int64_t size, const T val); |
| void Swap(Vector<T>& v); |
| inline T& operator[](int64_t i) { return data_[i]; } |
| |
| private: |
| std::unique_ptr<OwnedMutableBuffer> buffer_; |
| int64_t size_; |
| int64_t capacity_; |
| T* data_; |
| |
| DISALLOW_COPY_AND_ASSIGN(Vector); |
| }; |
| |
| } // namespace parquet |
| |
| #endif // PARQUET_UTIL_BUFFER_H |