Inker Manifest to be a two-level list
To eas seraching from front to back, change the inker manifest to be a two-level list
This commit is contained in:
parent
1f406c76dd
commit
853f113ee5
2 changed files with 208 additions and 74 deletions
|
@ -10,13 +10,24 @@
|
||||||
|
|
||||||
-export([
|
-export([
|
||||||
generate_entry/1,
|
generate_entry/1,
|
||||||
add_entry/2,
|
add_entry/3,
|
||||||
append_lastkey/3,
|
append_lastkey/3,
|
||||||
remove_entry/2,
|
remove_entry/2,
|
||||||
find_entry/2
|
find_entry/2,
|
||||||
|
head_entry/1,
|
||||||
|
to_list/1,
|
||||||
|
from_list/1,
|
||||||
|
reader/2,
|
||||||
|
writer/3,
|
||||||
|
printer/1,
|
||||||
|
complete_filex/0
|
||||||
|
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-define(MANIFEST_FILEX, "man").
|
||||||
|
-define(PENDING_FILEX, "pnd").
|
||||||
|
-define(SKIP_WIDTH, 16).
|
||||||
|
|
||||||
|
|
||||||
%%%============================================================================
|
%%%============================================================================
|
||||||
%%% API
|
%%% API
|
||||||
|
@ -34,16 +45,25 @@ generate_entry(Journal) ->
|
||||||
[]
|
[]
|
||||||
end.
|
end.
|
||||||
|
|
||||||
add_entry(Manifest, Entry) ->
|
add_entry(Manifest, Entry, ToEnd) ->
|
||||||
{SQN, FN, PidR, LastKey} = Entry,
|
{SQN, FN, PidR, LastKey} = Entry,
|
||||||
StrippedName = filename:rootname(FN),
|
StrippedName = filename:rootname(FN),
|
||||||
lists:reverse(lists:sort([{SQN, StrippedName, PidR, LastKey}|Manifest])).
|
case ToEnd of
|
||||||
|
true ->
|
||||||
|
prepend_entry({SQN, StrippedName, PidR, LastKey}, Manifest);
|
||||||
|
false ->
|
||||||
|
Man0 = [{SQN, StrippedName, PidR, LastKey}|to_list(Manifest)],
|
||||||
|
Man1 = lists:reverse(lists:sort(Man0)),
|
||||||
|
from_list(Man1)
|
||||||
|
end.
|
||||||
|
|
||||||
append_lastkey(Manifest, Pid, LastKey) ->
|
append_lastkey(Manifest, Pid, LastKey) ->
|
||||||
[{SQN, Filename, PidR, LK}|ManifestTail] = Manifest,
|
[{SQNMarker, SQNL}|ManifestTail] = Manifest,
|
||||||
case {PidR, LK} of
|
[{E_SQN, E_FN, E_P, E_LK}|SQNL_Tail] = SQNL,
|
||||||
|
case {E_P, E_LK} of
|
||||||
{Pid, empty} ->
|
{Pid, empty} ->
|
||||||
[{SQN, Filename, PidR, LastKey}|ManifestTail];
|
UpdEntry = {E_SQN, E_FN, E_P, LastKey},
|
||||||
|
[{SQNMarker, [UpdEntry|SQNL_Tail]}|ManifestTail];
|
||||||
_ ->
|
_ ->
|
||||||
Manifest
|
Manifest
|
||||||
end.
|
end.
|
||||||
|
@ -51,20 +71,153 @@ append_lastkey(Manifest, Pid, LastKey) ->
|
||||||
remove_entry(Manifest, Entry) ->
|
remove_entry(Manifest, Entry) ->
|
||||||
{SQN, FN, _PidR, _LastKey} = Entry,
|
{SQN, FN, _PidR, _LastKey} = Entry,
|
||||||
leveled_log:log("I0013", [FN]),
|
leveled_log:log("I0013", [FN]),
|
||||||
lists:keydelete(SQN, 1, Manifest).
|
Man0 = lists:keydelete(SQN, 1, to_list(Manifest)),
|
||||||
|
from_list(Man0).
|
||||||
|
|
||||||
find_entry(SQN, [{LowSQN, _FN, Pid, _LK}|_Tail]) when SQN >= LowSQN ->
|
find_entry(SQN, [{SQNMarker, SubL}|_Tail]) when SQN >= SQNMarker ->
|
||||||
Pid;
|
find_subentry(SQN, SubL);
|
||||||
find_entry(SQN, [_Head|Tail]) ->
|
find_entry(SQN, [_TopEntry|Tail]) ->
|
||||||
find_entry(SQN, Tail).
|
find_entry(SQN, Tail).
|
||||||
|
|
||||||
|
head_entry(Manifest) ->
|
||||||
|
[{_SQNMarker, SQNL}|_Tail] = Manifest,
|
||||||
|
[HeadEntry|_SQNL_Tail] = SQNL,
|
||||||
|
HeadEntry.
|
||||||
|
|
||||||
|
to_list(Manifest) ->
|
||||||
|
FoldFun =
|
||||||
|
fun({_SQNMarker, SubL}, Acc) ->
|
||||||
|
Acc ++ SubL
|
||||||
|
end,
|
||||||
|
lists:foldl(FoldFun, [], Manifest).
|
||||||
|
|
||||||
|
reader(SQN, RootPath) ->
|
||||||
|
ManifestPath = leveled_inker:filepath(RootPath, manifest_dir),
|
||||||
|
leveled_log:log("I0015", [ManifestPath, SQN]),
|
||||||
|
{ok, MBin} = file:read_file(filename:join(ManifestPath,
|
||||||
|
integer_to_list(SQN)
|
||||||
|
++ ".man")),
|
||||||
|
from_list(lists:reverse(lists:sort(binary_to_term(MBin)))).
|
||||||
|
|
||||||
|
|
||||||
|
writer(Manifest, ManSQN, RootPath) ->
|
||||||
|
ManPath = leveled_inker:filepath(RootPath, manifest_dir),
|
||||||
|
NewFN = filename:join(ManPath,
|
||||||
|
integer_to_list(ManSQN) ++ "." ++ ?MANIFEST_FILEX),
|
||||||
|
TmpFN = filename:join(ManPath,
|
||||||
|
integer_to_list(ManSQN) ++ "." ++ ?PENDING_FILEX),
|
||||||
|
MBin = term_to_binary(to_list(Manifest), [compressed]),
|
||||||
|
case filelib:is_file(NewFN) of
|
||||||
|
false ->
|
||||||
|
leveled_log:log("I0016", [ManSQN]),
|
||||||
|
ok = file:write_file(TmpFN, MBin),
|
||||||
|
ok = file:rename(TmpFN, NewFN),
|
||||||
|
ok
|
||||||
|
end.
|
||||||
|
|
||||||
|
printer(Manifest) ->
|
||||||
|
lists:foreach(fun({SQN, FN, _PID, _LK}) ->
|
||||||
|
leveled_log:log("I0017", [SQN, FN]) end,
|
||||||
|
to_list(Manifest)).
|
||||||
|
|
||||||
|
complete_filex() ->
|
||||||
|
?MANIFEST_FILEX.
|
||||||
|
|
||||||
|
|
||||||
|
%%%============================================================================
|
||||||
|
%%% Internal Functions
|
||||||
|
%%%============================================================================
|
||||||
|
|
||||||
|
from_list(Manifest) ->
|
||||||
|
% Manifest should already be sorted with the highest SQN at the head
|
||||||
|
% This will be maintained so that we can fold from the left, and find
|
||||||
|
% more recently added entries quicker - under the assumptions that fresh
|
||||||
|
% reads are more common than stale reads
|
||||||
|
lists:foldr(fun prepend_entry/2, [], Manifest).
|
||||||
|
|
||||||
|
prepend_entry(Entry, AccL) ->
|
||||||
|
{SQN, _FN, _PidR, _LastKey} = Entry,
|
||||||
|
case AccL of
|
||||||
|
[] ->
|
||||||
|
[{SQN, [Entry]}];
|
||||||
|
[{SQNMarker, SubL}|Tail] ->
|
||||||
|
case length(SubL) < ?SKIP_WIDTH of
|
||||||
|
true ->
|
||||||
|
[{SQNMarker, [Entry|SubL]}|Tail];
|
||||||
|
false ->
|
||||||
|
[{SQN, [Entry]}|AccL]
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
find_subentry(SQN, [{ME_SQN, _FN, ME_P, _LK}|_Tail]) when SQN >= ME_SQN ->
|
||||||
|
ME_P;
|
||||||
|
find_subentry(SQN, [_TopEntry|Tail]) ->
|
||||||
|
find_subentry(SQN, Tail).
|
||||||
|
|
||||||
|
|
||||||
%%%============================================================================
|
%%%============================================================================
|
||||||
%%% Test
|
%%% Test
|
||||||
%%%============================================================================
|
%%%============================================================================
|
||||||
|
|
||||||
-ifdef(TEST).
|
-ifdef(TEST).
|
||||||
|
|
||||||
|
build_testmanifest_aslist() ->
|
||||||
|
ManifestMapFun =
|
||||||
|
fun(N) ->
|
||||||
|
NStr = integer_to_list(N),
|
||||||
|
{max(1, N * 1000), "FN" ++ NStr, "pid" ++ NStr, "LK" ++ NStr}
|
||||||
|
end,
|
||||||
|
lists:map(ManifestMapFun, lists:reverse(lists:seq(0, 50))).
|
||||||
|
|
||||||
|
test_testmanifest(Man0) ->
|
||||||
|
?assertMatch("pid0", find_entry(1, Man0)),
|
||||||
|
?assertMatch("pid0", find_entry(2, Man0)),
|
||||||
|
?assertMatch("pid1", find_entry(1001, Man0)),
|
||||||
|
?assertMatch("pid20", find_entry(20000, Man0)),
|
||||||
|
?assertMatch("pid20", find_entry(20001, Man0)),
|
||||||
|
?assertMatch("pid20", find_entry(20999, Man0)),
|
||||||
|
?assertMatch("pid50", find_entry(99999, Man0)).
|
||||||
|
|
||||||
|
buildfromlist_test() ->
|
||||||
|
ManL = build_testmanifest_aslist(),
|
||||||
|
Man0 = from_list(ManL),
|
||||||
|
test_testmanifest(Man0),
|
||||||
|
?assertMatch(ManL, to_list(Man0)).
|
||||||
|
|
||||||
|
buildfromend_test() ->
|
||||||
|
ManL = build_testmanifest_aslist(),
|
||||||
|
FoldFun =
|
||||||
|
fun(E, Man) ->
|
||||||
|
add_entry(Man, E, true)
|
||||||
|
end,
|
||||||
|
Man0 = lists:foldr(FoldFun, [], ManL),
|
||||||
|
test_testmanifest(Man0),
|
||||||
|
?assertMatch(ManL, to_list(Man0)).
|
||||||
|
|
||||||
|
buildrandomfashion_test() ->
|
||||||
|
ManL0 = build_testmanifest_aslist(),
|
||||||
|
RandMapFun =
|
||||||
|
fun(X) ->
|
||||||
|
{random:uniform(), X}
|
||||||
|
end,
|
||||||
|
ManL1 = lists:map(RandMapFun, ManL0),
|
||||||
|
ManL2 = lists:sort(ManL1),
|
||||||
|
|
||||||
|
FoldFun =
|
||||||
|
fun({_R, E}, Man) ->
|
||||||
|
add_entry(Man, E, false)
|
||||||
|
end,
|
||||||
|
Man0 = lists:foldl(FoldFun, [], ManL2),
|
||||||
|
|
||||||
|
test_testmanifest(Man0),
|
||||||
|
?assertMatch(ManL0, to_list(Man0)),
|
||||||
|
|
||||||
|
RandomEntry = lists:nth(random:uniform(50), ManL0),
|
||||||
|
Man1 = remove_entry(Man0, RandomEntry),
|
||||||
|
Man2 = add_entry(Man1, RandomEntry, false),
|
||||||
|
|
||||||
|
test_testmanifest(Man2),
|
||||||
|
?assertMatch(ManL0, to_list(Man2)).
|
||||||
|
|
||||||
|
|
||||||
-endif.
|
-endif.
|
|
@ -110,7 +110,6 @@
|
||||||
ink_close/1,
|
ink_close/1,
|
||||||
ink_doom/1,
|
ink_doom/1,
|
||||||
build_dummy_journal/0,
|
build_dummy_journal/0,
|
||||||
simple_manifest_reader/2,
|
|
||||||
clean_testdir/1,
|
clean_testdir/1,
|
||||||
filepath/2,
|
filepath/2,
|
||||||
filepath/3]).
|
filepath/3]).
|
||||||
|
@ -122,7 +121,6 @@
|
||||||
-define(COMPACT_FP, "post_compact").
|
-define(COMPACT_FP, "post_compact").
|
||||||
-define(WASTE_FP, "waste").
|
-define(WASTE_FP, "waste").
|
||||||
-define(JOURNAL_FILEX, "cdb").
|
-define(JOURNAL_FILEX, "cdb").
|
||||||
-define(MANIFEST_FILEX, "man").
|
|
||||||
-define(PENDING_FILEX, "pnd").
|
-define(PENDING_FILEX, "pnd").
|
||||||
-define(LOADING_PAUSE, 1000).
|
-define(LOADING_PAUSE, 1000).
|
||||||
-define(LOADING_BATCH, 1000).
|
-define(LOADING_BATCH, 1000).
|
||||||
|
@ -259,7 +257,7 @@ handle_call({get, Key, SQN}, _From, State) ->
|
||||||
handle_call({key_check, Key, SQN}, _From, State) ->
|
handle_call({key_check, Key, SQN}, _From, State) ->
|
||||||
{reply, key_check(Key, SQN, State#state.manifest), State};
|
{reply, key_check(Key, SQN, State#state.manifest), State};
|
||||||
handle_call({load_pcl, StartSQN, FilterFun, Penciller}, _From, State) ->
|
handle_call({load_pcl, StartSQN, FilterFun, Penciller}, _From, State) ->
|
||||||
Manifest = lists:reverse(State#state.manifest),
|
Manifest = lists:reverse(leveled_imanifest:to_list(State#state.manifest)),
|
||||||
Reply = load_from_sequence(StartSQN, FilterFun, Penciller, Manifest),
|
Reply = load_from_sequence(StartSQN, FilterFun, Penciller, Manifest),
|
||||||
{reply, Reply, State};
|
{reply, Reply, State};
|
||||||
handle_call({register_snapshot, Requestor}, _From , State) ->
|
handle_call({register_snapshot, Requestor}, _From , State) ->
|
||||||
|
@ -281,29 +279,30 @@ handle_call({confirm_delete, ManSQN}, _From, State) ->
|
||||||
State#state.registered_snapshots),
|
State#state.registered_snapshots),
|
||||||
{reply, Reply, State};
|
{reply, Reply, State};
|
||||||
handle_call(get_manifest, _From, State) ->
|
handle_call(get_manifest, _From, State) ->
|
||||||
{reply, State#state.manifest, State};
|
{reply, leveled_imanifest:to_list(State#state.manifest), State};
|
||||||
handle_call({update_manifest,
|
handle_call({update_manifest,
|
||||||
ManifestSnippet,
|
ManifestSnippet,
|
||||||
DeletedFiles}, _From, State) ->
|
DeletedFiles}, _From, State) ->
|
||||||
Man0 = lists:foldl(fun(ManEntry, AccMan) ->
|
DropFun =
|
||||||
leveled_imanifest:remove_entry(AccMan, ManEntry)
|
fun(E, Acc) ->
|
||||||
end,
|
leveled_imanifest:remove_entry(Acc, E)
|
||||||
State#state.manifest,
|
end,
|
||||||
DeletedFiles),
|
Man0 = lists:foldl(DropFun, State#state.manifest, DeletedFiles),
|
||||||
Man1 = lists:foldl(fun(ManEntry, AccMan) ->
|
AddFun =
|
||||||
leveled_imanifest:add_entry(AccMan, ManEntry) end,
|
fun(E, Acc) ->
|
||||||
Man0,
|
leveled_imanifest:add_entry(Acc, E, false)
|
||||||
ManifestSnippet),
|
end,
|
||||||
|
Man1 = lists:foldl(AddFun, Man0, ManifestSnippet),
|
||||||
NewManifestSQN = State#state.manifest_sqn + 1,
|
NewManifestSQN = State#state.manifest_sqn + 1,
|
||||||
manifest_printer(Man1),
|
leveled_imanifest:printer(Man1),
|
||||||
simple_manifest_writer(Man1, NewManifestSQN, State#state.root_path),
|
leveled_imanifest:writer(Man1, NewManifestSQN, State#state.root_path),
|
||||||
{reply,
|
{reply,
|
||||||
{ok, NewManifestSQN},
|
{ok, NewManifestSQN},
|
||||||
State#state{manifest=Man1,
|
State#state{manifest=Man1,
|
||||||
manifest_sqn=NewManifestSQN,
|
manifest_sqn=NewManifestSQN,
|
||||||
pending_removals=DeletedFiles}};
|
pending_removals=DeletedFiles}};
|
||||||
handle_call(print_manifest, _From, State) ->
|
handle_call(print_manifest, _From, State) ->
|
||||||
manifest_printer(State#state.manifest),
|
leveled_imanifest:printer(State#state.manifest),
|
||||||
{reply, ok, State};
|
{reply, ok, State};
|
||||||
handle_call({compact,
|
handle_call({compact,
|
||||||
Checker,
|
Checker,
|
||||||
|
@ -353,8 +352,9 @@ terminate(Reason, State) ->
|
||||||
lists:foreach(fun({Snap, _SQN}) -> ok = ink_close(Snap) end,
|
lists:foreach(fun({Snap, _SQN}) -> ok = ink_close(Snap) end,
|
||||||
State#state.registered_snapshots),
|
State#state.registered_snapshots),
|
||||||
leveled_log:log("I0007", []),
|
leveled_log:log("I0007", []),
|
||||||
manifest_printer(State#state.manifest),
|
leveled_imanifest:printer(State#state.manifest),
|
||||||
ok = close_allmanifest(State#state.manifest)
|
ManAsList = leveled_imanifest:to_list(State#state.manifest),
|
||||||
|
ok = close_allmanifest(ManAsList)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
code_change(_OldVsn, State, _Extra) ->
|
code_change(_OldVsn, State, _Extra) ->
|
||||||
|
@ -439,10 +439,10 @@ put_object(LedgerKey, Object, KeyChanges, State) ->
|
||||||
State#state.root_path,
|
State#state.root_path,
|
||||||
CDBopts),
|
CDBopts),
|
||||||
{_, _, NewJournalP, _} = ManEntry,
|
{_, _, NewJournalP, _} = ManEntry,
|
||||||
Manifest1 = leveled_imanifest:add_entry(Manifest0, ManEntry),
|
Manifest1 = leveled_imanifest:add_entry(Manifest0, ManEntry, true),
|
||||||
ok = simple_manifest_writer(Manifest1,
|
ok = leveled_imanifest:writer(Manifest1,
|
||||||
State#state.manifest_sqn + 1,
|
State#state.manifest_sqn + 1,
|
||||||
State#state.root_path),
|
State#state.root_path),
|
||||||
ok = leveled_cdb:cdb_put(NewJournalP,
|
ok = leveled_cdb:cdb_put(NewJournalP,
|
||||||
JournalKey,
|
JournalKey,
|
||||||
JournalBin),
|
JournalBin),
|
||||||
|
@ -478,7 +478,7 @@ build_manifest(ManifestFilenames,
|
||||||
CDBopts) ->
|
CDBopts) ->
|
||||||
% Find the manifest with a highest Manifest sequence number
|
% Find the manifest with a highest Manifest sequence number
|
||||||
% Open it and read it to get the current Confirmed Manifest
|
% Open it and read it to get the current Confirmed Manifest
|
||||||
ManifestRegex = "(?<MSQN>[0-9]+)\\." ++ ?MANIFEST_FILEX,
|
ManifestRegex = "(?<MSQN>[0-9]+)\\." ++ leveled_imanifest:complete_filex(),
|
||||||
ValidManSQNs = sequencenumbers_fromfilenames(ManifestFilenames,
|
ValidManSQNs = sequencenumbers_fromfilenames(ManifestFilenames,
|
||||||
ManifestRegex,
|
ManifestRegex,
|
||||||
'MSQN'),
|
'MSQN'),
|
||||||
|
@ -488,7 +488,7 @@ build_manifest(ManifestFilenames,
|
||||||
{[], 1};
|
{[], 1};
|
||||||
_ ->
|
_ ->
|
||||||
PersistedManSQN = lists:max(ValidManSQNs),
|
PersistedManSQN = lists:max(ValidManSQNs),
|
||||||
M1 = simple_manifest_reader(PersistedManSQN,
|
M1 = leveled_imanifest:reader(PersistedManSQN,
|
||||||
RootPath),
|
RootPath),
|
||||||
{M1, PersistedManSQN}
|
{M1, PersistedManSQN}
|
||||||
end,
|
end,
|
||||||
|
@ -497,7 +497,10 @@ build_manifest(ManifestFilenames,
|
||||||
% a valid active journal at the head of the manifest
|
% a valid active journal at the head of the manifest
|
||||||
OpenManifest = open_all_manifest(Manifest, RootPath, CDBopts),
|
OpenManifest = open_all_manifest(Manifest, RootPath, CDBopts),
|
||||||
|
|
||||||
{ActiveLowSQN, _FN, ActiveJournal, _LK} = lists:nth(1, OpenManifest),
|
{ActiveLowSQN,
|
||||||
|
_FN,
|
||||||
|
ActiveJournal,
|
||||||
|
_LK} = leveled_imanifest:head_entry(OpenManifest),
|
||||||
JournalSQN = case leveled_cdb:cdb_lastkey(ActiveJournal) of
|
JournalSQN = case leveled_cdb:cdb_lastkey(ActiveJournal) of
|
||||||
empty ->
|
empty ->
|
||||||
ActiveLowSQN;
|
ActiveLowSQN;
|
||||||
|
@ -511,13 +514,13 @@ build_manifest(ManifestFilenames,
|
||||||
if
|
if
|
||||||
length(OpenManifest) > length(Manifest) ->
|
length(OpenManifest) > length(Manifest) ->
|
||||||
leveled_log:log("I0009", []),
|
leveled_log:log("I0009", []),
|
||||||
manifest_printer(OpenManifest),
|
leveled_imanifest:printer(OpenManifest),
|
||||||
NextSQN = ManifestSQN + 1,
|
NextSQN = ManifestSQN + 1,
|
||||||
simple_manifest_writer(OpenManifest, NextSQN, RootPath),
|
leveled_imanifest:writer(OpenManifest, NextSQN, RootPath),
|
||||||
NextSQN;
|
NextSQN;
|
||||||
true ->
|
true ->
|
||||||
leveled_log:log("I0010", []),
|
leveled_log:log("I0010", []),
|
||||||
manifest_printer(OpenManifest),
|
leveled_imanifest:printer(OpenManifest),
|
||||||
ManifestSQN
|
ManifestSQN
|
||||||
end,
|
end,
|
||||||
{OpenManifest, UpdManifestSQN, JournalSQN, ActiveJournal}.
|
{OpenManifest, UpdManifestSQN, JournalSQN, ActiveJournal}.
|
||||||
|
@ -533,9 +536,11 @@ close_allmanifest([H|ManifestT]) ->
|
||||||
|
|
||||||
open_all_manifest([], RootPath, CDBOpts) ->
|
open_all_manifest([], RootPath, CDBOpts) ->
|
||||||
leveled_log:log("I0011", []),
|
leveled_log:log("I0011", []),
|
||||||
leveled_imanifest:add_entry([], start_new_activejournal(1, RootPath, CDBOpts));
|
leveled_imanifest:add_entry([],
|
||||||
|
start_new_activejournal(1, RootPath, CDBOpts),
|
||||||
|
true);
|
||||||
open_all_manifest(Man0, RootPath, CDBOpts) ->
|
open_all_manifest(Man0, RootPath, CDBOpts) ->
|
||||||
Man1 = lists:reverse(lists:sort(Man0)),
|
Man1 = leveled_imanifest:to_list(Man0),
|
||||||
[{HeadSQN, HeadFN, _IgnorePid, HeadLK}|ManifestTail] = Man1,
|
[{HeadSQN, HeadFN, _IgnorePid, HeadLK}|ManifestTail] = Man1,
|
||||||
OpenJournalFun =
|
OpenJournalFun =
|
||||||
fun(ManEntry) ->
|
fun(ManEntry) ->
|
||||||
|
@ -559,7 +564,8 @@ open_all_manifest(Man0, RootPath, CDBOpts) ->
|
||||||
ManEntry
|
ManEntry
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
OpenedTail = lists:map(OpenJournalFun, ManifestTail),
|
OpenedTailAsList = lists:map(OpenJournalFun, ManifestTail),
|
||||||
|
OpenedTail = leveled_imanifest:from_list(OpenedTailAsList),
|
||||||
CompleteHeadFN = HeadFN ++ "." ++ ?JOURNAL_FILEX,
|
CompleteHeadFN = HeadFN ++ "." ++ ?JOURNAL_FILEX,
|
||||||
PendingHeadFN = HeadFN ++ "." ++ ?PENDING_FILEX,
|
PendingHeadFN = HeadFN ++ "." ++ ?PENDING_FILEX,
|
||||||
case filelib:is_file(CompleteHeadFN) of
|
case filelib:is_file(CompleteHeadFN) of
|
||||||
|
@ -572,16 +578,20 @@ open_all_manifest(Man0, RootPath, CDBOpts) ->
|
||||||
{HeadSQN,
|
{HeadSQN,
|
||||||
HeadFN,
|
HeadFN,
|
||||||
HeadR,
|
HeadR,
|
||||||
LastKey}),
|
LastKey},
|
||||||
|
true),
|
||||||
NewManEntry = start_new_activejournal(LastSQN + 1,
|
NewManEntry = start_new_activejournal(LastSQN + 1,
|
||||||
RootPath,
|
RootPath,
|
||||||
CDBOpts),
|
CDBOpts),
|
||||||
leveled_imanifest:add_entry(ManToHead, NewManEntry);
|
leveled_imanifest:add_entry(ManToHead,
|
||||||
|
NewManEntry,
|
||||||
|
true);
|
||||||
false ->
|
false ->
|
||||||
{ok, HeadW} = leveled_cdb:cdb_open_writer(PendingHeadFN,
|
{ok, HeadW} = leveled_cdb:cdb_open_writer(PendingHeadFN,
|
||||||
CDBOpts),
|
CDBOpts),
|
||||||
leveled_imanifest:add_entry(OpenedTail,
|
leveled_imanifest:add_entry(OpenedTail,
|
||||||
{HeadSQN, HeadFN, HeadW, HeadLK})
|
{HeadSQN, HeadFN, HeadW, HeadLK},
|
||||||
|
true)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
@ -707,35 +717,6 @@ filepath(CompactFilePath, NewSQN, compact_journal) ->
|
||||||
++ "." ++ ?PENDING_FILEX).
|
++ "." ++ ?PENDING_FILEX).
|
||||||
|
|
||||||
|
|
||||||
simple_manifest_reader(SQN, RootPath) ->
|
|
||||||
ManifestPath = filepath(RootPath, manifest_dir),
|
|
||||||
leveled_log:log("I0015", [ManifestPath, SQN]),
|
|
||||||
{ok, MBin} = file:read_file(filename:join(ManifestPath,
|
|
||||||
integer_to_list(SQN)
|
|
||||||
++ ".man")),
|
|
||||||
binary_to_term(MBin).
|
|
||||||
|
|
||||||
|
|
||||||
simple_manifest_writer(Manifest, ManSQN, RootPath) ->
|
|
||||||
ManPath = filepath(RootPath, manifest_dir),
|
|
||||||
NewFN = filename:join(ManPath,
|
|
||||||
integer_to_list(ManSQN) ++ "." ++ ?MANIFEST_FILEX),
|
|
||||||
TmpFN = filename:join(ManPath,
|
|
||||||
integer_to_list(ManSQN) ++ "." ++ ?PENDING_FILEX),
|
|
||||||
MBin = term_to_binary(Manifest, [compressed]),
|
|
||||||
case filelib:is_file(NewFN) of
|
|
||||||
false ->
|
|
||||||
leveled_log:log("I0016", [ManSQN]),
|
|
||||||
ok = file:write_file(TmpFN, MBin),
|
|
||||||
ok = file:rename(TmpFN, NewFN),
|
|
||||||
ok
|
|
||||||
end.
|
|
||||||
|
|
||||||
manifest_printer(Manifest) ->
|
|
||||||
lists:foreach(fun({SQN, FN, _PID, _LK}) ->
|
|
||||||
leveled_log:log("I0017", [SQN, FN]) end,
|
|
||||||
Manifest).
|
|
||||||
|
|
||||||
initiate_penciller_snapshot(Bookie) ->
|
initiate_penciller_snapshot(Bookie) ->
|
||||||
{ok,
|
{ok,
|
||||||
{LedgerSnap, LedgerCache},
|
{LedgerSnap, LedgerCache},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue