aboutsummaryrefslogtreecommitdiffstats
path: root/lib/stdlib/src/dets.erl
diff options
context:
space:
mode:
authorHans Bolinder <[email protected]>2011-10-06 09:50:38 +0200
committerHans Bolinder <[email protected]>2011-10-17 08:29:22 +0200
commit45951664c2214ee9e4342e5909a8fa8445f03b92 (patch)
tree0bdf0c0cf0444bfbba2b088e91f4b2b9ac77972b /lib/stdlib/src/dets.erl
parent20aff71404e5af42555887964cfc3b308c1f8a7f (diff)
downloadotp-45951664c2214ee9e4342e5909a8fa8445f03b92.tar.gz
otp-45951664c2214ee9e4342e5909a8fa8445f03b92.tar.bz2
otp-45951664c2214ee9e4342e5909a8fa8445f03b92.zip
Fix a bug in Dets concerning repair of almost full tables
A Dets table with sufficiently large buckets could not always be repaired. (Reported by Gordon Guthrie.) The format of Dets files has been modified. When downgrading tables created with the new system will be repaired. Otherwise the modification should not be noticeable.
Diffstat (limited to 'lib/stdlib/src/dets.erl')
-rw-r--r--lib/stdlib/src/dets.erl57
1 files changed, 25 insertions, 32 deletions
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 7ed9c4b695..c0f9ce34b0 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.erl
@@ -1754,17 +1754,6 @@ system_code_change(State, _Module, _OldVsn, _Extra) ->
%%% Internal functions
%%%----------------------------------------------------------------------
-constants(FH, FileName) ->
- Version = FH#fileheader.version,
- if
- Version =< 8 ->
- dets_v8:constants();
- Version =:= 9 ->
- dets_v9:constants();
- true ->
- throw({error, {not_a_dets_file, FileName}})
- end.
-
%% -> {ok, Fd, fileheader()} | throw(Error)
read_file_header(FileName, Access, RamFile) ->
BF = if
@@ -1842,7 +1831,11 @@ do_bchunk_init(Head, Tab) ->
{H2, {error, old_version}};
Parms ->
L = dets_utils:all_allocated(H2),
- C0 = #dets_cont{no_objs = default, bin = <<>>, alloc = L},
+ Bin = if
+ L =:= <<>> -> eof;
+ true -> <<>>
+ end,
+ C0 = #dets_cont{no_objs = default, bin = Bin, alloc = L},
BinParms = term_to_binary(Parms),
{H2, {C0#dets_cont{tab = Tab, proc = self(),what = bchunk},
[BinParms]}}
@@ -2478,9 +2471,7 @@ fopen2(Fname, Tab) ->
Do = case Mod:check_file_header(FH, Fd) of
{ok, Head1, ExtraInfo} ->
Head2 = Head1#head{filename = Fname},
- try Mod:init_freelist(Head2, ExtraInfo) of
- Ftab ->
- {ok, Head1#head{freelists = Ftab}}
+ try {ok, Mod:init_freelist(Head2, ExtraInfo)}
catch
throw:_ ->
{repair, " has bad free lists, repairing ..."}
@@ -2574,9 +2565,7 @@ fopen_existing_file(Tab, OpenArgs) ->
Do = case Wh of
{Tag, Hd, Extra} when Tag =:= final; Tag =:= compact ->
Hd1 = Hd#head{filename = Fname},
- try Mod:init_freelist(Hd1, Extra) of
- Ftab ->
- {Tag, Hd#head{freelists = Ftab}}
+ try {Tag, Mod:init_freelist(Hd1, Extra)}
catch
throw:_ ->
{repair, " has bad free lists, repairing ..."}
@@ -3164,8 +3153,12 @@ init_scan(Head, NoObjs) ->
check_safe_fixtable(Head),
FreeLists = dets_utils:get_freelists(Head),
Base = Head#head.base,
- {From, To} = dets_utils:find_next_allocated(FreeLists, Base, Base),
- #dets_cont{no_objs = NoObjs, bin = <<>>, alloc = {From, To, <<>>}}.
+ case dets_utils:find_next_allocated(FreeLists, Base, Base) of
+ {From, To} ->
+ #dets_cont{no_objs = NoObjs, bin = <<>>, alloc = {From,To,<<>>}};
+ none ->
+ #dets_cont{no_objs = NoObjs, bin = eof, alloc = <<>>}
+ end.
check_safe_fixtable(Head) ->
case (Head#head.fixed =:= false) andalso
@@ -3266,18 +3259,18 @@ view(FileName) ->
case catch read_file_header(FileName, read, false) of
{ok, Fd, FH} ->
Mod = FH#fileheader.mod,
- try
- case Mod:check_file_header(FH, Fd) of
- {ok, H0, ExtraInfo} ->
- Ftab = Mod:init_freelist(H0, ExtraInfo),
- {_Bump, Base} = constants(FH, FileName),
- H = H0#head{freelists=Ftab, base = Base},
- v_free_list(H),
- Mod:v_segments(H),
- ok;
- X ->
- X
- end
+ try Mod:check_file_header(FH, Fd) of
+ {ok, H0, ExtraInfo} ->
+ Mod = FH#fileheader.mod,
+ case Mod:check_file_header(FH, Fd) of
+ {ok, H0, ExtraInfo} ->
+ H = Mod:init_freelist(H0, ExtraInfo),
+ v_free_list(H),
+ Mod:v_segments(H),
+ ok;
+ X ->
+ X
+ end
after file:close(Fd)
end;
X ->