@@ -331,6 +331,82 @@ impl Iter<'_> {
331331 pub fn next_range_back ( & mut self ) -> Option < core:: ops:: RangeInclusive < u32 > > {
332332 next_range_back_impl ( & mut self . front , & mut self . containers , & mut self . back )
333333 }
334+
335+ /// Retrieve the next `dst.len()` values from the iterator and write them into `dst`.
336+ ///
337+ /// Returns the number of values written. This will be less than `dst.len()` only
338+ /// if the iterator is exhausted.
339+ ///
340+ /// This method is significantly faster than calling `next()` repeatedly due to
341+ /// reduced per-element overhead and better CPU cache utilization.
342+ ///
343+ /// # Examples
344+ ///
345+ /// ```rust
346+ /// use roaring::RoaringBitmap;
347+ ///
348+ /// let bitmap: RoaringBitmap = (0..100).collect();
349+ /// let mut iter = bitmap.iter();
350+ /// let mut buf = [0u32; 32];
351+ ///
352+ /// let n = iter.next_many(&mut buf);
353+ /// assert_eq!(n, 32);
354+ /// assert_eq!(buf[0], 0);
355+ /// assert_eq!(buf[31], 31);
356+ ///
357+ /// // Iterate remainder
358+ /// let n = iter.next_many(&mut buf);
359+ /// assert_eq!(n, 32);
360+ /// assert_eq!(buf[0], 32);
361+ /// ```
362+ pub fn next_many ( & mut self , dst : & mut [ u32 ] ) -> usize {
363+ if dst. is_empty ( ) {
364+ return 0 ;
365+ }
366+
367+ let mut count = 0 ;
368+
369+ // First drain from the front container iterator if present
370+ if let Some ( ref mut front_iter) = self . front {
371+ let n = front_iter. next_many ( & mut dst[ count..] ) ;
372+ count += n;
373+ if count >= dst. len ( ) {
374+ return count;
375+ }
376+ // Front is exhausted
377+ self . front = None ;
378+ }
379+
380+ // Process remaining containers
381+ while count < dst. len ( ) {
382+ let Some ( container) = self . containers . next ( ) else {
383+ // No more containers in the middle, try the back
384+ break ;
385+ } ;
386+ let mut container_iter = container. into_iter ( ) ;
387+ let n = container_iter. next_many ( & mut dst[ count..] ) ;
388+ count += n;
389+
390+ // If container still has values, save it as new front
391+ if n > 0 && container_iter. len ( ) > 0 {
392+ self . front = Some ( container_iter) ;
393+ return count;
394+ }
395+ }
396+
397+ // Finally, try draining from the back iterator if present
398+ if count < dst. len ( ) {
399+ if let Some ( ref mut back_iter) = self . back {
400+ let n = back_iter. next_many ( & mut dst[ count..] ) ;
401+ count += n;
402+ if back_iter. len ( ) == 0 {
403+ self . back = None ;
404+ }
405+ }
406+ }
407+
408+ count
409+ }
334410}
335411
336412impl IntoIter {
@@ -419,6 +495,82 @@ impl IntoIter {
419495 pub fn next_range_back ( & mut self ) -> Option < core:: ops:: RangeInclusive < u32 > > {
420496 next_range_back_impl ( & mut self . front , & mut self . containers , & mut self . back )
421497 }
498+
499+ /// Retrieve the next `dst.len()` values from the iterator and write them into `dst`.
500+ ///
501+ /// Returns the number of values written. This will be less than `dst.len()` only
502+ /// if the iterator is exhausted.
503+ ///
504+ /// This method is significantly faster than calling `next()` repeatedly due to
505+ /// reduced per-element overhead and better CPU cache utilization.
506+ ///
507+ /// # Examples
508+ ///
509+ /// ```rust
510+ /// use roaring::RoaringBitmap;
511+ ///
512+ /// let bitmap: RoaringBitmap = (0..100).collect();
513+ /// let mut iter = bitmap.into_iter();
514+ /// let mut buf = [0u32; 32];
515+ ///
516+ /// let n = iter.next_many(&mut buf);
517+ /// assert_eq!(n, 32);
518+ /// assert_eq!(buf[0], 0);
519+ /// assert_eq!(buf[31], 31);
520+ ///
521+ /// // Iterate remainder
522+ /// let n = iter.next_many(&mut buf);
523+ /// assert_eq!(n, 32);
524+ /// assert_eq!(buf[0], 32);
525+ /// ```
526+ pub fn next_many ( & mut self , dst : & mut [ u32 ] ) -> usize {
527+ if dst. is_empty ( ) {
528+ return 0 ;
529+ }
530+
531+ let mut count = 0 ;
532+
533+ // First drain from the front container iterator if present
534+ if let Some ( ref mut front_iter) = self . front {
535+ let n = front_iter. next_many ( & mut dst[ count..] ) ;
536+ count += n;
537+ if count >= dst. len ( ) {
538+ return count;
539+ }
540+ // Front is exhausted
541+ self . front = None ;
542+ }
543+
544+ // Process remaining containers
545+ while count < dst. len ( ) {
546+ let Some ( container) = self . containers . next ( ) else {
547+ // No more containers in the middle, try the back
548+ break ;
549+ } ;
550+ let mut container_iter = container. into_iter ( ) ;
551+ let n = container_iter. next_many ( & mut dst[ count..] ) ;
552+ count += n;
553+
554+ // If container still has values, save it as new front
555+ if n > 0 && container_iter. len ( ) > 0 {
556+ self . front = Some ( container_iter) ;
557+ return count;
558+ }
559+ }
560+
561+ // Finally, try draining from the back iterator if present
562+ if count < dst. len ( ) {
563+ if let Some ( ref mut back_iter) = self . back {
564+ let n = back_iter. next_many ( & mut dst[ count..] ) ;
565+ count += n;
566+ if back_iter. len ( ) == 0 {
567+ self . back = None ;
568+ }
569+ }
570+ }
571+
572+ count
573+ }
422574}
423575
424576fn size_hint_impl (
0 commit comments