Merge pull request #44 from aeternity/uw-index-metadata

Adding/deleting indexes cleans up index metadata
This commit is contained in:
Ulf Wiger 2023-10-12 18:19:16 +02:00 committed by GitHub
commit 33ee7929d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 1 deletions

View File

@ -33,6 +33,7 @@
, read_info/2 %% (Alias, Tab) , read_info/2 %% (Alias, Tab)
, read_info/4 %% (Alias, Tab, Key, Default) , read_info/4 %% (Alias, Tab, Key, Default)
, write_info/4 %% (Alias, Tab, Key, Value) , write_info/4 %% (Alias, Tab, Key, Value)
, delete_info/3 %% (Alias, Tab, Key)
, write_table_property/3 %% (Alias, Tab, Property) , write_table_property/3 %% (Alias, Tab, Property)
]). ]).
@ -287,6 +288,14 @@ write_info_encv(Ref, Tab, K, V) ->
maybe_write_standalone_info(Ref, K, V), maybe_write_standalone_info(Ref, K, V),
mrdb:rdb_put(Ref, EncK, V, []). mrdb:rdb_put(Ref, EncK, V, []).
delete_info(Alias, Tab, K) ->
delete_info_(get_ref({admin, Alias}), Tab, K).
delete_info_(Ref, Tab, K) ->
EncK = mnesia_rocksdb_lib:encode_key({info, Tab, K}, sext),
maybe_delete_standalone_info(Ref, K),
mrdb:rdb_delete(Ref, EncK, []).
maybe_write_standalone_info(Ref, K, V) -> maybe_write_standalone_info(Ref, K, V) ->
case Ref of case Ref of
#{type := standalone, vsn := 1, db_ref := DbRef} -> #{type := standalone, vsn := 1, db_ref := DbRef} ->
@ -298,6 +307,16 @@ maybe_write_standalone_info(Ref, K, V) ->
ok ok
end. end.
maybe_delete_standalone_info(Ref, K) ->
case Ref of
#{type := standalone, vsn := 1, db_ref := DbRef} ->
EncK = mnesia_rocksdb_lib:encode_key(K, sext),
Key = <<?INFO_TAG, EncK/binary>>,
rocksdb:delete(DbRef, Key, []);
_ ->
ok
end.
write_table_property(Alias, Tab, Prop) when is_tuple(Prop), size(Prop) >= 1 -> write_table_property(Alias, Tab, Prop) when is_tuple(Prop), size(Prop) >= 1 ->
call(Alias, {write_table_property, Tab, Prop}). call(Alias, {write_table_property, Tab, Prop}).
@ -521,7 +540,7 @@ handle_req(Alias, {create_table, Name, Props}, Backend, St) ->
case create_trec(Alias, Name, Props, Backend, St) of case create_trec(Alias, Name, Props, Backend, St) of
{ok, NewCf} -> {ok, NewCf} ->
St1 = update_cf(Alias, Name, NewCf, St), St1 = update_cf(Alias, Name, NewCf, St),
{reply, {ok, NewCf}, St1}; {reply, {ok, NewCf}, maybe_update_main(Alias, Name, create, St1)};
{error, _} = Error -> {error, _} = Error ->
{reply, Error, St} {reply, Error, St}
end end
@ -637,8 +656,14 @@ maybe_update_main(Alias, {Main, index, I}, Op, St) ->
case {Op, lists:member(I, Index)} of case {Op, lists:member(I, Index)} of
{delete, true} -> {delete, true} ->
CfM1 = CfM#{properties => Props#{index => Index -- [I]}}, CfM1 = CfM#{properties => Props#{index => Index -- [I]}},
delete_info(Alias, Main, {index_consistent, I}),
maybe_update_pt(Main, CfM1), maybe_update_pt(Main, CfM1),
update_cf(Alias, Main, CfM1, St); update_cf(Alias, Main, CfM1, St);
{create, _} ->
%% Due to a previous bug, this marker might linger
%% In any case, it mustn't be there for a newly created index
delete_info(Alias, Main, {index_consistent, I}),
St;
_ -> _ ->
St St
end; end;
@ -649,6 +674,7 @@ maybe_update_main(Alias, {Main, index, I}, Op, St) ->
maybe_update_main(_, _, _, St) -> maybe_update_main(_, _, _, St) ->
St. St.
%% The pt may not have been created yet. If so, don't do it here. %% The pt may not have been created yet. If so, don't do it here.
maybe_update_pt(Name, Ref) -> maybe_update_pt(Name, Ref) ->
case get_pt(Name, error) of case get_pt(Name, error) of

View File

@ -6,6 +6,9 @@
, iterator_move/2 , iterator_move/2
, iterator/2 , iterator/2
, iterator_close/1 , iterator_close/1
, fold/4
, rev_fold/4
, index_ref/2
]). ]).
-record(mrdb_ix_iter, { i :: mrdb:iterator() -record(mrdb_ix_iter, { i :: mrdb:iterator()
@ -62,6 +65,41 @@ iterator(Tab, IxPos) ->
iterator_move(#mrdb_ix_iter{type = set} = IxI, Dir) -> iterator_move_set(IxI, Dir); iterator_move(#mrdb_ix_iter{type = set} = IxI, Dir) -> iterator_move_set(IxI, Dir);
iterator_move(#mrdb_ix_iter{type = bag} = IxI, Dir) -> iterator_move_bag(IxI, Dir). iterator_move(#mrdb_ix_iter{type = bag} = IxI, Dir) -> iterator_move_bag(IxI, Dir).
-spec fold(mrdb:ref_or_tab(), mrdb:index_position(),
fun( (index_value(), object() | [], Acc) -> Acc ), Acc) -> Acc
when Acc :: any().
%% Folds over the index table corresponding to Tab and IxPos.
%% The fold fun is called with the index key and the corresponding object,
%% or [] if there is no such object.
fold(Tab, IxPos, FoldFun, Acc) when is_function(FoldFun, 3) ->
fold_(Tab, IxPos, first, next, FoldFun, Acc).
-spec rev_fold(mrdb:ref_or_tab(), mrdb:index_position(),
fun( (index_value(), object() | [], Acc) -> Acc ), Acc) -> Acc
when Acc :: any().
%% Like fold/4 above, but folds over the index in the reverse order.
rev_fold(Tab, IxPos, FoldFun, Acc) when is_function(FoldFun, 3) ->
fold_(Tab, IxPos, last, prev, FoldFun, Acc).
fold_(Tab, IxPos, Start, Dir, FoldFun, Acc) ->
with_iterator(
Tab, IxPos,
fun(I) ->
iter_fold(I, Start, Dir, FoldFun, Acc)
end).
iter_fold(I, Start, Dir, Fun, Acc) ->
iter_fold_(iterator_move(I, Start), I, Dir, Fun, Acc).
iter_fold_({ok, IxVal, Obj}, I, Dir, Fun, Acc) ->
iter_fold_(iterator_move(I, Dir), I, Dir, Fun, Fun(IxVal, Obj, Acc));
iter_fold_({error, _}, _, _, _, Acc) ->
Acc.
index_ref(Tab, Pos) ->
TRef = mrdb:ensure_ref(Tab),
ensure_index_ref(Pos, TRef).
iterator_move_set(#mrdb_ix_iter{i = I, sub = Sub}, Dir) -> iterator_move_set(#mrdb_ix_iter{i = I, sub = Sub}, Dir) ->
case mrdb:iterator_move(I, Dir) of case mrdb:iterator_move(I, Dir) of
{ok, {{FKey, PKey}}} -> {ok, {{FKey, PKey}}} ->

View File

@ -33,6 +33,7 @@
-export([ -export([
index_plugin_mgmt/1 index_plugin_mgmt/1
, add_indexes/1 , add_indexes/1
, delete_indexes/1
, create_bag_index/1 , create_bag_index/1
, create_ordered_index/1 , create_ordered_index/1
, test_1_ram_copies/1 , test_1_ram_copies/1
@ -94,6 +95,7 @@ groups() ->
, create_ordered_index , create_ordered_index
, index_plugin_mgmt , index_plugin_mgmt
, add_indexes , add_indexes
, delete_indexes
]} ]}
, {access, [sequence], [ , {access, [sequence], [
test_1_ram_copies test_1_ram_copies
@ -239,6 +241,25 @@ add_indexes(_Config) ->
{atomic, ok} = mnesia:add_table_index(T, a), {atomic, ok} = mnesia:add_table_index(T, a),
ok. ok.
delete_indexes(_Config) ->
T = ?TAB(t1),
{atomic, ok} = mnesia:create_table(T, [{rdb, [node()]}, {attributes, [k, a, b]}]),
ok = mrdb:insert(T, {T, a, 1, 1}),
ok = mrdb:insert(T, {T, b, 1, 2}),
{atomic, ok} = mnesia:add_table_index(T, a),
[{1, {T,a,1,1}}, {1, {T,b,1,2}}] =
mrdb_index:rev_fold(T, a, fun ix_fold_acc/3, []),
{atomic, ok} = mnesia:del_table_index(T, a),
ok = mrdb:delete(T, b),
ok = mrdb:insert(T, {T, c, 2, 3}),
{atomic, ok} = mnesia:add_table_index(T, a),
[{1, {T,a,1,1}}, {2, {T,c,2,3}}] =
mrdb_index:rev_fold(T, a, fun ix_fold_acc/3, []),
ok.
ix_fold_acc(K, V, Acc) ->
[{K, V} | Acc].
index_plugin_mgmt(_Config) -> index_plugin_mgmt(_Config) ->
{aborted,_} = mnesia:create_table(x, [{index,[{unknown}]}]), {aborted,_} = mnesia:create_table(x, [{index,[{unknown}]}]),
{aborted,_} = mnesia:create_table(x, [{index,[{{unknown},bag}]}]), {aborted,_} = mnesia:create_table(x, [{index,[{{unknown},bag}]}]),