This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new f4ed84d88f [python] Avoid materializing row IDs in to_range_list
(#8787)
f4ed84d88f is described below
commit f4ed84d88f21e54a6e3ea1b77aadffb1fa58c9fd
Author: QuakeWang <[email protected]>
AuthorDate: Wed Jul 22 08:53:01 2026 +0800
[python] Avoid materializing row IDs in to_range_list (#8787)
---
.../pypaimon/tests/roaring_bitmap_test.py | 55 ++++++++++++++++++++++
paimon-python/pypaimon/utils/roaring_bitmap.py | 13 +++--
2 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/paimon-python/pypaimon/tests/roaring_bitmap_test.py
b/paimon-python/pypaimon/tests/roaring_bitmap_test.py
new file mode 100644
index 0000000000..4b330b832d
--- /dev/null
+++ b/paimon-python/pypaimon/tests/roaring_bitmap_test.py
@@ -0,0 +1,55 @@
+# 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.
+
+import unittest
+
+from pypaimon.utils.range import Range
+from pypaimon.utils.roaring_bitmap import RoaringBitmap64
+
+
+class RoaringBitmap64Test(unittest.TestCase):
+
+ def test_to_range_list_empty(self):
+ self.assertEqual([], RoaringBitmap64().to_range_list())
+
+ def test_to_range_list_single_value(self):
+ bitmap = RoaringBitmap64()
+ bitmap.add(7)
+
+ self.assertEqual([Range(7, 7)], bitmap.to_range_list())
+
+ def test_to_range_list_multiple_ranges(self):
+ bitmap = RoaringBitmap64()
+ for value in [9, 3, 4, 5, 11]:
+ bitmap.add(value)
+
+ self.assertEqual(
+ [Range(3, 5), Range(9, 9), Range(11, 11)],
+ bitmap.to_range_list(),
+ )
+
+ def test_to_range_list_across_high_bitmap_boundary(self):
+ bitmap = RoaringBitmap64()
+ start = (1 << 32) - 2
+ end = (1 << 32) + 2
+ bitmap.add_range(start, end)
+
+ self.assertEqual([Range(start, end)], bitmap.to_range_list())
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/paimon-python/pypaimon/utils/roaring_bitmap.py
b/paimon-python/pypaimon/utils/roaring_bitmap.py
index ed95c4ab38..4327c3d5f3 100644
--- a/paimon-python/pypaimon/utils/roaring_bitmap.py
+++ b/paimon-python/pypaimon/utils/roaring_bitmap.py
@@ -83,20 +83,19 @@ class RoaringBitmap64:
if self.is_empty():
return []
- # Use pyroaring's efficient iteration
ranges = []
- sorted_values = list(self._data)
- start = sorted_values[0]
+ iterator = iter(self._data)
+ start = next(iterator)
end = start
- for i in range(1, len(sorted_values)):
- if sorted_values[i] == end + 1:
+ for value in iterator:
+ if value == end + 1:
# Consecutive, extend the range
- end = sorted_values[i]
+ end = value
else:
# Gap, close current range and start new one
ranges.append(Range(start, end))
- start = sorted_values[i]
+ start = value
end = start
# Add the last range