]> granicus.if.org Git - ejabberd/commitdiff
add indexes to improve pubsub efficiency (TECH-1293)
authorChristophe Romain <christophe.romain@process-one.net>
Wed, 23 Mar 2011 08:36:03 +0000 (09:36 +0100)
committerChristophe Romain <christophe.romain@process-one.net>
Wed, 23 Mar 2011 08:36:03 +0000 (09:36 +0100)
src/mod_pubsub/mod_pubsub.erl
src/mod_pubsub/node_flat.erl
src/mod_pubsub/pubsub.hrl
src/mod_pubsub/pubsub_subscription.erl

index a01a2a14815f4abd698bc0ed7e86b9dc0ade8eb3..5cab106de2d469b695e6636dcc169904126ebb67 100644 (file)
@@ -2953,8 +2953,6 @@ get_options_helper(JID, Lang, Node, NodeId, SubId, Type) ->
 
 read_sub(Subscriber, Node, NodeId, SubId, Lang) ->
     case pubsub_subscription:get_subscription(Subscriber, NodeId, SubId) of
-       {error, notfound} ->
-           {error, extended_error('not-acceptable', "invalid-subid")};
        {result, #pubsub_subscription{options = Options}} ->
             {result, XdataEl} = pubsub_subscription:get_options_xform(Lang, Options),
             OptionsEl = #xmlel{ns = ?NS_PUBSUB, name = 'options',
@@ -2962,6 +2960,12 @@ read_sub(Subscriber, Node, NodeId, SubId, Lang) ->
                                         ?XMLATTR(<<"subid">>, SubId) | nodeAttr(Node)],
                               children = [XdataEl]},
             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}
     end.
 
@@ -3012,12 +3016,14 @@ set_options_helper(Configuration, JID, NodeId, SubId, Type) ->
 
 write_sub(_Subscriber, _NodeId, _SubId, invalid) ->
     {error, extended_error('bad-request', "invalid-options")};
+write_sub(_Subscriber, _NodeID, _SubID, []) ->
+    {result, []};
 write_sub(Subscriber, NodeId, SubId, Options) ->
     case pubsub_subscription:set_subscription(Subscriber, NodeId, SubId, Options) of
-       {error, notfound} ->
-           {error, extended_error('not-acceptable', "invalid-subid")};
        {result, _} ->
-           {result, []}
+           {result, []};
+       {error, _} ->
+           {error, extended_error('not-acceptable', "invalid-subid")}
     end.
 
 %% @spec (Host, Node, JID, Plugins) -> {error, Reason} | {result, Response}
index 5ec336cde32f66aabed7746bfb32c85940bdd8d1..1eb74d84249c672e8cc7146a4c8fe4eb19b410e2 100644 (file)
@@ -107,9 +107,11 @@ init(_Host, _ServerHost, _Opts) ->
     pubsub_subscription:init(),
     mnesia:create_table(pubsub_state,
                        [{disc_copies, [node()]},
+                        {index, [nodeidx]},
                         {attributes, record_info(fields, pubsub_state)}]),
     mnesia:create_table(pubsub_item,
                        [{disc_only_copies, [node()]},
+                        {index, [nodeidx]},
                         {attributes, record_info(fields, pubsub_item)}]),
     ItemsFields = record_info(fields, pubsub_item),
     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) ->
-    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'}}.
 
 %% @spec (Removed) -> ok
@@ -557,6 +559,7 @@ publish_item(NodeIdx, #jid{node = U, domain = S, resource = R} = _JID, PublishMo
                               _ ->
                                   #pubsub_item{
                                 id = {ItemId, NodeIdx},
+                                nodeidx = NodeIdx,
                                 creation = {Now, GenKey},  % TODO, better use {Now, SubKey} ?
                                 modification = Modification,
                                 payload = Payload}
@@ -1024,7 +1027,7 @@ end.
 
 get_states(NodeIdx) ->
     States = case
-            catch mnesia:match_object(#pubsub_state{id = {'_', NodeIdx}, _ = '_'})
+            catch mnesia:index_read(pubsub_state, NodeIdx, #pubsub_state.nodeidx)
                 of
                 PubsubStates when is_list(PubsubStates) -> PubsubStates; %% is_list(PubsubStates) useful ?
                 _                                       -> []
@@ -1046,7 +1049,7 @@ get_states(NodeIdx) ->
 get_state(NodeIdx, Entity) ->
     case catch mnesia:read({pubsub_state, {Entity, NodeIdx}}) of
        [#pubsub_state{} = State] -> State;
-       _                         -> #pubsub_state{id = {Entity, NodeIdx}}
+       _                         -> #pubsub_state{id = {Entity, NodeIdx}, nodeidx=NodeIdx}
     end.
 
 %% @spec (State) -> ok | {error, Reason::stanzaError()}
@@ -1094,7 +1097,7 @@ del_state(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))}.
 
 
index 9af43a4ebfd964862a807cb33c59745604319193..e809605a332da5e27dc9de2ad377c5a5d3ee436c 100644 (file)
 -type(pubsubNode() :: #pubsub_node{}).
 
 
-%%% @type pubsubState() = {pubsub_state, Id, Items, Affiliation, Subscriptions}
+%%% @type pubsubState() = {pubsub_state, Id, NodeIdx, Items, Affiliation, Subscriptions}
 %%%    Id            = {fullUsr(), nodeIdx()}
+%%%    NodeIdx       = nodeIdx(),
 %%%    Items         = [itemId()]
 %%%    Affiliation   = affiliation()
 %%%    Subscriptions = [{subscription(), subId()}].
 -record(pubsub_state,
        {
          id                     :: {fullUsr(), nodeIdx()},
+         nodeidx                :: nodeIdx(),
          items         = []     :: [itemId()],
          affiliation   = 'none' :: affiliation(),
          subscriptions = []     :: [{subscription(), subId()}]
 -type(pubsubState() :: #pubsub_state{}).
 
 
-%%% @type pubsubItem() = {pubsub_item, Id, Creation, Modification, Payload}
+%%% @type pubsubItem() = {pubsub_item, Id, NodeIdx, Creation, Modification, Payload}
 %%%    Id           = {itemId(), nodeIdx()}
+%%%    NodeIdx      = nodeIdx()
 %%%    Creation     = {now(), bareUsr()}
 %%%    Modification = {now(), fullUsr()}
 %%%    Payload      = payload().
 -record(pubsub_item,
        {
          id                               :: {itemId(), nodeIdx()},
+         nodeidx                          :: nodeIdx(),
          creation     = {unknown,unknown} :: {now(), bareUsr()},
          modification = {unknown,unknown} :: {now(), fullUsr()},
          payload      = []                :: payload()
index 712446067c0d5b73158f08b5af8f43067ba61155..6d0ce23cd17f22d7e558398e70d6e324fefa7f09 100644 (file)
@@ -223,6 +223,8 @@ create_table() ->
       -> SubId::subId()
            ).
 
+add_subscription(_JID, _NodeID, []) ->
+    make_subid();
 add_subscription(_Entity, _NodeIdx, Options) ->
     SubId = make_subid(),
     mnesia:write(#pubsub_subscription{subid = SubId, options = Options}),
@@ -262,14 +264,11 @@ read_subscription(_Entity, _NodeIdx, SubId) ->
                           NodeIdx :: nodeIdx(),
                           SubId   :: subId(),
                           Options :: [nodeOption()])
-      -> 'ok' | {'error', 'notfound'}
-           ).
+      -> 'ok'
+       ).
 
-write_subscription(Entity, NodeIdx, SubId, Options) ->
-    case read_subscription(Entity, NodeIdx, SubId) of
-       {error, 'notfound'} -> {error, 'notfound'};
-       Subscription -> mnesia:write(Subscription#pubsub_subscription{options = Options})
-    end.
+write_subscription(_Entity, _NodeIdx, SubId, Options) ->
+    mnesia:write(#pubsub_subscription{subid = SubId, options = Options}).
 
 
 -spec(make_subid/0 :: () -> SubId::subId()).