@@ -91,7 +91,15 @@ fn merge(
91
91
index : & Index ,
92
92
mut segment_entries : Vec < SegmentEntry > ,
93
93
target_opstamp : Opstamp ,
94
- ) -> crate :: Result < SegmentEntry > {
94
+ ) -> crate :: Result < Option < SegmentEntry > > {
95
+ let num_docs = segment_entries
96
+ . iter ( )
97
+ . map ( |segment| segment. meta ( ) . num_docs ( ) as u64 )
98
+ . sum :: < u64 > ( ) ;
99
+ if num_docs == 0 {
100
+ return Ok ( None ) ;
101
+ }
102
+
95
103
// first we need to apply deletes to our segment.
96
104
let merged_segment = index. new_segment ( ) ;
97
105
@@ -120,7 +128,7 @@ fn merge(
120
128
let merged_segment_id = merged_segment. id ( ) ;
121
129
122
130
let segment_meta = index. new_segment_meta ( merged_segment_id, num_docs) ;
123
- Ok ( SegmentEntry :: new ( segment_meta, delete_cursor, None ) )
131
+ Ok ( Some ( SegmentEntry :: new ( segment_meta, delete_cursor, None ) ) )
124
132
}
125
133
126
134
/// Advanced: Merges a list of segments from different indices in a new index.
@@ -475,7 +483,7 @@ impl SegmentUpdater {
475
483
// suggested and the moment when it ended up being executed.)
476
484
//
477
485
// `segment_ids` is required to be non-empty.
478
- pub fn start_merge ( & self , merge_operation : MergeOperation ) -> FutureResult < SegmentMeta > {
486
+ pub fn start_merge ( & self , merge_operation : MergeOperation ) -> FutureResult < ( ) > {
479
487
assert ! (
480
488
!merge_operation. segment_ids( ) . is_empty( ) ,
481
489
"Segment_ids cannot be empty."
@@ -512,18 +520,19 @@ impl SegmentUpdater {
512
520
merge_operation. target_opstamp ( ) ,
513
521
) {
514
522
Ok ( after_merge_segment_entry) => {
515
- let segment_meta_res =
516
- segment_updater. end_merge ( merge_operation, after_merge_segment_entry) ;
517
- let _send_result = merging_future_send. send ( segment_meta_res) ;
523
+ let res = segment_updater. end_merge ( merge_operation, after_merge_segment_entry) ;
524
+ let _send_result = merging_future_send. send ( res) ;
518
525
}
519
526
Err ( merge_error) => {
520
527
warn ! (
521
528
"Merge of {:?} was cancelled: {:?}" ,
522
529
merge_operation. segment_ids( ) . to_vec( ) ,
523
530
merge_error
524
531
) ;
532
+ if cfg ! ( test) {
533
+ panic ! ( "{:?}" , merge_error) ;
534
+ }
525
535
let _send_result = merging_future_send. send ( Err ( merge_error) ) ;
526
- assert ! ( !cfg!( test) , "Merge failed." ) ;
527
536
}
528
537
}
529
538
} ) ;
@@ -573,35 +582,39 @@ impl SegmentUpdater {
573
582
fn end_merge (
574
583
& self ,
575
584
merge_operation : MergeOperation ,
576
- mut after_merge_segment_entry : SegmentEntry ,
577
- ) -> crate :: Result < SegmentMeta > {
585
+ mut after_merge_segment_entry : Option < SegmentEntry > ,
586
+ ) -> crate :: Result < ( ) > {
578
587
let segment_updater = self . clone ( ) ;
579
- let after_merge_segment_meta = after_merge_segment_entry. meta ( ) . clone ( ) ;
580
588
self . schedule_task ( move || {
581
- info ! ( "End merge {:?}" , after_merge_segment_entry. meta( ) ) ;
589
+ info ! (
590
+ "End merge {:?}" ,
591
+ after_merge_segment_entry. as_ref( ) . map( |entry| entry. meta( ) )
592
+ ) ;
582
593
{
583
- let mut delete_cursor = after_merge_segment_entry. delete_cursor ( ) . clone ( ) ;
584
- if let Some ( delete_operation) = delete_cursor. get ( ) {
585
- let committed_opstamp = segment_updater. load_meta ( ) . opstamp ;
586
- if delete_operation. opstamp < committed_opstamp {
587
- let index = & segment_updater. index ;
588
- let segment = index. segment ( after_merge_segment_entry. meta ( ) . clone ( ) ) ;
589
- if let Err ( advance_deletes_err) = advance_deletes (
590
- segment,
591
- & mut after_merge_segment_entry,
592
- committed_opstamp,
593
- ) {
594
- error ! (
595
- "Merge of {:?} was cancelled (advancing deletes failed): {:?}" ,
596
- merge_operation. segment_ids( ) ,
597
- advance_deletes_err
598
- ) ;
599
- assert ! ( !cfg!( test) , "Merge failed." ) ;
600
-
601
- // ... cancel merge
602
- // `merge_operations` are tracked. As it is dropped, the
603
- // the segment_ids will be available again for merge.
604
- return Err ( advance_deletes_err) ;
594
+ if let Some ( mut after_merge_segment_entry) = after_merge_segment_entry. as_mut ( ) {
595
+ let mut delete_cursor = after_merge_segment_entry. delete_cursor ( ) . clone ( ) ;
596
+ if let Some ( delete_operation) = delete_cursor. get ( ) {
597
+ let committed_opstamp = segment_updater. load_meta ( ) . opstamp ;
598
+ if delete_operation. opstamp < committed_opstamp {
599
+ let index = & segment_updater. index ;
600
+ let segment = index. segment ( after_merge_segment_entry. meta ( ) . clone ( ) ) ;
601
+ if let Err ( advance_deletes_err) = advance_deletes (
602
+ segment,
603
+ & mut after_merge_segment_entry,
604
+ committed_opstamp,
605
+ ) {
606
+ error ! (
607
+ "Merge of {:?} was cancelled (advancing deletes failed): {:?}" ,
608
+ merge_operation. segment_ids( ) ,
609
+ advance_deletes_err
610
+ ) ;
611
+ assert ! ( !cfg!( test) , "Merge failed." ) ;
612
+
613
+ // ... cancel merge
614
+ // `merge_operations` are tracked. As it is dropped, the
615
+ // the segment_ids will be available again for merge.
616
+ return Err ( advance_deletes_err) ;
617
+ }
605
618
}
606
619
}
607
620
}
@@ -622,7 +635,7 @@ impl SegmentUpdater {
622
635
Ok ( ( ) )
623
636
} )
624
637
. wait ( ) ?;
625
- Ok ( after_merge_segment_meta )
638
+ Ok ( ( ) )
626
639
}
627
640
628
641
/// Wait for current merging threads.
0 commit comments