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

Reply via email to