aboutsummaryrefslogtreecommitdiff
path: root/src/mod_offline.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/mod_offline.erl')
-rw-r--r--src/mod_offline.erl34
1 files changed, 28 insertions, 6 deletions
diff --git a/src/mod_offline.erl b/src/mod_offline.erl
index d81022fdd..f6870adc0 100644
--- a/src/mod_offline.erl
+++ b/src/mod_offline.erl
@@ -123,10 +123,7 @@ store_offline_msg(_Host, US, Msgs, Len, MaxOfflineMsgs,
mnesia) ->
F = fun () ->
Count = if MaxOfflineMsgs =/= infinity ->
- Len +
- p1_mnesia:count_records(offline_msg,
- #offline_msg{us = US,
- _ = '_'});
+ Len + count_mnesia_records(US);
true -> 0
end,
if Count > MaxOfflineMsgs -> discard_warn_sender(Msgs);
@@ -986,8 +983,7 @@ count_offline_messages(User, Server) ->
count_offline_messages(LUser, LServer, mnesia) ->
US = {LUser, LServer},
F = fun () ->
- p1_mnesia:count_records(offline_msg,
- #offline_msg{us = US, _ = '_'})
+ count_mnesia_records(US)
end,
case catch mnesia:async_dirty(F) of
I when is_integer(I) -> I;
@@ -1016,6 +1012,32 @@ count_offline_messages(_Acc, User, Server) ->
N = count_offline_messages(User, Server),
{stop, N}.
+%% Return the number of records matching a given match expression.
+%% This function is intended to be used inside a Mnesia transaction.
+%% The count has been written to use the fewest possible memory by
+%% getting the record by small increment and by using continuation.
+-define(BATCHSIZE, 100).
+
+count_mnesia_records(US) ->
+ MatchExpression = #offline_msg{us = US, _ = '_'},
+ case mnesia:select(offline_msg, [{MatchExpression, [], [[]]}],
+ ?BATCHSIZE, read) of
+ {Result, Cont} ->
+ Count = length(Result),
+ count_records_cont(Cont, Count);
+ '$end_of_table' ->
+ 0
+ end.
+
+count_records_cont(Cont, Count) ->
+ case mnesia:select(Cont) of
+ {Result, Cont} ->
+ NewCount = Count + length(Result),
+ count_records_cont(Cont, NewCount);
+ '$end_of_table' ->
+ Count
+ end.
+
offline_msg_schema() ->
{record_info(fields, offline_msg), #offline_msg{}}.