@@ -65,7 +65,7 @@ start_link(#{name := Name} = Config) ->
65
65
gen_server :start_link ({local , Name }, ? MODULE , [Config ], []).
66
66
67
67
-spec accept_mem_tables (atom () | pid (),
68
- #{ra_uid () => [{ets :tid (), ra : range ()}]},
68
+ #{ra_uid () => [{ets :tid (), ra_seq : state ()}]},
69
69
string ()) -> ok .
70
70
accept_mem_tables (_SegmentWriter , Tables , undefined )
71
71
when map_size (Tables ) == 0 ->
@@ -261,7 +261,7 @@ get_overview(#state{data_dir = Dir,
261
261
#{data_dir => Dir ,
262
262
segment_conf => Conf }.
263
263
264
- flush_mem_table_ranges ({ServerUId , TidRanges0 },
264
+ flush_mem_table_ranges ({ServerUId , TidSeqs0 },
265
265
# state {system = System } = State ) ->
266
266
SmallestIdx = smallest_live_idx (ServerUId ),
267
267
% % TidRanges arrive here sorted new -> old.
@@ -270,31 +270,32 @@ flush_mem_table_ranges({ServerUId, TidRanges0},
270
270
% % list of tid ranges to flush to disk
271
271
% % now TidRanges are sorted old -> new, i.e the correct order of
272
272
% % processing
273
- TidRanges = lists :foldl (
274
- fun ({T , Range0 }, []) ->
275
- case ra_range :truncate (SmallestIdx - 1 , Range0 ) of
276
- undefined ->
277
- [];
278
- Range ->
279
- [{T , Range }]
280
- end ;
281
- ({T , Range0 }, [{_T , {Start , _ }} | _ ] = Acc ) ->
282
- Range1 = ra_range :truncate (SmallestIdx - 1 , Range0 ),
283
- case ra_range :limit (Start , Range1 ) of
284
- undefined ->
285
- Acc ;
286
- Range ->
287
- [{T , Range } | Acc ]
288
- end
289
- end , [], TidRanges0 ),
273
+ TidSeqs = lists :foldl (
274
+ fun ({T , Seq0 }, []) ->
275
+ case ra_seq :floor (SmallestIdx , Seq0 ) of
276
+ undefined ->
277
+ [];
278
+ Seq ->
279
+ [{T , Seq }]
280
+ end ;
281
+ ({T , Seq0 }, [{_T , PrevSeq } | _ ] = Acc ) ->
282
+ Start = ra_seq :first (PrevSeq ),
283
+ Seq1 = ra_seq :floor (SmallestIdx , Seq0 ),
284
+ case ra_seq :limit (Start , Seq1 ) of
285
+ undefined ->
286
+ Acc ;
287
+ Seq ->
288
+ [{T , Seq } | Acc ]
289
+ end
290
+ end , [], TidSeqs0 ),
290
291
291
292
SegRefs0 = lists :append (
292
293
lists :reverse (
293
294
% % segrefs are returned in appended order so new -> old
294
295
% % so we need to reverse them so that the final appended list
295
296
% % of segrefs is in the old -> new order
296
- [flush_mem_table_range (ServerUId , TidRange , State )
297
- || TidRange <- TidRanges ])),
297
+ [flush_mem_table_range (ServerUId , TidSeq , State )
298
+ || TidSeq <- TidSeqs ])),
298
299
299
300
% % compact cases where a segment was appended in a subsequent call to
300
301
% % flush_mem_table_range
@@ -308,14 +309,14 @@ flush_mem_table_ranges({ServerUId, TidRanges0},
308
309
[Seg | Acc ]
309
310
end , [], SegRefs0 )),
310
311
311
- ok = send_segments (System , ServerUId , TidRanges0 , SegRefs ),
312
+ ok = send_segments (System , ServerUId , TidSeqs0 , SegRefs ),
312
313
ok .
313
314
314
- flush_mem_table_range (ServerUId , {Tid , { StartIdx0 , EndIdx } },
315
+ flush_mem_table_range (ServerUId , {Tid , Seq },
315
316
# state {data_dir = DataDir ,
316
317
segment_conf = SegConf } = State ) ->
317
318
Dir = filename :join (DataDir , binary_to_list (ServerUId )),
318
- StartIdx = start_index (ServerUId , StartIdx0 ),
319
+ % StartIdx = start_index(ServerUId, StartIdx0),
319
320
case open_file (Dir , SegConf ) of
320
321
enoent ->
321
322
? DEBUG (" segment_writer: skipping segment as directory ~ts does "
@@ -324,8 +325,7 @@ flush_mem_table_range(ServerUId, {Tid, {StartIdx0, EndIdx}},
324
325
% % clean up the tables for this process
325
326
[];
326
327
Segment0 ->
327
- case append_to_segment (ServerUId , Tid , StartIdx , EndIdx ,
328
- Segment0 , State ) of
328
+ case append_to_segment (ServerUId , Tid , Seq , Segment0 , State ) of
329
329
undefined ->
330
330
? WARN (" segment_writer: skipping segments for ~w as
331
331
directory ~ts disappeared whilst writing" ,
@@ -366,31 +366,37 @@ send_segments(System, ServerUId, TidRanges, SegRefs) ->
366
366
[ServerUId , " No Pid" ]),
367
367
% % delete from the memtable on the non-running server's behalf
368
368
[begin
369
+ % % TODO: HACK: this is a hack to get a full range out of a
370
+ % % sequent, ideally the mt should take the ra_seq and
371
+ % % delete from that
372
+ Range = {ra_seq :first (Seq ), ra_seq :last (Seq )},
369
373
_ = catch ra_mt :delete ({range , Tid , Range })
370
- end || {Tid , Range } <- TidRanges ],
374
+ end || {Tid , Seq } <- TidRanges ],
371
375
ok ;
372
376
Pid ->
373
377
Pid ! {ra_log_event , {segments , TidRanges , SegRefs }},
374
378
ok
375
379
end .
376
380
377
- append_to_segment (UId , Tid , StartIdx0 , EndIdx , Seg , State ) ->
378
- StartIdx = start_index (UId , StartIdx0 ),
379
- % EndIdx + 1 because FP
380
- append_to_segment (UId , Tid , StartIdx , EndIdx + 1 , Seg , [], State ).
381
+ append_to_segment (UId , Tid , Seq0 , Seg , State ) ->
382
+ FirstIdx = ra_seq :first (Seq0 ),
383
+ StartIdx = start_index (UId , FirstIdx ),
384
+ % % TODO combine flor and iterator into one operation
385
+ Seq = ra_seq :floor (StartIdx , Seq0 ),
386
+ SeqIter = ra_seq :iterator (Seq ),
387
+ append_to_segment (UId , Tid , ra_seq :next (SeqIter ), Seg , [], State ).
381
388
382
- append_to_segment (_ , _ , StartIdx , EndIdx , Seg , Closed , _State )
383
- when StartIdx >= EndIdx ->
389
+ append_to_segment (_ , _ , end_of_seq , Seg , Closed , _State ) ->
384
390
{Seg , Closed };
385
- append_to_segment (UId , Tid , Idx , EndIdx , Seg0 , Closed , State ) ->
391
+ append_to_segment (UId , Tid , { Idx , SeqIter } = Cur , Seg0 , Closed , State ) ->
386
392
try ets :lookup (Tid , Idx ) of
387
393
[] ->
388
394
StartIdx = start_index (UId , Idx ),
389
395
case Idx < StartIdx of
390
396
true ->
391
397
% % a snapshot must have been completed after we last checked
392
398
% % the start idx, continue flush from new start index.
393
- append_to_segment (UId , Tid , StartIdx , EndIdx , Seg0 ,
399
+ append_to_segment (UId , Tid , next_ra_seq ( StartIdx , SeqIter ) , Seg0 ,
394
400
Closed , State );
395
401
false ->
396
402
% % oh dear, an expected index was not found in the mem table.
@@ -419,7 +425,7 @@ append_to_segment(UId, Tid, Idx, EndIdx, Seg0, Closed, State) ->
419
425
% % the segment index but is probably good enough to get comparative
420
426
% % data rates for different Ra components
421
427
ok = counters :add (State # state .counter , ? C_BYTES_WRITTEN , DataSize ),
422
- append_to_segment (UId , Tid , Idx + 1 , EndIdx , Seg , Closed , State );
428
+ append_to_segment (UId , Tid , ra_seq : next ( SeqIter ) , Seg , Closed , State );
423
429
{error , full } ->
424
430
% close and open a new segment
425
431
case open_successor_segment (Seg0 , State # state .segment_conf ) of
@@ -432,8 +438,14 @@ append_to_segment(UId, Tid, Idx, EndIdx, Seg0, Closed, State) ->
432
438
% % re-evaluate snapshot state for the server in case
433
439
% % a snapshot has completed during segment flush
434
440
StartIdx = start_index (UId , Idx ),
435
- append_to_segment (UId , Tid , StartIdx , EndIdx , Seg ,
436
- [Seg0 | Closed ], State )
441
+ Next = case StartIdx == Idx of
442
+ true ->
443
+ Cur ;
444
+ false ->
445
+ next_ra_seq (StartIdx , SeqIter )
446
+ end ,
447
+ append_to_segment (UId , Tid , Next ,
448
+ Seg , [Seg0 | Closed ], State )
437
449
end ;
438
450
{error , Posix } ->
439
451
FileName = ra_log_segment :filename (Seg0 ),
@@ -549,3 +561,13 @@ maybe_upgrade_segment_file_names(System, DataDir) ->
549
561
ok
550
562
end .
551
563
564
+ next_ra_seq (Idx , Iter0 ) ->
565
+ case ra_seq :next (Iter0 ) of
566
+ end_of_seq ->
567
+ end_of_seq ;
568
+ {I , _ } = Next
569
+ when I >= Idx ->
570
+ Next ;
571
+ {_ , Iter } ->
572
+ next_ra_seq (Idx , Iter )
573
+ end .
0 commit comments