blob: af5214b4054a78cfdb4bde7778210281faed0c0e [file]
/*
* 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 "paimon/utils/roaring_bitmap32.h"
#include <cassert>
#include <memory>
#include <utility>
#include "paimon/fs/file_system.h"
#include "paimon/io/byte_array_input_stream.h"
#include "paimon/result.h"
#include "roaring.hh" // NOLINT(build/include_subdir)
namespace paimon {
namespace {
roaring::Roaring::const_iterator& GetIterator(void* iter) {
return *(static_cast<roaring::Roaring::const_iterator*>(iter));
}
roaring::Roaring& GetRoaringBitmap(void* bitmap) {
return *(static_cast<roaring::Roaring*>(bitmap));
}
} // namespace
RoaringBitmap32::Iterator::Iterator(const RoaringBitmap32& bitmap) {
iterator_ =
new roaring::Roaring::const_iterator(GetRoaringBitmap(bitmap.roaring_bitmap_).begin());
}
RoaringBitmap32::Iterator::~Iterator() {
if (iterator_) {
delete static_cast<roaring::Roaring::const_iterator*>(iterator_);
}
}
RoaringBitmap32::Iterator::Iterator(const RoaringBitmap32::Iterator& other) noexcept {
*this = other;
}
RoaringBitmap32::Iterator& RoaringBitmap32::Iterator::operator=(
const RoaringBitmap32::Iterator& other) noexcept {
if (&other == this) {
return *this;
}
if (!iterator_) {
iterator_ = new roaring::Roaring::const_iterator(GetIterator(other.iterator_));
} else {
GetIterator(iterator_) = GetIterator(other.iterator_);
}
return *this;
}
RoaringBitmap32::Iterator::Iterator(RoaringBitmap32::Iterator&& other) noexcept {
*this = std::move(other);
}
RoaringBitmap32::Iterator& RoaringBitmap32::Iterator::operator=(
RoaringBitmap32::Iterator&& other) noexcept {
if (&other == this) {
return *this;
}
if (iterator_) {
delete static_cast<roaring::Roaring::const_iterator*>(iterator_);
}
iterator_ = other.iterator_;
other.iterator_ = nullptr;
return *this;
}
int32_t RoaringBitmap32::Iterator::operator*() const {
return *GetIterator(iterator_);
}
RoaringBitmap32::Iterator& RoaringBitmap32::Iterator::operator++() {
++GetIterator(iterator_);
return *this;
}
bool RoaringBitmap32::Iterator::operator==(const Iterator& other) const {
if (&other == this) {
return true;
}
assert(iterator_ && other.iterator_);
return GetIterator(iterator_) == GetIterator(other.iterator_);
}
bool RoaringBitmap32::Iterator::operator!=(const Iterator& other) const {
return !(*this == other);
}
RoaringBitmap32::RoaringBitmap32() {
roaring_bitmap_ = new roaring::Roaring();
}
RoaringBitmap32::~RoaringBitmap32() {
if (roaring_bitmap_) {
delete static_cast<roaring::Roaring*>(roaring_bitmap_);
}
}
RoaringBitmap32::RoaringBitmap32(const RoaringBitmap32& other) noexcept {
*this = other;
}
RoaringBitmap32& RoaringBitmap32::operator=(const RoaringBitmap32& other) noexcept {
if (&other == this) {
return *this;
}
if (!roaring_bitmap_) {
roaring_bitmap_ = new roaring::Roaring(GetRoaringBitmap(other.roaring_bitmap_));
} else {
GetRoaringBitmap(roaring_bitmap_) = GetRoaringBitmap(other.roaring_bitmap_);
}
return *this;
}
RoaringBitmap32::RoaringBitmap32(RoaringBitmap32&& other) noexcept {
*this = std::move(other);
}
RoaringBitmap32& RoaringBitmap32::operator=(RoaringBitmap32&& other) noexcept {
if (&other == this) {
return *this;
}
if (roaring_bitmap_) {
delete static_cast<roaring::Roaring*>(roaring_bitmap_);
}
roaring_bitmap_ = other.roaring_bitmap_;
other.roaring_bitmap_ = nullptr;
return *this;
}
RoaringBitmap32& RoaringBitmap32::operator|=(const RoaringBitmap32& other) {
GetRoaringBitmap(roaring_bitmap_) |= GetRoaringBitmap(other.roaring_bitmap_);
return *this;
}
RoaringBitmap32& RoaringBitmap32::operator&=(const RoaringBitmap32& other) {
GetRoaringBitmap(roaring_bitmap_) &= GetRoaringBitmap(other.roaring_bitmap_);
return *this;
}
RoaringBitmap32& RoaringBitmap32::operator-=(const RoaringBitmap32& other) {
GetRoaringBitmap(roaring_bitmap_) -= GetRoaringBitmap(other.roaring_bitmap_);
return *this;
}
void RoaringBitmap32::Add(int32_t x) {
GetRoaringBitmap(roaring_bitmap_).add(x);
}
void RoaringBitmap32::AddRange(int32_t min, int32_t max) {
GetRoaringBitmap(roaring_bitmap_).addRange(min, max);
}
void RoaringBitmap32::RemoveRange(int32_t min, int32_t max) {
GetRoaringBitmap(roaring_bitmap_).removeRange(min, max);
}
bool RoaringBitmap32::ContainsAny(int32_t min, int32_t max) const {
auto iter = EqualOrLarger(min);
if (iter != End() && *iter < max) {
return true;
}
return false;
}
bool RoaringBitmap32::CheckedAdd(int32_t x) {
if (Contains(x)) {
return false;
}
Add(x);
return true;
}
int32_t RoaringBitmap32::Cardinality() const {
return GetRoaringBitmap(roaring_bitmap_).cardinality();
}
bool RoaringBitmap32::Contains(int32_t x) const {
return GetRoaringBitmap(roaring_bitmap_).contains(x);
}
bool RoaringBitmap32::IsEmpty() const {
return GetRoaringBitmap(roaring_bitmap_).isEmpty();
}
size_t RoaringBitmap32::GetSizeInBytes() const {
return GetRoaringBitmap(roaring_bitmap_).getSizeInBytes();
}
void RoaringBitmap32::Flip(int32_t min, int32_t max) {
GetRoaringBitmap(roaring_bitmap_).flip(min, max);
}
bool RoaringBitmap32::operator==(const RoaringBitmap32& other) const noexcept {
if (this == &other) {
return true;
}
assert(roaring_bitmap_ && other.roaring_bitmap_);
return GetRoaringBitmap(roaring_bitmap_) == GetRoaringBitmap(other.roaring_bitmap_);
}
PAIMON_UNIQUE_PTR<Bytes> RoaringBitmap32::Serialize(MemoryPool* pool) const {
GetRoaringBitmap(roaring_bitmap_).runOptimize();
auto& bitmap = GetRoaringBitmap(roaring_bitmap_);
// Use default pool if no pool is provided
if (pool == nullptr) {
pool = GetDefaultPool().get();
}
auto bytes = Bytes::AllocateBytes(bitmap.getSizeInBytes(), pool);
bitmap.write(bytes->data());
return bytes;
}
Status RoaringBitmap32::Deserialize(ByteArrayInputStream* input_stream) {
const char* data = input_stream->GetRawData();
PAIMON_ASSIGN_OR_RAISE(int64_t pos, input_stream->GetPos());
PAIMON_ASSIGN_OR_RAISE(int64_t total_length, input_stream->Length());
try {
GetRoaringBitmap(roaring_bitmap_) =
roaring::Roaring::readSafe(data, /*maxbytes=*/total_length - pos);
} catch (...) {
return Status::Invalid("catch exception in Deserialize() of RoaringBitmap32");
}
return input_stream->Seek(GetRoaringBitmap(roaring_bitmap_).getSizeInBytes(),
SeekOrigin::FS_SEEK_CUR);
}
Status RoaringBitmap32::Deserialize(const char* begin, size_t length) {
try {
GetRoaringBitmap(roaring_bitmap_) = roaring::Roaring::readSafe(begin, length);
} catch (...) {
return Status::Invalid("catch exception in Deserialize() of RoaringBitmap32");
}
return Status::OK();
}
std::string RoaringBitmap32::ToString() const {
return GetRoaringBitmap(roaring_bitmap_).toString();
}
RoaringBitmap32 RoaringBitmap32::And(const RoaringBitmap32& lhs, const RoaringBitmap32& rhs) {
RoaringBitmap32 res;
GetRoaringBitmap(res.roaring_bitmap_) =
(GetRoaringBitmap(lhs.roaring_bitmap_) & GetRoaringBitmap(rhs.roaring_bitmap_));
return res;
}
RoaringBitmap32 RoaringBitmap32::Or(const RoaringBitmap32& lhs, const RoaringBitmap32& rhs) {
RoaringBitmap32 res;
GetRoaringBitmap(res.roaring_bitmap_) =
(GetRoaringBitmap(lhs.roaring_bitmap_) | GetRoaringBitmap(rhs.roaring_bitmap_));
return res;
}
RoaringBitmap32 RoaringBitmap32::AndNot(const RoaringBitmap32& lhs, const RoaringBitmap32& rhs) {
RoaringBitmap32 res;
GetRoaringBitmap(res.roaring_bitmap_) =
(GetRoaringBitmap(lhs.roaring_bitmap_) - GetRoaringBitmap(rhs.roaring_bitmap_));
return res;
}
RoaringBitmap32 RoaringBitmap32::From(const std::vector<int32_t>& values) {
RoaringBitmap32 res;
for (const auto& value : values) {
res.Add(value);
}
return res;
}
RoaringBitmap32 RoaringBitmap32::FastUnion(const std::vector<const RoaringBitmap32*>& inputs) {
std::vector<roaring::Roaring*> roaring_inputs;
roaring_inputs.reserve(inputs.size());
for (const auto* roaring : inputs) {
roaring_inputs.push_back(&GetRoaringBitmap(roaring->roaring_bitmap_));
}
RoaringBitmap32 res;
GetRoaringBitmap(res.roaring_bitmap_) = roaring::Roaring::fastunion(
roaring_inputs.size(), const_cast<const roaring::Roaring**>(roaring_inputs.data()));
return res;
}
RoaringBitmap32 RoaringBitmap32::FastUnion(const std::vector<RoaringBitmap32>& inputs) {
std::vector<const RoaringBitmap32*> inputs_ptr;
inputs_ptr.reserve(inputs.size());
for (const auto& bitmap : inputs) {
inputs_ptr.push_back(&bitmap);
}
return FastUnion(inputs_ptr);
}
RoaringBitmap32::Iterator RoaringBitmap32::Begin() const {
return RoaringBitmap32::Iterator(*this);
}
RoaringBitmap32::Iterator RoaringBitmap32::End() const {
RoaringBitmap32::Iterator iter(*this);
GetIterator(iter.iterator_) = GetRoaringBitmap(roaring_bitmap_).end();
return iter;
}
RoaringBitmap32::Iterator RoaringBitmap32::EqualOrLarger(int32_t key) const {
RoaringBitmap32::Iterator iter(*this);
GetIterator(iter.iterator_).equalorlarger(key);
return iter;
}
} // namespace paimon