137137-define (WASTE_FP , " waste" ).
138138-define (JOURNAL_FILEX , " cdb" ).
139139-define (PENDING_FILEX , " pnd" ).
140+ -define (ARCHIVE_FILEX , " bak" ).
141+ % Note that archive means "no longer active", it is an indication of
142+ % removable waste not of backup.
140143-define (TEST_KC , {[], infinity }).
141144-define (SHUTDOWN_LOOPS , 10 ).
142145-define (SHUTDOWN_PAUSE , 10000 ).
@@ -682,7 +685,7 @@ handle_call(roll, _From, State = #state{is_snapshot = Snap}) when
682685 }}
683686 end ;
684687handle_call (
685- {backup , BackupPath }, _from , State
688+ {backup , BackupPath }, _From , State
686689) when
687690 State # state .is_snapshot == true
688691->
@@ -699,20 +702,21 @@ handle_call(
699702 ExtendedBaseFN = BaseFN ++ " ." ++ ? JOURNAL_FILEX ,
700703 BackupName = filename :join (BackupJFP , BaseFN ),
701704 true = leveled_cdb :finished_rolling (PidR ),
702- case
705+ Link =
703706 file :make_link (
704707 FN ++ " ." ++ ? JOURNAL_FILEX ,
705708 BackupName ++ " ." ++ ? JOURNAL_FILEX
706- )
707- of
709+ ),
710+ case Link of
708711 ok ->
709712 ok ;
710713 {error , eexist } ->
711714 ok
712715 end ,
713- {[{SQN , BackupName , PidR , LastKey } | ManAcc ], [
714- ExtendedBaseFN | FTRAcc
715- ]};
716+ {
717+ [{SQN , BackupName , PidR , LastKey } | ManAcc ],
718+ [ExtendedBaseFN | FTRAcc ]
719+ };
716720 false ->
717721 ? STD_LOG (i0021 , [FN , SQN , State # state .journal_sqn ]),
718722 {ManAcc , FTRAcc }
@@ -1263,7 +1267,7 @@ close_allmanifest([H | ManifestT]) ->
12631267) ->
12641268 leveled_imanifest :manifest ().
12651269% % @doc
1266- % % Open all the files in the manifets , and updating the manifest with the PIDs
1270+ % % Open all the files in the manifest , and updating the manifest with the PIDs
12671271% % of the opened files
12681272open_all_manifest ([], RootPath , CDBOpts ) ->
12691273 ? STD_LOG (i0011 , []),
@@ -1273,51 +1277,93 @@ open_all_manifest([], RootPath, CDBOpts) ->
12731277 true
12741278 );
12751279open_all_manifest (Man0 , RootPath , CDBOpts ) ->
1280+ OnDiskJournalSet =
1281+ sets :from_list (get_all_completejournals (RootPath ), [{version , 2 }]),
12761282 Man1 = leveled_imanifest :to_list (Man0 ),
12771283 [{HeadSQN , HeadFN , _IgnorePid , HeadLK } | ManifestTail ] = Man1 ,
12781284 OpenJournalFun =
1279- fun (ManEntry ) ->
1285+ fun (ManEntry , Acc ) ->
12801286 {LowSQN , FN , _ , LK_RO } = ManEntry ,
12811287 CFN = FN ++ " ." ++ ? JOURNAL_FILEX ,
12821288 PFN = FN ++ " ." ++ ? PENDING_FILEX ,
12831289 case filelib :is_file (CFN ) of
12841290 true ->
12851291 {ok , Pid } =
12861292 leveled_cdb :cdb_reopen_reader (CFN , LK_RO , CDBOpts ),
1287- {LowSQN , FN , Pid , LK_RO };
1293+ {
1294+ {LowSQN , FN , Pid , LK_RO },
1295+ sets :del_element (CFN , Acc )
1296+ };
12881297 false ->
1289- W = leveled_cdb :cdb_open_writer (PFN , CDBOpts ),
1290- {ok , Pid } = W ,
1298+ {ok , Pid } = leveled_cdb :cdb_open_writer (PFN , CDBOpts ),
12911299 ok = leveled_cdb :cdb_roll (Pid ),
12921300 LK_WR = leveled_cdb :cdb_lastkey (Pid ),
1293- {LowSQN , FN , Pid , LK_WR }
1301+ {
1302+ {LowSQN , FN , Pid , LK_WR },
1303+ Acc
1304+ }
12941305 end
12951306 end ,
1296- OpenedTailAsList = lists :map (OpenJournalFun , ManifestTail ),
1307+ {
1308+ OpenedTailAsList ,
1309+ FilteredOnDiskJournalSet
1310+ } =
1311+ lists :mapfoldl (OpenJournalFun , OnDiskJournalSet , ManifestTail ),
12971312 OpenedTail = leveled_imanifest :from_list (OpenedTailAsList ),
12981313 CompleteHeadFN = HeadFN ++ " ." ++ ? JOURNAL_FILEX ,
12991314 PendingHeadFN = HeadFN ++ " ." ++ ? PENDING_FILEX ,
1300- case filelib :is_file (CompleteHeadFN ) of
1301- true ->
1302- ? STD_LOG (i0012 , [HeadFN ]),
1303- {ok , HeadR } = leveled_cdb :cdb_open_reader (CompleteHeadFN ),
1304- LastKey = {LastSQN , _ , _ } = leveled_cdb :cdb_lastkey (HeadR ),
1305- ManToHead =
1315+ StartedManifest =
1316+ case filelib :is_file (CompleteHeadFN ) of
1317+ true ->
1318+ ? STD_LOG (i0012 , [HeadFN ]),
1319+ {ok , HeadR } = leveled_cdb :cdb_open_reader (CompleteHeadFN ),
1320+ LastKey = {LastSQN , _ , _ } = leveled_cdb :cdb_lastkey (HeadR ),
1321+ ManToHead =
1322+ leveled_imanifest :add_entry (
1323+ OpenedTail ,
1324+ {HeadSQN , HeadFN , HeadR , LastKey },
1325+ true
1326+ ),
1327+ NewManEntry =
1328+ start_new_activejournal (LastSQN + 1 , RootPath , CDBOpts ),
1329+ leveled_imanifest :add_entry (ManToHead , NewManEntry , true );
1330+ false ->
1331+ {ok , HeadW } =
1332+ leveled_cdb :cdb_open_writer (PendingHeadFN , CDBOpts ),
13061333 leveled_imanifest :add_entry (
1307- OpenedTail ,
1308- {HeadSQN , HeadFN , HeadR , LastKey },
1309- true
1310- ),
1311- NewManEntry =
1312- start_new_activejournal (LastSQN + 1 , RootPath , CDBOpts ),
1313- leveled_imanifest :add_entry (ManToHead , NewManEntry , true );
1314- false ->
1315- {ok , HeadW } =
1316- leveled_cdb :cdb_open_writer (PendingHeadFN , CDBOpts ),
1317- leveled_imanifest :add_entry (
1318- OpenedTail , {HeadSQN , HeadFN , HeadW , HeadLK }, true
1319- )
1320- end .
1334+ OpenedTail , {HeadSQN , HeadFN , HeadW , HeadLK }, true
1335+ )
1336+ end ,
1337+ lists :foreach (
1338+ fun (FN ) ->
1339+ NewName =
1340+ filename :flatten ([filename :rootname (FN ), " ." ++ ? ARCHIVE_FILEX ]),
1341+ ? STD_LOG (i0029 , [FN ]),
1342+ file :rename (FN , NewName )
1343+ end ,
1344+ sets :to_list (
1345+ sets :del_element (CompleteHeadFN , FilteredOnDiskJournalSet )
1346+ )
1347+ ),
1348+ StartedManifest .
1349+
1350+ - spec get_all_completejournals (string ()) -> list (file :filename ()).
1351+ get_all_completejournals (RootPath ) ->
1352+ JFiles = list_dir (filepath (RootPath , journal_dir )),
1353+ CFiles = list_dir (filepath (RootPath , journal_compact_dir )),
1354+ lists :filter (
1355+ fun (FN ) ->
1356+ filename :extension (FN ) == (" ." ++ ? JOURNAL_FILEX )
1357+ end ,
1358+ JFiles ++ CFiles
1359+ ).
1360+
1361+ - spec list_dir (string ()) -> list (file :filename ()).
1362+ list_dir (Path ) ->
1363+ {ok , Files } = file :list_dir (Path ),
1364+ lists :map (
1365+ fun (FN ) -> filename :join (Path , FN ) end , Files
1366+ ).
13211367
13221368start_new_activejournal (SQN , RootPath , CDBOpts ) ->
13231369 Filename = filepath (RootPath , SQN , new_journal ),
0 commit comments