25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-26 16:26:24 +01:00

add indexes to improve pubsub efficiency (TECH-1293)

This commit is contained in:
Christophe Romain 2011-03-23 09:36:03 +01:00
parent 25a6493e1b
commit 8d2def619d
4 changed files with 30 additions and 18 deletions

View File

@ -2953,8 +2953,6 @@ get_options_helper(JID, Lang, Node, NodeId, SubId, Type) ->
read_sub(Subscriber, Node, NodeId, SubId, Lang) -> read_sub(Subscriber, Node, NodeId, SubId, Lang) ->
case pubsub_subscription:get_subscription(Subscriber, NodeId, SubId) of case pubsub_subscription:get_subscription(Subscriber, NodeId, SubId) of
{error, notfound} ->
{error, extended_error('not-acceptable', "invalid-subid")};
{result, #pubsub_subscription{options = Options}} -> {result, #pubsub_subscription{options = Options}} ->
{result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options), {result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options),
OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options', OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options',
@ -2962,6 +2960,12 @@ read_sub(Subscriber, Node, NodeId, SubId, Lang) ->
?XMLATTR(<<"subid">>, SubId) | nodeAttr(Node)], ?XMLATTR(<<"subid">>, SubId) | nodeAttr(Node)],
children = [XdataEl]}, children = [XdataEl]},
PubsubEl = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children = [OptionsEl]}, PubsubEl = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children = [OptionsEl]},
{result, PubsubEl};
_ ->
OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options',
attrs = [?XMLATTR(<<"jid">>, exmpp_jid:to_binary(Subscriber)),
?XMLATTR(<<"subid">>, SubId) | nodeAttr(Node)]},
PubsubEl = #xmlel{ns = ?NS_PUBSUB, name = 'pubsub', children = [OptionsEl]},
{result, PubsubEl} {result, PubsubEl}
end. end.
@ -3012,12 +3016,14 @@ set_options_helper(Configuration, JID, NodeId, SubId, Type) ->
write_sub(_Subscriber, _NodeId, _SubId, invalid) -> write_sub(_Subscriber, _NodeId, _SubId, invalid) ->
{error, extended_error('bad-request', "invalid-options")}; {error, extended_error('bad-request', "invalid-options")};
write_sub(_Subscriber, _NodeID, _SubID, []) ->
{result, []};
write_sub(Subscriber, NodeId, SubId, Options) -> write_sub(Subscriber, NodeId, SubId, Options) ->
case pubsub_subscription:set_subscription(Subscriber, NodeId, SubId, Options) of case pubsub_subscription:set_subscription(Subscriber, NodeId, SubId, Options) of
{error, notfound} ->
{error, extended_error('not-acceptable', "invalid-subid")};
{result, _} -> {result, _} ->
{result, []} {result, []};
{error, _} ->
{error, extended_error('not-acceptable', "invalid-subid")}
end. end.
%% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response} %% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response}

View File

@ -107,9 +107,11 @@ init(_Host, _ServerHost, _Opts) ->
pubsub_subscription:init(), pubsub_subscription:init(),
mnesia:create_table(pubsub_state, mnesia:create_table(pubsub_state,
[{disc_copies, [node()]}, [{disc_copies, [node()]},
{index, [nodeidx]},
{attributes, record_info(fields, pubsub_state)}]), {attributes, record_info(fields, pubsub_state)}]),
mnesia:create_table(pubsub_item, mnesia:create_table(pubsub_item,
[{disc_only_copies, [node()]}, [{disc_only_copies, [node()]},
{index, [nodeidx]},
{attributes, record_info(fields, pubsub_item)}]), {attributes, record_info(fields, pubsub_item)}]),
ItemsFields = record_info(fields, pubsub_item), ItemsFields = record_info(fields, pubsub_item),
case mnesia:table_info(pubsub_item, attributes) of case mnesia:table_info(pubsub_item, attributes) of
@ -234,7 +236,7 @@ create_node_permission(Host, ServerHost, _NodeId, _ParentNodeId, #jid{node = U,
). ).
create_node(NodeIdx, #jid{node = U, domain = S} = _JID) -> create_node(NodeIdx, #jid{node = U, domain = S} = _JID) ->
set_state(#pubsub_state{id = {{U,S,undefined}, NodeIdx}, affiliation = 'owner'}), set_state(#pubsub_state{id = {{U,S,undefined}, NodeIdx}, nodeidx = NodeIdx, affiliation = 'owner'}),
{'result', {'default', 'broadcast'}}. {'result', {'default', 'broadcast'}}.
%% @spec (Removed) -> ok %% @spec (Removed) -> ok
@ -557,6 +559,7 @@ publish_item(NodeIdx, #jid{node = U, domain = S, resource = R} = _JID, PublishMo
_ -> _ ->
#pubsub_item{ #pubsub_item{
id = {ItemId, NodeIdx}, id = {ItemId, NodeIdx},
nodeidx = NodeIdx,
creation = {Now, GenKey}, % TODO, better use {Now, SubKey} ? creation = {Now, GenKey}, % TODO, better use {Now, SubKey} ?
modification = Modification, modification = Modification,
payload = Payload} payload = Payload}
@ -1024,7 +1027,7 @@ end.
get_states(NodeIdx) -> get_states(NodeIdx) ->
States = case States = case
catch mnesia:match_object(#pubsub_state{id = {'_', NodeIdx}, _ = '_'}) catch mnesia:index_read(pubsub_state, NodeIdx, #pubsub_state.nodeidx)
of of
PubsubStates when is_list(PubsubStates) -> PubsubStates; %% is_list(PubsubStates) useful ? PubsubStates when is_list(PubsubStates) -> PubsubStates; %% is_list(PubsubStates) useful ?
_ -> [] _ -> []
@ -1046,7 +1049,7 @@ get_states(NodeIdx) ->
get_state(NodeIdx, Entity) -> get_state(NodeIdx, Entity) ->
case catch mnesia:read({pubsub_state, {Entity, NodeIdx}}) of case catch mnesia:read({pubsub_state, {Entity, NodeIdx}}) of
[#pubsub_state{} = State] -> State; [#pubsub_state{} = State] -> State;
_ -> #pubsub_state{id = {Entity, NodeIdx}} _ -> #pubsub_state{id = {Entity, NodeIdx}, nodeidx=NodeIdx}
end. end.
%% @spec (State) -> ok | {error, Reason::stanzaError()} %% @spec (State) -> ok | {error, Reason::stanzaError()}
@ -1094,7 +1097,7 @@ del_state(NodeIdx, Entity) ->
). ).
get_items(NodeIdx, _Entity) -> get_items(NodeIdx, _Entity) ->
Items = mnesia:match_object(#pubsub_item{id = {'_', NodeIdx}, _ = '_'}), Items = mnesia:index_read(pubsub_item, NodeIdx, #pubsub_item.nodeidx),
{result, lists:reverse(lists:keysort(#pubsub_item.modification, Items))}. {result, lists:reverse(lists:keysort(#pubsub_item.modification, Items))}.

View File

@ -307,8 +307,9 @@
-type(pubsubNode() :: #pubsub_node{}). -type(pubsubNode() :: #pubsub_node{}).
%%% @type pubsubState() = {pubsub_state, Id, Items, Affiliation, Subscriptions} %%% @type pubsubState() = {pubsub_state, Id, NodeIdx, Items, Affiliation, Subscriptions}
%%% Id = {fullUsr(), nodeIdx()} %%% Id = {fullUsr(), nodeIdx()}
%%% NodeIdx = nodeIdx(),
%%% Items = [itemId()] %%% Items = [itemId()]
%%% Affiliation = affiliation() %%% Affiliation = affiliation()
%%% Subscriptions = [{subscription(), subId()}]. %%% Subscriptions = [{subscription(), subId()}].
@ -319,6 +320,7 @@
-record(pubsub_state, -record(pubsub_state,
{ {
id :: {fullUsr(), nodeIdx()}, id :: {fullUsr(), nodeIdx()},
nodeidx :: nodeIdx(),
items = [] :: [itemId()], items = [] :: [itemId()],
affiliation = 'none' :: affiliation(), affiliation = 'none' :: affiliation(),
subscriptions = [] :: [{subscription(), subId()}] subscriptions = [] :: [{subscription(), subId()}]
@ -327,8 +329,9 @@
-type(pubsubState() :: #pubsub_state{}). -type(pubsubState() :: #pubsub_state{}).
%%% @type pubsubItem() = {pubsub_item, Id, Creation, Modification, Payload} %%% @type pubsubItem() = {pubsub_item, Id, NodeIdx, Creation, Modification, Payload}
%%% Id = {itemId(), nodeIdx()} %%% Id = {itemId(), nodeIdx()}
%%% NodeIdx = nodeIdx()
%%% Creation = {now(), bareUsr()} %%% Creation = {now(), bareUsr()}
%%% Modification = {now(), fullUsr()} %%% Modification = {now(), fullUsr()}
%%% Payload = payload(). %%% Payload = payload().
@ -339,6 +342,7 @@
-record(pubsub_item, -record(pubsub_item,
{ {
id :: {itemId(), nodeIdx()}, id :: {itemId(), nodeIdx()},
nodeidx :: nodeIdx(),
creation = {unknown,unknown} :: {now(), bareUsr()}, creation = {unknown,unknown} :: {now(), bareUsr()},
modification = {unknown,unknown} :: {now(), fullUsr()}, modification = {unknown,unknown} :: {now(), fullUsr()},
payload = [] :: payload() payload = [] :: payload()

View File

@ -223,6 +223,8 @@ create_table() ->
-> SubId::subId() -> SubId::subId()
). ).
add_subscription(_JID, _NodeID, []) ->
make_subid();
add_subscription(_Entity, _NodeIdx, Options) -> add_subscription(_Entity, _NodeIdx, Options) ->
SubId = make_subid(), SubId = make_subid(),
mnesia:write(#pubsub_subscription{subid = SubId, options = Options}), mnesia:write(#pubsub_subscription{subid = SubId, options = Options}),
@ -262,14 +264,11 @@ read_subscription(_Entity, _NodeIdx, SubId) ->
NodeIdx :: nodeIdx(), NodeIdx :: nodeIdx(),
SubId :: subId(), SubId :: subId(),
Options :: [nodeOption()]) Options :: [nodeOption()])
-> 'ok' | {'error', 'notfound'} -> 'ok'
). ).
write_subscription(Entity, NodeIdx, SubId, Options) -> write_subscription(_Entity, _NodeIdx, SubId, Options) ->
case read_subscription(Entity, NodeIdx, SubId) of mnesia:write(#pubsub_subscription{subid = SubId, options = Options}).
{error, 'notfound'} -> {error, 'notfound'};
Subscription -> mnesia:write(Subscription#pubsub_subscription{options = Options})
end.
-spec(make_subid/0 :: () -> SubId::subId()). -spec(make_subid/0 :: () -> SubId::subId()).