blob: de642655297bf729797e80fd36b999d5e738a21a [file] [log] [blame]
// 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