Skip to content

Commit 036dd3a

Browse files
authored
feat: add RoaringBitmap32, RoaringBitmap64, and BitSet utilities (#35)
1 parent ca728c7 commit 036dd3a

9 files changed

Lines changed: 2313 additions & 0 deletions

File tree

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
#include <cstddef>
21+
#include <cstdint>
22+
#include <limits>
23+
#include <string>
24+
#include <vector>
25+
26+
#include "paimon/io/byte_array_input_stream.h"
27+
#include "paimon/memory/bytes.h"
28+
#include "paimon/memory/memory_pool.h"
29+
#include "paimon/status.h"
30+
#include "paimon/visibility.h"
31+
32+
namespace paimon {
33+
class ByteArrayInputStream;
34+
class RoaringBitmap64;
35+
36+
/// A compressed bitmap for 32-bit integer.
37+
class PAIMON_EXPORT RoaringBitmap32 {
38+
public:
39+
RoaringBitmap32();
40+
~RoaringBitmap32();
41+
42+
RoaringBitmap32(const RoaringBitmap32&) noexcept;
43+
RoaringBitmap32& operator=(const RoaringBitmap32&) noexcept;
44+
45+
RoaringBitmap32(RoaringBitmap32&&) noexcept;
46+
RoaringBitmap32& operator=(RoaringBitmap32&&) noexcept;
47+
48+
class PAIMON_EXPORT Iterator {
49+
public:
50+
friend class RoaringBitmap32;
51+
explicit Iterator(const RoaringBitmap32& bitmap);
52+
~Iterator();
53+
Iterator(const Iterator&) noexcept;
54+
Iterator(Iterator&&) noexcept;
55+
Iterator& operator=(const Iterator&) noexcept;
56+
Iterator& operator=(Iterator&&) noexcept;
57+
58+
/// Return the current value of iterator.
59+
int32_t operator*() const;
60+
/// Move the iterator to next value.
61+
Iterator& operator++();
62+
bool operator==(const Iterator& other) const;
63+
bool operator!=(const Iterator& other) const;
64+
65+
private:
66+
void* iterator_ = nullptr;
67+
};
68+
69+
static constexpr int32_t MAX_VALUE = std::numeric_limits<int32_t>::max();
70+
71+
/// @param x value added to bitmap
72+
void Add(int32_t x);
73+
74+
/// @param x value added to bitmap
75+
/// @return false if contain x; true if not contain x
76+
bool CheckedAdd(int32_t x);
77+
78+
/// @return true if contain x; false if not contain x
79+
bool Contains(int32_t x) const;
80+
81+
/// @return true if bitmap is empty
82+
bool IsEmpty() const;
83+
84+
/// @return the cardinality of bitmap, i.e., the number of unique value added
85+
int32_t Cardinality() const;
86+
87+
/// Computes the negation of the roaring bitmap within the half-open interval [min, max).
88+
/// Areas outside the interval are unchanged.
89+
void Flip(int32_t min, int32_t max);
90+
91+
/// Adds all values in the half-open interval [min, max).
92+
void AddRange(int32_t min, int32_t max);
93+
94+
/// Removes all values in the half-open interval [min, max).
95+
void RemoveRange(int32_t min, int32_t max);
96+
97+
/// Contain any value in the half-open interval [min, max).
98+
bool ContainsAny(int32_t min, int32_t max) const;
99+
100+
/// Serialize bitmap to bytes.
101+
/// @note Cannot accurately compare the output byte streams with Java and C++ versions,
102+
/// as the `runOptimize` function of roaring bitmap may optimize consecutive integers
103+
/// differently.
104+
PAIMON_UNIQUE_PTR<Bytes> Serialize(MemoryPool* pool) const;
105+
106+
/// Deserialize bitmap from input stream.
107+
Status Deserialize(ByteArrayInputStream* input_stream);
108+
109+
/// Deserialize bitmap from buffer with begin and length.
110+
Status Deserialize(const char* begin, size_t length);
111+
112+
/// @return How many bytes are required to serialize this bitmap.
113+
size_t GetSizeInBytes() const;
114+
115+
bool operator==(const RoaringBitmap32& other) const noexcept;
116+
117+
/// Compute the union of the current bitmap and the provided bitmap,
118+
/// writing the result in the current bitmap. The provided bitmap is not
119+
/// modified.
120+
RoaringBitmap32& operator|=(const RoaringBitmap32& other);
121+
122+
/// Compute the intersection of the current bitmap and the provided bitmap,
123+
/// writing the result in the current bitmap. The provided bitmap is not
124+
/// modified.
125+
/// @note If you are computing the intersection between several
126+
/// bitmaps, two-by-two, it is best to start with the smallest bitmap.
127+
RoaringBitmap32& operator&=(const RoaringBitmap32& other);
128+
129+
/// Compute the difference of the current bitmap and the provided bitmap,
130+
/// writing the result in the current bitmap. The provided bitmap is not
131+
/// modified.
132+
RoaringBitmap32& operator-=(const RoaringBitmap32& other);
133+
134+
std::string ToString() const;
135+
136+
Iterator Begin() const;
137+
Iterator End() const;
138+
/// @return the iterator moved to the value which is equal or larger than key
139+
Iterator EqualOrLarger(int32_t key) const;
140+
141+
/// Computes the intersection between two bitmaps and returns new bitmap.
142+
/// The current bitmap and the provided bitmap are unchanged.
143+
///
144+
/// @note If you are computing the intersection between several bitmaps, two-by-two, it is best
145+
/// to start with the smallest bitmap. Consider also using the operator &= to avoid needlessly
146+
/// creating many temporary bitmaps.
147+
static RoaringBitmap32 And(const RoaringBitmap32& lhs, const RoaringBitmap32& rhs);
148+
149+
/// Computes the union between two bitmaps and returns new bitmap.
150+
/// The current bitmap and the provided bitmap are unchanged.
151+
static RoaringBitmap32 Or(const RoaringBitmap32& lhs, const RoaringBitmap32& rhs);
152+
153+
/// Computes the difference between two bitmaps and returns new bitmap.
154+
/// The current bitmap and the provided bitmap are unchanged.
155+
static RoaringBitmap32 AndNot(const RoaringBitmap32& lhs, const RoaringBitmap32& rhs);
156+
157+
/// @return a bitmap contains input values
158+
static RoaringBitmap32 From(const std::vector<int32_t>& values);
159+
160+
/// Fast union multiple bitmaps.
161+
static RoaringBitmap32 FastUnion(const std::vector<const RoaringBitmap32*>& inputs);
162+
163+
/// Fast union multiple bitmaps.
164+
static RoaringBitmap32 FastUnion(const std::vector<RoaringBitmap32>& inputs);
165+
166+
friend class RoaringBitmap64;
167+
168+
private:
169+
void* roaring_bitmap_ = nullptr;
170+
};
171+
} // namespace paimon
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
#include <cstddef>
21+
#include <cstdint>
22+
#include <limits>
23+
#include <string>
24+
#include <vector>
25+
26+
#include "paimon/io/byte_array_input_stream.h"
27+
#include "paimon/memory/bytes.h"
28+
#include "paimon/memory/memory_pool.h"
29+
#include "paimon/status.h"
30+
#include "paimon/utils/roaring_bitmap32.h"
31+
#include "paimon/visibility.h"
32+
33+
namespace paimon {
34+
class ByteArrayInputStream;
35+
36+
/// A compressed bitmap for 64-bit integer.
37+
class PAIMON_EXPORT RoaringBitmap64 {
38+
public:
39+
RoaringBitmap64();
40+
~RoaringBitmap64();
41+
42+
RoaringBitmap64(const RoaringBitmap64&) noexcept;
43+
RoaringBitmap64& operator=(const RoaringBitmap64&) noexcept;
44+
45+
RoaringBitmap64(RoaringBitmap64&&) noexcept;
46+
RoaringBitmap64& operator=(RoaringBitmap64&&) noexcept;
47+
48+
explicit RoaringBitmap64(const RoaringBitmap32&) noexcept;
49+
RoaringBitmap64& operator=(const RoaringBitmap32&) noexcept;
50+
51+
class PAIMON_EXPORT Iterator {
52+
public:
53+
friend class RoaringBitmap64;
54+
explicit Iterator(const RoaringBitmap64& bitmap);
55+
~Iterator();
56+
Iterator(const Iterator&) noexcept;
57+
Iterator(Iterator&&) noexcept;
58+
Iterator& operator=(const Iterator&) noexcept;
59+
Iterator& operator=(Iterator&&) noexcept;
60+
61+
/// Return the current value of iterator.
62+
int64_t operator*() const;
63+
/// Move the iterator to next value.
64+
Iterator& operator++();
65+
bool operator==(const Iterator& other) const;
66+
bool operator!=(const Iterator& other) const;
67+
/// Move the iterator to the value which is equal or larger than input value
68+
void EqualOrLarger(int64_t value);
69+
70+
private:
71+
void* iterator_ = nullptr;
72+
};
73+
74+
static constexpr int64_t MAX_VALUE = std::numeric_limits<int64_t>::max();
75+
76+
/// @param x value added to bitmap
77+
void Add(int64_t x);
78+
79+
/// Bulk-insert `n` values into the bitmap.
80+
///
81+
/// Compared to repeatedly calling `Add`, this implementation:
82+
/// 1. Buckets the input values by their high-32 bits in a single pass.
83+
/// 2. Feeds each bucket to the inner 32-bit Roaring's true-batch
84+
/// `addMany(uint32_t*)` path, which performs container-level bulk
85+
/// insertion.
86+
///
87+
/// This avoids the per-value `std::map` lookup of the 64-bit wrapper and
88+
/// the per-value insertion overhead inside the 32-bit array container.
89+
/// Values may be unsorted; ordering is handled internally.
90+
void AddMany(size_t n, const int64_t* values);
91+
92+
/// @param x value added to bitmap
93+
/// @return false if contain x; true if not contain x
94+
bool CheckedAdd(int64_t x);
95+
96+
/// @return true if contain x; false if not contain x
97+
bool Contains(int64_t x) const;
98+
99+
/// @return true if bitmap is empty
100+
bool IsEmpty() const;
101+
102+
/// @return the cardinality of bitmap, i.e., the number of unique value added
103+
int64_t Cardinality() const;
104+
105+
/// Computes the negation of the roaring bitmap within the half-open interval [min, max).
106+
/// Areas outside the interval are unchanged.
107+
void Flip(int64_t min, int64_t max);
108+
109+
/// Adds all values in the half-open interval [min, max).
110+
void AddRange(int64_t min, int64_t max);
111+
112+
/// Removes all values in the half-open interval [min, max).
113+
void RemoveRange(int64_t min, int64_t max);
114+
115+
/// Contain any value in the half-open interval [min, max).
116+
bool ContainsAny(int64_t min, int64_t max) const;
117+
118+
/// Serialize bitmap to bytes.
119+
PAIMON_UNIQUE_PTR<Bytes> Serialize(MemoryPool* pool) const;
120+
121+
/// Deserialize bitmap from input stream.
122+
Status Deserialize(ByteArrayInputStream* input_stream);
123+
124+
/// Deserialize bitmap from buffer with begin and length.
125+
Status Deserialize(const char* begin, size_t length);
126+
127+
/// @return How many bytes are required to serialize this bitmap.
128+
size_t GetSizeInBytes() const;
129+
130+
bool operator==(const RoaringBitmap64& other) const noexcept;
131+
132+
/// Compute the union of the current bitmap and the provided bitmap,
133+
/// writing the result in the current bitmap. The provided bitmap is not
134+
/// modified.
135+
RoaringBitmap64& operator|=(const RoaringBitmap64& other);
136+
137+
/// Compute the intersection of the current bitmap and the provided bitmap,
138+
/// writing the result in the current bitmap. The provided bitmap is not
139+
/// modified.
140+
/// @note If you are computing the intersection between several
141+
/// bitmaps, two-by-two, it is best to start with the smallest bitmap.
142+
RoaringBitmap64& operator&=(const RoaringBitmap64& other);
143+
144+
/// Compute the difference of the current bitmap and the provided bitmap,
145+
/// writing the result in the current bitmap. The provided bitmap is not
146+
/// modified.
147+
RoaringBitmap64& operator-=(const RoaringBitmap64& other);
148+
149+
std::string ToString() const;
150+
151+
Iterator Begin() const;
152+
Iterator End() const;
153+
/// @return the iterator moved to the value which is equal or larger than key
154+
Iterator EqualOrLarger(int64_t key) const;
155+
156+
/// Computes the intersection between two bitmaps and returns new bitmap.
157+
/// The current bitmap and the provided bitmap are unchanged.
158+
///
159+
/// @note If you are computing the intersection between several bitmaps, two-by-two, it is best
160+
/// to start with the smallest bitmap. Consider also using the operator &= to avoid needlessly
161+
/// creating many temporary bitmaps.
162+
static RoaringBitmap64 And(const RoaringBitmap64& lhs, const RoaringBitmap64& rhs);
163+
164+
/// Computes the union between two bitmaps and returns new bitmap.
165+
/// The current bitmap and the provided bitmap are unchanged.
166+
static RoaringBitmap64 Or(const RoaringBitmap64& lhs, const RoaringBitmap64& rhs);
167+
168+
/// Computes the difference between two bitmaps and returns new bitmap.
169+
/// The current bitmap and the provided bitmap are unchanged.
170+
static RoaringBitmap64 AndNot(const RoaringBitmap64& lhs, const RoaringBitmap64& rhs);
171+
172+
/// @return a bitmap contains input values
173+
static RoaringBitmap64 From(const std::vector<int64_t>& values);
174+
175+
/// Fast union multiple bitmaps.
176+
static RoaringBitmap64 FastUnion(const std::vector<const RoaringBitmap64*>& inputs);
177+
178+
/// Fast union multiple bitmaps.
179+
static RoaringBitmap64 FastUnion(const std::vector<RoaringBitmap64>& inputs);
180+
181+
private:
182+
void* roaring_bitmap_ = nullptr;
183+
};
184+
} // namespace paimon

0 commit comments

Comments
 (0)